Ungazikhusela njani iinkqubo kunye nokwandiswa kwekernel kwi-macOS

Molo, Habr! Namhlanje ndingathanda ukuthetha malunga nendlela onokuthi uzikhusele ngayo iinkqubo ekuhlaselweni ngabahlaseli kwi-macOS. Umzekelo, oku kuluncedo kwi-antivirus okanye inkqubo yokugcina, ngakumbi kuba phantsi kwe-macOS kukho iindlela ezininzi "zokubulala" inkqubo. Funda ngale nto kunye neendlela zokukhusela phantsi kokusikwa.

Ungazikhusela njani iinkqubo kunye nokwandiswa kwekernel kwi-macOS

Indlela yakudala "yokubulala" inkqubo

Indlela eyaziwayo "yokubulala" inkqubo kukuthumela uphawu lwe-SIGKILL kwinkqubo. Nge-bash ungabiza umgangatho "ukubulala -SIGKILL PID" okanye "pkill -9 NAME" ukubulala. Umyalelo "wokubulala" uyaziwa ukususela ngeentsuku ze-UNIX kwaye awufumaneki kuphela kwi-macOS, kodwa nakwezinye iinkqubo ezifana ne-UNIX.

Njengakwiinkqubo ezifana ne-UNIX, i-macOS ikuvumela ukuba uthintele nayiphi na imiqondiso kwinkqubo ngaphandle kwemibini-SIGKILL kunye ne-SIGSTOP. Eli nqaku liza kugxininisa ngokukodwa kwisignali ye-SIGKILL njengomqondiso obangela ukuba inkqubo ibulawe.

iinkcukacha ze-macOS

Kwi-macOS, inkqubo yokubulala umnxeba kwi-kernel ye-XNU ibiza i-psignal(SIGKILL,...) umsebenzi. Makhe sizame ukubona ukuba zeziphi ezinye izenzo zomsebenzisi kwindawo yomsebenzisi ezinokubizwa ngumsebenzi we-psignal. Masikhuphe iifowuni kumsebenzi we-psignal kwiindlela zangaphakathi ze-kernel (nangona zinokuba zincinci, kodwa siya kuzishiya kwelinye inqaku 🙂 - ukuqinisekiswa kwesiginesha, iimpazamo zememori, ukuphuma / ukuphelisa ukuphatha, ukuphulwa kokukhusela iifayile, njl.

Masiqale uphononongo kunye nomsebenzi kunye nefowuni yenkqubo ehambelanayo phelisa_ngomthwalo. Kuya kubonakala ukuba ukongeza kumnxeba wokubulala weklasikhi, kukho enye indlela echanekileyo yenkqubo yokusebenza ye-macOS kwaye ayifumaneki kwi-BSD. Imigaqo yokusebenza yazo zombini iifowuni zenkqubo nayo iyafana. Ziifowuni ezithe ngqo kwi-kernel function psignal. Kwakhona qaphela ukuba ngaphambi kokuba ubulale inkqubo, ukuhlolwa kwe "cansignal" kuyenziwa - ingaba inkqubo ingathumela umqondiso kwenye inkqubo; inkqubo ayivumeli nasiphi na isicelo sokubulala iinkqubo zenkqubo, umzekelo.

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);
	}
...
}

yaziswa

Indlela esemgangathweni yokwenza iidaemon ekuqalisweni kwenkqubo kunye nokulawula ubomi babo iyaziswa. Nceda uqaphele ukuba imithombo yeyohlobo oludala lwe-launchctl ukuya kuthi ga kwi-macOS 10.10, imizekelo yekhowudi inikezelwe ngeenjongo zokubonisa. I-launchctl yanamhlanje ithumela imiqondiso ephehlelelweyo nge-XPC, ingqiqo ye-launchctl isiwe kuyo.

Makhe sijonge ukuba izicelo zinqunyanyiswa njani. Phambi kokuthumela uphawu lwe-SIGTERM, isicelo sizanywe ukuyekwa kusetyenziswa inkqubo yokufowuna “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));
		} 
...
<>

Ngaphantsi kwe-hood, i-proc_terminate, ngaphandle kwegama layo, ayinakuthumela kuphela i-psignal nge-SIGTERM, kodwa kunye ne-SIGKILL.

I-Indirect Kill-Umda weResource

Imeko enomdla ngakumbi inokubonwa kwenye ifowuni yenkqubo inkqubo_umgaqo-nkqubo. Ukusetyenziswa okuqhelekileyo kwesi sixokelelwano sokufowuna kukunciphisa izixhobo zesicelo, ezifana nesalathiso sokukhawulela ixesha le-CPU kunye nememori quotas ukuze inkqubo ingacothiswa kakhulu yimisebenzi yogcino lwefayile. Ukuba isicelo sifikelele kumda wesixhobo saso, njengoko kunokubonwa kumsebenzi we-proc_apply_resource_actions, uphawu lwe-SIGKILL luthunyelwa kwinkqubo.

Nangona le nkqubo yokufowuna inokubulala inkqubo, inkqubo ayizange ijonge ngokwaneleyo amalungelo enkqubo yokubiza inkqubo yokufowuna. Ngokwenene jonga ebekhona, kodwa kwanele ukusebenzisa enye iflegi PROC_POLICY_ACTION_SET ukugqitha lo mqathango.

Ke, ukuba "unciphisa" i-quota yokusetyenziswa kwe-CPU yesicelo (umzekelo, vumela kuphela i-1 ns ukuba isebenze), ngoko unokubulala nayiphi na inkqubo kwinkqubo. Ke, i-malware inokubulala nayiphi na inkqubo kwinkqubo, kubandakanya nenkqubo ye-antivirus. Kwakhona umdla sisiphumo esenzekayo xa ubulala inkqubo nge-pid 1 (launchctl) - i-kernel panic xa izama ukuqhubela phambili umqondiso we-SIGKILL :)

Ungazikhusela njani iinkqubo kunye nokwandiswa kwekernel kwi-macOS

Indlela yokusombulula ingxaki?

Eyona ndlela ithe ngqo yokuthintela inkqubo ekubulaweni kukubuyisela isalathisi somsebenzi kwitafile yokufowuna. Ngelishwa, le ndlela ayibalulekanga ngenxa yezizathu ezininzi.

Okokuqala, isimboli elawula indawo yenkumbulo ye-sysent ayibucala kuphela kwisimboli se-kernel ye-XNU, kodwa ayinakufunyanwa kwiisimboli zekernel. Kuya kufuneka usebenzise iindlela zokukhangela ze-heuristic, ezinjengokuqhaqha ngokuguquguqukayo umsebenzi kunye nokukhangela isalathisi kuyo.

Okwesibini, ubume bokungeniswa kwitheyibhile kuxhomekeke kwiiflegi apho i-kernel ihlanganiswe khona. Ukuba iflegi yeCONFIG_REQUIRES_U32_MUNGING ibhengezwe, ubungakanani besakhiwo buya kutshintshwa - indawo eyongezelelweyo iya kongezwa. sy_arg_munge32. Kuyimfuneko ukwenza uqwalaselo olongezelelweyo ukumisela ukuba yeyiphi iflegi edityaniswe nekernel, okanye ngenye indlela, khangela izikhombisi zokusebenza ngokuchasene nezaziwayo.

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
                                         */
};

Ngethamsanqa, kwiinguqulelo zanamhlanje ze-macOS, iApple ibonelela nge-API entsha yokusebenza ngeenkqubo. I-Endpoint Security API ivumela abathengi ukuba bagunyazise izicelo ezininzi kwezinye iinkqubo. Ngaloo ndlela, unokuvala nayiphi na imiqondiso kwiinkqubo, kuquka i-SIGKILL uphawu, usebenzisa i-API ekhankanywe ngasentla.

#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;
}

Ngokufanayo, uMgaqo-nkqubo we-MAC unokubhaliswa kwi-kernel, enika indlela yokukhusela isignali (umgaqo-nkqubo we-proc_check_signal), kodwa i-API ayixhaswanga ngokusemthethweni.

Ukhuseleko lokwandiswa kweKernel

Ukongeza kwiinkqubo zokukhusela kwinkqubo, ukukhusela i-kernel extension ngokwayo (i-kext) nayo iyimfuneko. iMacOS ibonelela ngesakhelo kubaphuhlisi ukuba baphuhlise ngokulula abaqhubi besixhobo se-IOKit. Ukongeza ekuboneleleni ngezixhobo zokusebenza kunye nezixhobo, i-IOKit ibonelela ngeendlela zokupakisha umqhubi usebenzisa imizekelo yeeklasi zeC ++. Isicelo kwi-userspace siya kukwazi "ukufumana" umzekelo obhalisiweyo weklasi ukuseka ubudlelwane be-kernel-userspace.

Ukubona inani leemeko zeklasi kwinkqubo, kukho i-ioclasscount utility.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Naluphi na ulwandiso lwe-kernel olunqwenela ukubhalisa kunye nesitaki somqhubi kufuneka sibhengeze udidi oluzuza njengelifa kwi-IOService, umzekelo my_kext_ioservice kule meko Ukudibanisa izicelo zomsebenzisi kubangela ukuyilwa komzekelo omtsha wodidi olufumana ilifa kwi-IOUserClient, kumzekelo my_kext_iouserclient.

Xa uzama ukukhulula umqhubi kwinkqubo (umyalelo we-kextunload), umsebenzi wenyani "i-bool terminate (iinketho ze-IOOptionBits)" ibizwa ngokuba. Kwanele ukubuyisela ubuxoki kwifowuni yokuphelisa xa uzama ukukhulula ukukhubaza i-kextunload.

bool Kext::terminate(IOOptionBits options)
{

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

  return super::terminate(options);
}

IsUnloadAllowed iflegi inokusetwa yi-IOUserClient xa ilayisha. Xa kukho umda wokukhuphela, umyalelo we kextunload uya kubuyisela imveliso elandelayo:

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.

Ukhuseleko olufanayo kufuneka lwenziwe kwi-IOUserClient. Iimeko zeeklasi zinokukhutshwa kusetyenziswa i-IOKitLib yendawo yomsebenzisi umsebenzi "IOCatalogueTerminate(mach_port_t, uint32_t flag, io_name_t description);". Ungabuyisela ubuxoki xa ubiza "ukuphelisa" umyalelo de isicelo sesithuba somsebenzisi "sife", oko kukuthi, umsebenzi we "clientDied" awubizwa.

Ukhuseleko lwefayile

Ukukhusela iifayile, kwanele ukusebenzisa i-Kauth API, ekuvumela ukuba uthintele ukufikelela kwiifayile. I-Apple ibonelela abaphuhlisi ngezaziso malunga neziganeko ezahlukeneyo kumda; kuthi, imisebenzi KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA kunye ne-KAUTH_VNODE_DELETE_CHILD zibalulekile. Eyona ndlela ilula yokukhawulela ukufikelela kwiifayile yindlela - sisebenzisa "vn_getpath" API ukufumana indlela eya kwifayile kwaye uthelekise isimaphambili sendlela. Qaphela ukuba ukwenza ngcono ukuthiywa ngokutsha kweendlela zefolda yefayile, isixokelelwano asigunyazisi ufikelelo kwifayile nganye, kodwa kuphela kulawulo ngokwayo oluthiywe ngokutsha. Kuyimfuneko ukuthelekisa indlela yomzali kwaye uthintele i-KAUTH_VNODE_DELETE kuyo.

Ungazikhusela njani iinkqubo kunye nokwandiswa kwekernel kwi-macOS

Isithintelo sale ndlela inokuba yintsebenzo ephantsi njengoko inani lezimaphambili lisanda. Ukuqinisekisa ukuba uthelekiso alulingani no-O(isimaphambili* ubude), apho isimaphambili silinani lezimaphambili, ubude bubude bomtya, ungasebenzisa i-deterministic finite automaton (DFA) eyakhiwe ngezimaphambili.

Makhe siqwalasele indlela yokwakha i-DFA kwiseti enikiweyo yezimaphambili. Siqalisa iikhesa ekuqaleni kwesimaphambili ngasinye. Ukuba zonke iikhesa zikhomba kuphawu olufanayo, ngoko nyusa ikhesa ngonobumba omnye kwaye ukhumbule ukuba ubude bomgca omnye bukhulu ngesinye. Ukuba kukho iikhesa ezimbini ezineesimboli ezahlukeneyo, yahlula-hlula iikhesa zibe ngamaqela ngokwesimboli ezikhomba kuyo kwaye uphinde i-algorithm yeqela ngalinye.

Kwimeko yokuqala (bonke abalinganiswa phantsi kwee-cursors bayafana), sifumana i-DFA state enenguqu enye kuphela kumgca ofanayo. Kwimeko yesibini, sifumana itheyibhile yeenguqu zesayizi 256 (inani labalinganiswa kunye nenani eliphezulu lamaqela) ukuya kumazwe alandelayo afunyenwe ngokubiza ngokuphindaphindiweyo umsebenzi.

Makhe sijonge umzekelo. Kuluhlu lwezimaphambili (“/foo/bar/tmp/”, “/var/db/foo/”, “/foo/bar/aba/”, “foo/bar/aac/”) ungafumana oku kulandelayo DFA. Umzobo ubonisa kuphela utshintsho olukhokelela kwamanye amazwe; ezinye iinguqu aziyi kuba zokugqibela.

Ungazikhusela njani iinkqubo kunye nokwandiswa kwekernel kwi-macOS

Xa uhamba ngeemeko ze-DKA, kunokubakho iimeko ezi-3.

  1. Isimo sokugqibela sifikelelwe - indlela ikhuselwe, sinciphisa imisebenzi KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA kunye ne KAUTH_VNODE_DELETE_CHILD
  2. Isimo sokugqibela asizange sifikelelwe, kodwa umendo "uphelile" (i-null terminator yafikelelwa) - umendo ungumzali, kuyimfuneko ukunciphisa i-KAUTH_VNODE_DELETE. Qaphela ukuba ukuba i-vnode sisiqulathi seefayili, kufuneka udibanise i-'/' ekugqibeleni, kungenjalo inokuyinqanda kwifayile “/foor/bar/t”, engeyiyo.
  3. Imeko yokugqibela ayizange ifike, indlela ayizange iphele. Akukho nasinye sezimaphambili esihambelana nesi, asazisi izithintelo.

isiphelo

Injongo yezisombululo zokhuseleko eziphuhliswayo kukunyusa izinga lokhuseleko lomsebenzisi kunye nedatha yakhe. Ngakolunye uhlangothi, le njongo ifezekiswa ngokuphuhliswa kwemveliso yesoftware ye-Acronis, evala ezo buthathaka apho inkqubo yokusebenza ngokwayo "ibuthathaka". Kwelinye icala, akufuneki sikutyeshele ukomeleza loo miba yokhuseleko enokuphuculwa kwicala le-OS, ngakumbi kuba ukuvala ubuthathaka obunjalo kwandisa ukuzinza kwethu njengemveliso. Ukuba sesichengeni kuye kwaxelwa kwiQela loKhuseleko lweMveliso ye-Apple kwaye ilungisiwe kwi-macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).

Ungazikhusela njani iinkqubo kunye nokwandiswa kwekernel kwi-macOS

Konke oku kunokwenziwa kuphela ukuba usetyenziso lwakho lufakwe ngokusemthethweni kwi-kernel. Oko kukuthi, akukho zikroba ezinjalo zesoftware yangaphandle nengafunwayo. Nangona kunjalo, njengoko ubona, nokukhusela iinkqubo ezisemthethweni ezifana ne-antivirus kunye neenkqubo zokulondoloza kufuna umsebenzi. Kodwa ngoku iimveliso ezintsha ze-Acronis ze-macOS ziya kuba nokhuseleko olongezelelweyo ekothuleni ngaphandle kwenkqubo.

umthombo: www.habr.com

Yongeza izimvo