Ungazivikela kanjani izinqubo kanye nezandiso ze-kernel ku-macOS

Sawubona, Habr! Namuhla ngithanda ukukhuluma ngokuthi ungazivikela kanjani izinqubo ekuhlaselweni ngabahlaseli ku-macOS. Isibonelo, lokhu kuyasiza ku-antivirus noma uhlelo lokusekelayo, ikakhulukazi njengoba ngaphansi kwe-macOS kunezindlela ezimbalwa "zokubulala" inqubo. Funda ngalokhu kanye nezindlela zokuvikela ngaphansi kokunqunywa.

Ungazivikela kanjani izinqubo kanye nezandiso ze-kernel ku-macOS

Indlela yakudala "yokubulala" inqubo

Indlela eyaziwayo "yokubulala" inqubo ukuthumela isignali ye-SIGKILL kunqubo. Nge-bash ungabiza indinganiso ethi “kill -SIGKILL PID” noma “pkill -9 NAME” ukuze ubulale. Umyalo othi "bulala" waziwa kusukela ezinsukwini ze-UNIX futhi awutholakali kuphela kuma-macOS, kodwa nakwezinye izinhlelo ezifana ne-UNIX.

Njengamasistimu afana ne-UNIX, i-macOS ikuvumela ukuthi ubambe noma yimaphi amasiginali kwinqubo ngaphandle kwamabili - SIGKILL kanye ne-SIGSTOP. Lesi sihloko sizogxila kakhulu kusiginali ye-SIGKILL njengesignali ebangela ukuthi inqubo ibulawe.

imininingwane ye-macOS

Ku-macOS, ucingo lwesistimu yokubulala ku-XNU kernel lubiza umsebenzi we-psignal(SIGKILL,...). Ake sizame ukubona ukuthi yiziphi ezinye izenzo zabasebenzisi endaweni yomsebenzisi ezingabizwa ngomsebenzi we-psignal. Ake sikhiphe izingcingo emsebenzini we-psignal ezindleleni zangaphakathi ze-kernel (yize zingase zingabi nalutho, kodwa sizozishiya kwesinye isihloko 🙂 - ukuqinisekiswa kwesiginesha, amaphutha enkumbulo, ukuphuma / ukunqamula ukuphatha, ukwephulwa kokuvikelwa kwefayela, njll.

Ake siqale isibuyekezo ngomsebenzi kanye nekholi yesistimu ehambisanayo qeda_ngomthwalo_wokukhokhelwa. Kungabonakala ukuthi ngaphezu kocingo lwakudala lokubulala, kunenye indlela eqondene nohlelo lokusebenza lwe-macOS futhi ayitholakali ku-BSD. Izimiso zokusebenza zazo zombili izingcingo zesistimu nazo ziyefana. Ziyizingcingo eziqondile zomsebenzi we-kernel psignal. Futhi qaphela ukuthi ngaphambi kokubulala inqubo, ukuhlolwa kwe-“cansignal” kuyenziwa - noma ngabe inqubo ingathumela isignali kwenye inqubo; isistimu ayivumeli noma yiluphi uhlelo lokusebenza ukubulala izinqubo zesistimu, isibonelo.

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

yethuliwe

Indlela ejwayelekile yokudala ama-daemon ekuqaleni kwesistimu nokulawula impilo yawo yonke yethulwa. Sicela uqaphele ukuthi imithombo ingeyenguqulo yakudala ye-launchctl kuze kufike ku-macOS 10.10, izibonelo zekhodi zinikezwa ngezinjongo zokubonisa. I-Launchctl yesimanje ithumela amasiginali ethulwe nge-XPC, i-launchctl logic ithuthelwe kuyo.

Ake sibheke ukuthi izicelo zimiswa kanjani. Ngaphambi kokuthumela isignali ye-SIGTERM, uhlelo lokusebenza luzanywa ukuyekiswa kusetshenziswa ikholi yesistimu ethi “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));
		} 
...
<>

Ngaphansi kwe-hood, i-proc_terminate, naphezu kwegama layo, ayikwazi ukuthumela i-psignal nge-SIGTERM kuphela, kodwa futhi ne-SIGKILL.

Ukubulala Okungaqondile - Umkhawulo Wensiza

Ikesi elithakasela kakhulu lingabonwa kwenye ikholi yesistimu inqubo_yenqubomgomo. Ukusetshenziswa okuvamile kwalolu cingo lwesistimu ukukhawulela izinsiza zohlelo lokusebenza, okufana nenkomba ukuthi ikhawulele isikhathi se-CPU nezilinganiso zememori ukuze isistimu inganciphisi ngokuphawulekayo imisebenzi yokulondolozwa kwefayela. Uma uhlelo lokusebenza selufinyelele umkhawulo walo wensiza, njengoba kungabonwa kumsebenzi we-proc_apply_resource_actions, isignali ye-SIGKILL ithunyelwa kunqubo.

Nakuba le kholi yesistimu ingase ibulale inqubo, isistimu ayizange ihlole ngokwanele amalungelo enqubo yokubiza ikholi yesistimu. Empeleni ngiyahlola yayikhona, kodwa kwanele ukusebenzisa elinye ifulegi elingu-PROC_POLICY_ACTION_SET ukuze udlule lesi simo.

Ngakho-ke, uma "ukhawulela" i-quota yokusetshenziswa kwe-CPU yohlelo lokusebenza (isibonelo, uvumela i-ns engu-1 kuphela ukuthi isebenze), ungabulala noma iyiphi inqubo ohlelweni. Ngakho, uhlelo olungayilungele ikhompuyutha lungabulala noma iyiphi inqubo ohlelweni, kuhlanganise nenqubo yokulwa namagciwane. Okunye okuthokozisayo umphumela owenzeka lapho kubulawa inqubo nge-pid 1 (launchctl) - kernel panic lapho izama ukucubungula isiginali ye-SIGKILL :)

Ungazivikela kanjani izinqubo kanye nezandiso ze-kernel ku-macOS

Indlela yokuxazulula inkinga?

Indlela eqonde kakhulu yokuvimbela inqubo ukuthi ingabulawa ukufaka esikhundleni sesikhombi somsebenzi kuthebula lekholi lesistimu. Ngeshwa, le ndlela ayiyona into encane ngenxa yezizathu eziningi.

Okokuqala, uphawu olulawula indawo yenkumbulo ye-sysent alugcini nje ngokuyimfihlo kuphawu lwe-XNU kernel, kodwa alukwazi ukutholakala kuzimpawu ze-kernel. Kuzodingeka usebenzise izindlela zokusesha ze-heuristic, njengokuqaqa umsebenzi nokusesha i-pointer kuwo.

Okwesibili, ukwakheka kokufakiwe etafuleni kuncike kumafulegi lapho i-kernel yahlanganiswa khona. Uma ifulegi le-CONFIG_REQUIRES_U32_MUNGING limenyezelwa, usayizi wesakhiwo uzoshintshwa - inkambu eyengeziwe izokwengezwa. sy_arg_munge32. Kuyadingeka ukwenza ukuhlola okwengeziwe ukuze kutholwe ukuthi iliphi ifulegi elahlanganiswa ne-kernel, noma ngenye indlela, hlola izikhombisi zokusebenza ngokumelene nabaziwayo.

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

Ngenhlanhla, ezinguqulweni zanamuhla ze-macOS, i-Apple inikeza i-API entsha yokusebenza ngezinqubo. I-Endpoint Security API ivumela amaklayenti ukuthi agunyaze izicelo eziningi kwezinye izinqubo. Ngakho-ke, ungavimba noma yiziphi izimpawu ezinqubweni, okuhlanganisa isignali ye-SIGKILL, usebenzisa i-API eshiwo ngenhla.

#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, Inqubomgomo ye-MAC ingabhaliswa ku-kernel, ehlinzeka ngendlela yokuvikela isignali (inqubomgomo ye-proc_check_signal), kodwa i-API ayisekelwe ngokusemthethweni.

Ukuvikelwa kwesandiso se-Kernel

Ngaphezu kokuvikela izinqubo ohlelweni, ukuvikela isandiso se-kernel ngokwayo (i-kext) kuyadingeka. I-macOS ihlinzeka ngohlaka lwabathuthukisi ukuthuthukisa kalula abashayeli bedivayisi ye-IOKit. Ngaphezu kokuhlinzeka ngamathuluzi okusebenza ngamadivayisi, i-IOKit inikeza izindlela zokupakisha abashayeli kusetshenziswa izimo zamakilasi e-C++. Uhlelo lokusebenza endaweni yomsebenzisi luzokwazi "ukuthola" isenzakalo esibhalisiwe sekilasi ukuze kusungulwe ubudlelwano be-kernel-userspace.

Ukuze uthole inani lezimo zekilasi ohlelweni, kukhona insiza ye-ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Noma isiphi isandiso se-kernel esifisa ukubhalisa nesitaki somshayeli kufanele simemezele ikilasi elizuza njengefa ku-IOService, isibonelo my_kext_ioservice kulesi simo. Ukuxhuma izinhlelo zokusebenza zomsebenzisi kubangela ukudalwa kwesibonelo esisha sekilasi elizuza njengefa ku-IOUserClient, kusibonelo my_kext_iouserclient.

Uma uzama ukuthulula umshayeli ohlelweni (umyalo we-kextunload), umsebenzi we-virtual "bool terminate(izinketho ze-IOOptionBits)" ubizwa. Kwanele ukubuyisela okungamanga ocingweni ukuze kunqanyulwe lapho uzama ukukhulula ukuze ukhubaze i-kextunload.

bool Kext::terminate(IOOptionBits options)
{

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

  return super::terminate(options);
}

Ifulegi le-IsUnloadAllowed lingasethwa yi-IOUserClient lapho lilayisha. Uma kunomkhawulo wokulanda, umyalo we-kextunload uzobuyisela okukhiphayo okulandelayo:

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.

Ukuvikelwa okufanayo kufanele kwenziwe ku-IOUserClient. Izimo zamakilasi zingalayishwa kusetshenziswa umsebenzi we-IOKitLib wendawo yomsebenzisi othi “IOCatalogueTerminate(mach_port_t, uint32_t flag, io_name_t description);”. Ungabuyisela okungamanga uma ubiza umyalo othi "phelisa" kuze kube yilapho uhlelo lokusebenza lwendawo yomsebenzisi "lufa", okungukuthi, umsebenzi we-"clientDied" awubizwa.

Ukuvikelwa Kwefayela

Ukuze uvikele amafayela, kwanele ukusebenzisa i-Kauth API, ekuvumela ukuthi ukhawulele ukufinyelela kumafayela. I-Apple inikeza onjiniyela izaziso mayelana nemicimbi eyahlukene kusikophu; kithina, ukusebenza kuka-KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA kanye ne-KAUTH_VNODE_DELETE_CHILD kubalulekile. Indlela elula yokukhawulela ukufinyelela kumafayela yindlela - sisebenzisa i-"vn_getpath" API ukuze sithole indlela eya kufayela futhi siqhathanise isiqalo sendlela. Qaphela ukuthi ukuze kuthuthukiswe ukuqanjwa kabusha kwezindlela zefolda yefayela, uhlelo alugunyazi ukufinyelela kufayela ngalinye, kodwa kuphela kufolda ngokwayo eye yaqanjwa kabusha. Kuyadingeka ukuqhathanisa indlela yomzali futhi ukhawulele i-KAUTH_VNODE_DELETE kuyo.

Ungazivikela kanjani izinqubo kanye nezandiso ze-kernel ku-macOS

Ububi bale ndlela kungase kube ukusebenza okuphansi njengoba inani leziqalo likhula. Ukuqinisekisa ukuthi ukuqhathanisa akulingani no-O(prefix*length), lapho isiqalo siyinani leziqalo, ubude buwubude beyunithi yezinhlamvu, ungasebenzisa i-deterministic finite automaton (DFA) eyakhiwe ngeziqalo.

Ake sicabangele indlela yokwakha i-DFA yeqoqo elithile leziqalo. Siqalisa amakhesa ekuqaleni kwesiqalo ngasinye. Uma zonke izikhombisi zikhomba uhlamvu olufanayo, bese ukhuphula ikhesa ngayinye ngohlamvu olulodwa futhi ukhumbule ukuthi ubude bomugqa ofanayo bukhulu ngowodwa. Uma kukhona izikhombisi ezimbili ezinezimpawu ezihlukene, hlukanisa izikhombisi zibe ngamaqembu ngokophawu ezikhomba kulo bese uphinda i-algorithm yeqembu ngalinye.

Esimweni sokuqala (zonke izinhlamvu ezingaphansi kwezikhombisi ziyafana), sithola isimo se-DFA esinoguquko olulodwa kuphela emgqeni ofanayo. Esimeni sesibili, sithola ithebula lezinguquko likasayizi 256 (inombolo yezinhlamvu kanye nenani eliphezulu lamaqembu) ukuya ezifundeni ezilandelayo ezitholwe ngokubiza umsebenzi ngokuphindaphindiwe.

Ake sibheke isibonelo. Ukuze uthole iqoqo leziqalo (“/foo/bar/tmp/”, “/var/db/foo/”, “/foo/bar/aba/”, “foo/bar/aac/”) ungathola okulandelayo I-DFA. Isibalo sibonisa kuphela izinguquko eziholela kwezinye izifundazwe; ezinye izinguquko ngeke zibe okokugcina.

Ungazivikela kanjani izinqubo kanye nezandiso ze-kernel ku-macOS

Uma udlula ezifundeni ze-DKA, kungase kube nezimo ezi-3.

  1. Isimo sokugcina sifinyelelwe - indlela ivikelwe, sikhawulela imisebenzi KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA kanye ne-KAUTH_VNODE_DELETE_CHILD
  2. Isimo sokugcina asifinyelelwanga, kodwa indlela "yaphela" (i-null terminator yafinyelelwa) - indlela ingumzali, kuyadingeka ukukhawulela i-KAUTH_VNODE_DELETE. Qaphela ukuthi uma i-vnode iyifolda, udinga ukwengeza u-'/' ekugcineni, ngaphandle kwalokho ingase ikhawulele kufayela elithi “/foor/bar/t”, elingalungile.
  3. Isimo sokugcina asifinyelelwanga, indlela ayizange iphele. Asikho isiqalo esifana nalesi, asethuli imikhawulo.

isiphetho

Umgomo wezixazululo zokuphepha ezithuthukiswayo ukukhulisa izinga lokuphepha lomsebenzisi nedatha yakhe. Ngakolunye uhlangothi, lo mgomo ufezwa ngokuthuthukiswa komkhiqizo wesofthiwe ye-Acronis, evala lezo zingozi lapho uhlelo lokusebenza ngokwayo "lubuthakathaka". Ngakolunye uhlangothi, akufanele sikudebesele ukuqinisa lezo zici zokuphepha ezingathuthukiswa ngasohlangothini lwe-OS, ikakhulukazi njengoba ukuvala ubungozi obunjalo kukhulisa ukuzinza kwethu njengomkhiqizo. Ukuba sengozini kubikwe Ithimba Lokuvikela Lomkhiqizo We-Apple futhi kulungisiwe ku-macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).

Ungazivikela kanjani izinqubo kanye nezandiso ze-kernel ku-macOS

Konke lokhu kungenziwa kuphela uma ukusetshenziswa kwakho kufakwe ngokusemthethweni ku-kernel. Okusho ukuthi, azikho izintuba ezinjalo zesofthiwe yangaphandle nengadingeki. Kodwa-ke, njengoba ubona, ngisho nokuvikela izinhlelo ezisemthethweni ezifana ne-antivirus kanye nezinhlelo zokusekelayo kudinga umsebenzi. Kepha manje imikhiqizo emisha ye-Acronis ye-macOS izoba nesivikelo esengeziwe ekukhipheni ohlelweni.

Source: www.habr.com

Engeza amazwana