Momwe mungatetezere njira ndi zowonjezera za kernel pa macOS

Moni, Habr! Lero ndikufuna kunena za momwe mungatetezere njira kuchokera kwa omwe akuukira mu macOS. Mwachitsanzo, izi ndizothandiza pa antivayirasi kapena makina osunga zobwezeretsera, makamaka popeza pansi pa macOS pali njira zingapo "zopha" njira. Werengani za izi ndi njira zotetezera pansi pa kudula.

Momwe mungatetezere njira ndi zowonjezera za kernel pa macOS

Njira yachikale "kupha" njira

Njira yodziwika bwino "yopha" ndondomeko ndi kutumiza chizindikiro cha SIGKILL ku ndondomekoyi. Kupyolera mu bash mutha kuyimba muyeso "kupha -SIGKILL PID" kapena "pkill -9 NAME" kupha. Lamulo la "kupha" ladziwika kuyambira masiku a UNIX ndipo limapezeka osati pa macOS okha, komanso pamakina ena a UNIX.

Monga momwe zilili m'makina a UNIX, macOS amakulolani kuti mutenge ma siginecha aliwonse kunjira kupatula awiri - SIGKILL ndi SIGSTOP. Nkhaniyi idzayang'ana kwambiri pa chizindikiro cha SIGKILL ngati chizindikiro chomwe chimayambitsa ndondomeko kuphedwa.

Zambiri za macOS

Pa macOS, kuyitana kwakupha mu XNU kernel kumatcha psignal(SIGKILL,...) ntchito. Tiyeni tiyese kuwona zomwe ogwiritsa ntchito ena mumalo ogwiritsira ntchito angatchulidwe ndi ntchito ya psignal. Tiyeni tichotse mafoni ku ntchito ya psignal m'makina amkati a kernel (ngakhale atha kukhala osachepera, tisiya nkhani ina 🙂 - kutsimikizira siginecha, zolakwika zamakumbukiro, kutuluka / kuletsa kachitidwe, kuphwanya chitetezo cha mafayilo, ndi zina zambiri. .

Tiyeni tiyambe kuwunikiranso ndi ntchitoyo komanso kuyimba kofananira terminate_with_payload. Zitha kuwoneka kuti kuwonjezera pa kuyimba kwanthawi yayitali, pali njira ina yomwe ili yodziwika ndi makina ogwiritsira ntchito a macOS ndipo sapezeka mu BSD. Mfundo zoyendetsera mafoni onsewa ndizofanana. Ndi mafoni achindunji ku kernel function psignal. Komanso dziwani kuti musanayambe kupha ndondomeko, kufufuza kwa "cansignal" kumachitidwa - ngati ndondomekoyo ikhoza kutumiza chizindikiro ku ndondomeko ina; dongosololi sililola ntchito iliyonse kupha machitidwe a dongosolo, mwachitsanzo.

static int
terminate_with_payload_internal(struct proc *cur_proc, int target_pid, uint32_t reason_namespace,
				uint64_t reason_code, user_addr_t payload, uint32_t payload_size,
				user_addr_t reason_string, uint64_t reason_flags)
{
...
	target_proc = proc_find(target_pid);
...
	if (!cansignal(cur_proc, cur_cred, target_proc, SIGKILL)) {
		proc_rele(target_proc);
		return EPERM;
	}
...
	if (target_pid == cur_proc->p_pid) {
		/*
		 * psignal_thread_with_reason() will pend a SIGKILL on the specified thread or
		 * return if the thread and/or task are already terminating. Either way, the
		 * current thread won't return to userspace.
		 */
		psignal_thread_with_reason(target_proc, current_thread(), SIGKILL, signal_reason);
	} else {
		psignal_with_reason(target_proc, SIGKILL, signal_reason);
	}
...
}

anayambitsa

Njira yokhazikika yopangira ma daemoni pakuyambitsa dongosolo ndikuwongolera moyo wawo imayambitsidwa. Chonde dziwani kuti magwero ake ndi a mtundu wakale wa launchctl mpaka macOS 10.10, zitsanzo zamakhodi zimaperekedwa pazowonetsera. Launchctl yamakono imatumiza zidziwitso zoyambitsidwa kudzera pa XPC, logic ya launchctl yasunthidwa kwa iyo.

Tiyeni tiwone momwe ndendende mapulogalamu amayimitsira. Musanatumize chizindikiro cha SIGTERM, ntchitoyo imayesedwa kuyimitsidwa pogwiritsa ntchito foni ya "proc_terminate".

<launchctl src/core.c>
...
	error = proc_terminate(j->p, &sig);
	if (error) {
		job_log(j, LOG_ERR | LOG_CONSOLE, "Could not terminate job: %d: %s", error, strerror(error));
		job_log(j, LOG_NOTICE | LOG_CONSOLE, "Using fallback option to terminate job...");
		error = kill2(j->p, SIGTERM);
		if (error) {
			job_log(j, LOG_ERR, "Could not signal job: %d: %s", error, strerror(error));
		} 
...
<>

Pansi pa hood, proc_terminate, ngakhale dzina lake, silingatumize psignal ndi SIGTERM, komanso SIGKILL.

Indirect Kill - Malire Othandizira

Nkhani yosangalatsa kwambiri imatha kuwoneka mu kuyimbira kwina kwadongosolo ndondomeko_ndondomeko. Kugwiritsiridwa ntchito kofala kwa kuyimba kwadongosololi ndikuchepetsa zogwiritsira ntchito, monga cholozera kuti chichepetse nthawi ya CPU ndi ma memory quotas kuti dongosolo lisachedwe kwambiri ndi ntchito zosunga mafayilo. Ngati ntchito yafikira malire ake, monga momwe tingawonere kuchokera ku proc_apply_resource_actions ntchito, chizindikiro cha SIGKILL chimatumizidwa ku ndondomekoyi.

Ngakhale kuyitana kwa dongosololi kungathe kupha ndondomeko, dongosolo silinayang'ane mokwanira ufulu wa ndondomekoyi yomwe imayitana kuyitana kwadongosolo. Kufufuza analipo, koma ndizokwanira kugwiritsa ntchito mbendera ya PROC_POLICY_ACTION_SET kuti mulambalale mkhalidwewu.

Chifukwa chake, ngati "muchepetsa" kuchuluka kwa kugwiritsa ntchito kwa CPU (mwachitsanzo, kulola 1 ns kuti igwire), ndiye kuti mutha kupha njira iliyonse mudongosolo. Chifukwa chake, pulogalamu yaumbanda imatha kupha njira iliyonse pamakina, kuphatikiza ma antivayirasi. Chosangalatsanso ndi zotsatira zomwe zimachitika mukapha njira ndi pid 1 (launchctl) - kernel panic poyesa kukonza chizindikiro cha SIGKILL :)

Momwe mungatetezere njira ndi zowonjezera za kernel pa macOS

Kodi mungathetse bwanji vutoli?

Njira yowongoka kwambiri yopewera kuphedwa ndikusintha cholozera chantchito patebulo loyimba foni. Tsoka ilo, njira iyi si yachidule pazifukwa zambiri.

Choyamba, chizindikiro chomwe chimayang'anira malo okumbukira a sysent sichingokhala chachinsinsi ku chizindikiro cha XNU kernel, koma sichipezeka muzizindikiro za kernel. Muyenera kugwiritsa ntchito njira zofufuzira za heuristic, monga kusokoneza ntchitoyo ndikufufuza cholozera mmenemo.

Kachiwiri, kapangidwe kazolemba patebulo zimatengera mbendera zomwe kernel idapangidwa. Ngati mbendera ya CONFIG_REQUIRES_U32_MUNGING italengezedwa, kukula kwake kudzasinthidwa - gawo lina lidzawonjezedwa. sy_arg_munge32. Ndikofunikira kuchita cheke chowonjezera kuti mudziwe kuti ndi mbendera iti yomwe idapangidwa ndi, kapenanso, fufuzani zolozera zogwirira ntchito motsutsana ndi omwe amadziwika.

struct sysent {         /* system call table */
        sy_call_t       *sy_call;       /* implementing function */
#if CONFIG_REQUIRES_U32_MUNGING || (__arm__ && (__BIGGEST_ALIGNMENT__ > 4))
        sy_munge_t      *sy_arg_munge32; /* system call arguments munger for 32-bit process */
#endif
        int32_t         sy_return_type; /* system call return types */
        int16_t         sy_narg;        /* number of args */
        uint16_t        sy_arg_bytes;   /* Total size of arguments in bytes for
                                         * 32-bit system calls
                                         */
};

Mwamwayi, m'mitundu yamakono ya macOS, Apple imapereka API yatsopano yogwirira ntchito ndi njira. Endpoint Security API imalola makasitomala kuvomereza zopempha zambiri kuzinthu zina. Chifukwa chake, mutha kuletsa ma siginecha aliwonse kunjira, kuphatikiza chizindikiro cha SIGKILL, pogwiritsa ntchito API yomwe yatchulidwa pamwambapa.

#include <bsm/libbsm.h>
#include <EndpointSecurity/EndpointSecurity.h>
#include <unistd.h>

int main(int argc, const char * argv[]) {
    es_client_t* cli = nullptr;
    {
        auto res = es_new_client(&cli, ^(es_client_t * client, const es_message_t * message) {
            switch (message->event_type) {
                case ES_EVENT_TYPE_AUTH_SIGNAL:
                {
                    auto& msg = message->event.signal;
                    auto target = msg.target;
                    auto& token = target->audit_token;
                    auto pid = audit_token_to_pid(token);
                    printf("signal '%d' sent to pid '%d'n", msg.sig, pid);
                    es_respond_auth_result(client, message, pid == getpid() ? ES_AUTH_RESULT_DENY : ES_AUTH_RESULT_ALLOW, false);
                }
                    break;
                default:
                    break;
            }
        });
    }

    {
        es_event_type_t evs[] = { ES_EVENT_TYPE_AUTH_SIGNAL };
        es_subscribe(cli, evs, sizeof(evs) / sizeof(*evs));
    }

    printf("%dn", getpid());
    sleep(60); // could be replaced with other waiting primitive

    es_unsubscribe_all(cli);
    es_delete_client(cli);

    return 0;
}

Mofananamo, MAC Policy ikhoza kulembedwa mu kernel, yomwe imapereka njira yotetezera chizindikiro (policy proc_check_signal), koma API sichimathandizidwa mwalamulo.

Chitetezo chowonjezera cha Kernel

Kuphatikiza pa kuteteza njira zamakina, kuteteza kukulitsa kwa kernel palokha (kext) ndikofunikira. macOS imapereka chimango kwa opanga kuti apange madalaivala a zida za IOKit mosavuta. Kuphatikiza pakupereka zida zogwirira ntchito ndi zida, IOKit imapereka njira zosungira madalaivala pogwiritsa ntchito makalasi a C ++. Ntchito mu malo ogwiritsira ntchito idzatha "kupeza" chitsanzo cholembetsa cha kalasi kuti chikhazikitse ubale wa kernel-userspace.

Kuti muwone kuchuluka kwa zochitika zamakalasi mudongosolo, pali ntchito ya ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Kuwonjeza kulikonse kwa kernel komwe kukufuna kulembetsa ndi stack yoyendetsa kuyenera kulengeza kalasi yomwe imalandira cholowa kuchokera ku IOService, mwachitsanzo my_kext_ioservice pamenepa.Kulumikiza mapulogalamu a ogwiritsa ntchito kumapangitsa kupanga kwatsopano kwa kalasi yomwe imatenga cholowa kuchokera ku IOUserClient, mu chitsanzo my_kext_iouserclient.

Mukayesa kutsitsa dalaivala kuchokera padongosolo (kextunload command), ntchito yeniyeni "bool terminate (IOOptionBits options)" imatchedwa. Ndikokwanira kubweza zabodza pa kuyitana kuti muthe poyesa kutsitsa kuti mulepheretse kextunload.

bool Kext::terminate(IOOptionBits options)
{

  if (!IsUnloadAllowed)
  {
    // Unload is not allowed, returning false
    return false;
  }

  return super::terminate(options);
}

Mbendera ya IsUnloadAllowed ikhoza kukhazikitsidwa ndi IOUserClient potsegula. Pakakhala malire otsitsa, lamulo la kextunload libweza zotsatirazi:

admin@admins-Mac drivermanager % sudo kextunload ./test.kext
Password:
(kernel) Can't remove kext my.kext.test; services failed to terminate - 0xe00002c7.
Failed to unload my.kext.test - (iokit/common) unsupported function.

Chitetezo chofananira chiyenera kuchitidwa kwa IOUserClient. Zochitika zamakalasi zitha kutsitsidwa pogwiritsa ntchito ntchito ya IOKitLib "IOCatalogueTerminate(mach_port_t, uint32_t flag, io_name_t description);". Mutha kubweza zabodza mukamayitana lamulo la "terminate" mpaka ntchito ya "userspace" imwalira, ndiko kuti, ntchito ya "clientDied" siyimatchedwa.

Chitetezo cha Fayilo

Kuti muteteze mafayilo, ndikwanira kugwiritsa ntchito Kauth API, yomwe imakupatsani mwayi wolepheretsa mafayilo. Apple imapatsa opanga zidziwitso zokhudzana ndi zochitika zosiyanasiyana; kwa ife, machitidwe a KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA ndi KAUTH_VNODE_DELETE_CHILD ndi ofunikira. Njira yosavuta yoletsa kupeza mafayilo ndi njira - timagwiritsa ntchito "vn_getpath" API kuti tipeze njira yopita ku fayilo ndikufanizira njira yoyambira. Zindikirani kuti kukhathamiritsa kusinthidwanso kwamafoda a fayilo, makinawo samalola mwayi wofikira fayilo iliyonse, koma kufoda yomwe idasinthidwanso. Ndikofunikira kufananiza njira ya makolo ndikuletsa KAUTH_VNODE_DELETE pa izo.

Momwe mungatetezere njira ndi zowonjezera za kernel pa macOS

Kuipa kwa njira iyi kungakhale kocheperako pamene chiwerengero cha ma prefixes chikuwonjezeka. Kuwonetsetsa kuti kufananitsa sikuli kofanana ndi O(prefix* length), pomwe choyambirira ndi chiwerengero cha prefixes, kutalika ndi kutalika kwa chingwe, mutha kugwiritsa ntchito deterministic finite automaton (DFA) yomangidwa ndi prefixes.

Tiyeni tikambirane njira yopangira DFA pagulu lina la prefixes. Timayambira zolozera kumayambiriro kwa chiyambi chilichonse. Ngati zolozera zonse ziloza ku chikhalidwe chomwecho, ndiye onjezerani cholozera chilichonse ndi khalidwe limodzi ndipo kumbukirani kuti kutalika kwa mzere womwewo ndi waukulu ndi umodzi. Ngati pali zolozera ziwiri zomwe zili ndi zizindikiro zosiyana, gawani zolozerazo m'magulu malinga ndi chizindikiro chomwe akuloza ndikubwereza ndondomeko ya gulu lirilonse.

Pachiyambi choyamba (zolemba zonse pansi pa zolozera ndizofanana), timapeza dziko la DFA lomwe liri ndi kusintha kumodzi kokha pamzere womwewo. M'chigawo chachiwiri, timapeza tebulo la kusintha kwa kukula 256 (chiwerengero cha zilembo ndi chiwerengero chachikulu cha magulu) kupita ku mayiko otsatirawa omwe akupezeka poyitana ntchitoyo mobwerezabwereza.

Tiyeni tione chitsanzo. Pamagulu oyambira (“/foo/bar/tmp/”, “/var/db/foo/”, “/foo/bar/aba/”, “foo/bar/aac/”) mukhoza kupeza zotsatirazi DFA. Chithunzichi chikuwonetsa kusintha komwe kumapita kumayiko ena; zosintha zina sizikhala zomaliza.

Momwe mungatetezere njira ndi zowonjezera za kernel pa macOS

Mukadutsa m'maboma a DKA, pakhoza kukhala milandu itatu.

  1. Gawo lomaliza lafika - njirayo ndi yotetezedwa, timachepetsa ntchito KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA ndi KAUTH_VNODE_DELETE_CHILD
  2. Dziko lomaliza silinafike, koma njira "inatha" (chomaliza chinafikira) - njirayo ndi kholo, m'pofunika kuchepetsa KAUTH_VNODE_DELETE. Dziwani kuti ngati vnode ndi chikwatu, muyenera kuwonjezera '/' kumapeto, apo ayi akhoza kuchepetsa ku fayilo "/foor/bar/t", zomwe sizolondola.
  3. Dziko lomaliza silinafike, njirayo sinathe. Palibe prefixes yofanana ndi iyi, sitikudziwitsani zoletsa.

Pomaliza

Cholinga cha mayankho achitetezo omwe akupangidwa ndikuwonjezera chitetezo cha wogwiritsa ntchito ndi deta yake. Kumbali imodzi, cholinga ichi chikukwaniritsidwa ndi chitukuko cha mapulogalamu a Acronis, omwe amatseka zowonongeka zomwe machitidwe opangira okha ndi "ofooka". Kumbali inayi, tisanyalanyaze kulimbikitsa zitetezo zomwe zitha kuwongolera mbali ya OS, makamaka popeza kutseka zofooka zotere kumawonjezera kukhazikika kwathu ngati chinthu. Kusatetezekako kudanenedwa ku Apple Product Security Team ndipo kwakhazikitsidwa mu macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).

Momwe mungatetezere njira ndi zowonjezera za kernel pa macOS

Zonsezi zitha kuchitika ngati chida chanu chakhazikitsidwa mwalamulo mu kernel. Ndiko kuti, palibe mipata yotere ya mapulogalamu akunja ndi osafunika. Komabe, monga mukuonera, ngakhale kuteteza mapulogalamu ovomerezeka monga antivayirasi ndi makina osunga zobwezeretsera kumafuna ntchito. Koma tsopano zinthu zatsopano za Acronis za macOS zidzakhala ndi chitetezo chowonjezera pakutsitsa kuchokera kudongosolo.

Source: www.habr.com

Kuwonjezera ndemanga