Otu esi echekwa usoro na mgbakwunye kernel na macOS

Ndewo, Habr! Taa, m ga-achọ ikwu maka otu ị ga - esi kpuchido usoro site na mwakpo nke ndị na-awakpo na macOS. Dịka ọmụmaatụ, nke a bara uru maka antivirus ma ọ bụ usoro ndabere, ọkachasị ebe ọ bụ na n'okpuru macOS enwere ọtụtụ ụzọ isi “gbuo” usoro. Gụọ banyere nke a na ụzọ nchebe n'okpuru ịkpụ.

Otu esi echekwa usoro na mgbakwunye kernel na macOS

The kpochapụwo ụzọ "igbu" a usoro

Ụzọ a maara nke ọma iji "gbuo" usoro bụ izipu akara SIGKILL na usoro ahụ. Site na bash ị nwere ike ịkpọ ọkọlọtọ "kill -SIGKILL PID" ma ọ bụ "pkill -9 NAME" igbu. Amara iwu "egbu" kemgbe ụbọchị UNIX ma dị ọ bụghị naanị na macOS, kamakwa na sistemụ UNIX ndị ọzọ.

Dịka ọ dị na sistemụ UNIX, macOS na-enye gị ohere igbochi akara ọ bụla na usoro ma ewezuga abụọ - SIGKILL na SIGSTOP. Edemede a ga-elekwasị anya na mgbama SIGKILL dị ka ihe mgbaàmà na-eme ka e gbuo usoro.

MacOS akọwapụtara

Na macOS, usoro igbu egbu na-akpọ na XNU kernel na-akpọ ọrụ psignal (SIGKILL, ...). Ka anyị gbalịa ịhụ ihe omume onye ọrụ ndị ọzọ na ebe ọrụ nwere ike ịkpọ site na ọrụ psignal. Ka anyị wepụ oku na-aga na ọrụ psignal n'ime usoro nke kernel (ọ bụ ezie na ha nwere ike ịbụ ihe na-adịghị mkpa, anyị ga-ahapụ ha maka edemede ọzọ 🙂 - nkwenye mbinye aka, njehie ebe nchekwa, nkwụsị / kwụsị njikwa, mmebi nchekwa faịlụ, wdg. .

Ka anyị malite nyochaa na ọrụ na oku usoro kwekọrọ kwụsị_na_ụgwọ. Enwere ike ịhụ na na mgbakwunye na oku igbu egbu, enwere ụzọ ọzọ nke akọwapụtara maka sistemụ arụmọrụ macOS na achọtaghị na BSD. Ụkpụrụ ọrụ nke oku sistemụ abụọ ahụ nwekwara otu ihe ahụ. Ha bụ oku ozugbo na psignal ọrụ kernel. Rịba ama na tupu igbu usoro, a na-eme nlele "cansignal" - ma usoro ahụ nwere ike izipu akara na usoro ọzọ; usoro ahụ anaghị ekwe ka ngwa ọ bụla gbuo usoro usoro, dịka ọmụmaatụ.

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

malite

Ewepụtala usoro ọkọlọtọ iji mepụta daemons na mmalite sistemụ yana ịchịkwa oge ndụ ha. Biko mara na isi mmalite ndị ahụ bụ maka ụdị launchctl ochie ruo macOS 10.10, a na-enye ihe atụ koodu maka ebumnuche nkọwa. Launchtl ọgbara ọhụrụ na-eziga akara ngosi ewepụtara site na XPC, ebugharịla mgbagha Launchertl na ya.

Ka anyị leba anya ka esi kwụsị ngwa ngwa. Tupu izipu akara SIGTERM, a na-anwa ịkwụsị ngwa a site na iji oku sistemụ “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));
		} 
...
<>

N'okpuru mkpuchi, proc_terminate, n'agbanyeghị aha ya, nwere ike izipu ọ bụghị naanị psignal na SIGTERM, kamakwa SIGKILL.

Ọnwụ na-apụtaghị ìhè - Oke akụrụngwa

Enwere ike ịhụ ikpe na-adọrọ mmasị karị na oku usoro ọzọ usoro_usoro. Oku usoro a na-ejikarị eme ihe bụ ịmachi akụrụngwa ngwa, dị ka maka onye na-egosi indexer machichi oge CPU na oke ebe nchekwa ka sistemu ahụ ghara iji nwayọ nwayọ site na mmemme caching faịlụ. Ọ bụrụ na ngwa eruola oke akụrụngwa ya, dịka enwere ike ịhụ site na ọrụ proc_apply_resource_actions, a na-eziga akara SIGKILL na usoro a.

Ọ bụ ezie na oku usoro a nwere ike igbu usoro, usoro ahụ enyochaghị nke ọma ikike nke usoro na-akpọ oku usoro. N'ezie ịlele dịrị, mana o zuola iji ọkọlọtọ ọzọ PROC_POLICY_ACTION_SET iji gafere ọnọdụ a.

N'ihi ya, ọ bụrụ na ị "na-amachi" oke ojiji CPU nke ngwa ahụ (dịka ọmụmaatụ, kwe ka naanị 1 ns na-agba ọsọ), mgbe ahụ ị nwere ike igbu usoro ọ bụla na sistemụ. Ya mere, malware nwere ike igbu usoro ọ bụla na sistemụ, gụnyere usoro antivirus. Ihe na-adọrọ mmasị bụ mmetụta na-eme mgbe ejiri pid 1 (launchctl) na-egbu usoro - ụjọ kernel mgbe ị na-agbalị ịhazi akara ngosi SIGKILL :)

Otu esi echekwa usoro na mgbakwunye kernel na macOS

Kedu ka esi edozi nsogbu ahụ?

Ụzọ kachasị mfe iji gbochie usoro igbu egbu bụ iji dochie ihe nrịbama ọrụ na tebụl oku usoro. N'ụzọ dị mwute, usoro a abụghị ihe efu n'ihi ọtụtụ ihe kpatara ya.

Nke mbụ, akara nke na-achịkwa ebe nchekwa sysent abụghị naanị nzuzo na akara kernel XNU, mana enweghị ike ịhụ ya na akara kernel. Ị ga-eji ụzọ nchọta heuristic, dị ka ikposa ọrụ ahụ n'ike na ịchọ ntụnye n'ime ya.

Nke abuo, nhazi nke ntinye na tebụl na-adabere na ọkọlọtọ nke ejiri chịkọta kernel. Ọ bụrụ na ekwuputa ọkọlọtọ CONFIG_REQUIRES_U32_MUNGING, a ga-agbanwe nha nke ihe owuwu ahụ - a ga-agbakwunye mpaghara ọzọ. sy_arg_munge32. Ọ dị mkpa ịme nyocha ọzọ iji chọpụta ọkọlọtọ kernel ejiri, ma ọ bụ ọzọ, lelee nrụnye ọrụ megide ndị ama ama.

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

Ọ dabara nke ọma, na ụdị macOS ọgbara ọhụrụ, Apple na-enye API ọhụrụ maka ịrụ ọrụ na usoro. Nchekwa Endpoint API na-enye ndị ahịa ikike inye ọtụtụ arịrịọ maka usoro ndị ọzọ. Yabụ, ị nwere ike igbochi akara ọ bụla na usoro, gụnyere akara SIGKILL, site na iji API akpọtụrụla n'elu.

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

N'otu aka ahụ, enwere ike ịdebanye aha iwu MAC na kernel, nke na-enye usoro nchebe mgbama (usoro iwu proc_check_signal), mana API anaghị akwado ya n'ihu ọha.

Nchekwa ndọtị kernel

Na mgbakwunye na ichebe usoro na usoro, ichebe kernel ndọtị n'onwe ya (kext) dịkwa mkpa. MacOS na-enye usoro maka ndị mmepe ka ha zụlite ndị ọkwọ ụgbọ ala IOKit ngwa ngwa. Na mgbakwunye na ịnye ngwaọrụ maka ịrụ ọrụ na ngwaọrụ, IOKit na-enye ụzọ maka ịkwọ ụgbọ ala na-eji ihe atụ nke klaasị C ++. Ngwa dị na ebe ọrụ ga-enwe ike "ịchọta" ihe atụ edebanyere aha nke klaasị iji guzobe mmekọrịta kernel-userspace.

Iji chọpụta ọnụọgụ nke klaasị na sistemụ, enwere ike ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Mgbakwunye kernel ọ bụla nke chọrọ ịdebanye aha na nchịkọta ọkwọ ụgbọ ala ga-ekwupụta klas nke ketara na ọrụ IOS, dịka ọmụmaatụ my_kext_ioservice na nke a. Ijikọ ngwa onye ọrụ na-eme ka ịmepụta ihe ọhụrụ nke klas nke ketara n'aka IOUserClient, na ihe atụ my_kext_iouserclient.

Mgbe ị na-agbalị ibupu onye ọkwọ ụgbọ ala na sistemụ (iwu kextunload), a na-akpọ ọrụ mebere “bool terminate(nhọrọ IOOptionBits)”. O zuru ezu ịlaghachi ụgha na oku ahụ iji kwụsị mgbe ị na-agbalị ibutu iji gbanyụọ kextunload.

bool Kext::terminate(IOOptionBits options)
{

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

  return super::terminate(options);
}

Ndị IOUserClient nwere ike ịtọ ọkọlọtọ IsUnloadAllowed mgbe ị na-ebu. Mgbe enwere oke nbudata, iwu kextunload ga-eweghachi mmepụta ndị a:

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.

A ga-emerịrị nchedo yiri nke ahụ maka IOUserClient. Enwere ike ibudata ihe atụ nke klaasị site na iji ọrụ IOKitLib userspace "IOCatalogueTerminate(mach_port_t, uint32_t flag, io_name_t nkọwa);". Ị nwere ike ịlaghachi ụgha mgbe ị na-akpọ iwu "kwụsị" ruo mgbe ngwa userspace "nwụrụ", ya bụ, a naghị akpọ ọrụ "clientDied".

Nchedo faịlụ

Iji chekwaa faịlụ, o zuru ezu iji Kauth API, nke na-enye gị ohere igbochi ịnweta faịlụ. Apple na-enye ndị mmepe ọkwa gbasara mmemme dị iche iche n'okirikiri; maka anyị, ọrụ KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA na KAUTH_VNODE_DELETE_CHILD dị mkpa. Ụzọ kachasị mfe iji gbochie ịnweta faịlụ bụ site n'ụzọ - anyị na-eji API "vn_getpath" nweta ụzọ faịlụ ahụ wee tulee prefix ụzọ. Rịba ama na iji kwalite renaming nke ụzọ nchekwa faịlụ, usoro anaghị enye ikike ịnweta faịlụ ọ bụla, kama ọ bụ naanị na nchekwa n'onwe ya nke ahagharịrị aha. Ọ dị mkpa ịtụnyere ụzọ nne na nna wee machibido KAUTH_VNODE_DELETE maka ya.

Otu esi echekwa usoro na mgbakwunye kernel na macOS

Ọdịmma nke ụzọ a nwere ike ịbụ arụmọrụ dị ala ka ọnụọgụ prefixes na-abawanye. Iji jide n'aka na ntụnyere ahụ erughị O (prefix * ogologo), ebe prefix bụ ọnụọgụ prefixes, ogologo bụ ogologo eriri, ị nwere ike iji deterministic finite automaton (DFA) wuru site na prefixes.

Ka anyị tulee usoro maka iwulite DFA maka otu prefixes enyere. Anyị na-ebido cursors na mmalite nke nganiihu ọ bụla. Ọ bụrụ na cursors niile na-atụ aka n'otu agwa, wee bulie cursor nke ọ bụla site na otu agwa wee cheta na ogologo nke otu ahịrị ka ukwuu site na otu. Ọ bụrụ na enwere cursors abụọ nwere akara dị iche iche, kewaa cursors n'ime otu dị ka akara ha na-atụ aka ma megharịa algọridim maka otu ọ bụla.

N'okwu nke mbụ (ihe odide niile dị n'okpuru cursors bụ otu), anyị na-enweta steeti DFA nke nwere naanị otu mgbanwe n'otu ahịrị. N'okwu nke abụọ, anyị na-enweta tebụl ntụgharị nke nha 256 (ọnụọgụ mkpụrụedemede na ọnụ ọgụgụ kachasị elu) na steeti ndị na-esote nke enwetara site na-akpọghachi ọrụ ahụ ugboro ugboro.

Ka anyị lee otu ihe atụ. Maka nhazi prefixes ("/foo/bar/tmp/", "/var/db/foo/", "/foo/bar/aba/","foo/bar/aac/") ị nwere ike nweta ihe ndị a DFA. Ọnụọgụ a na-egosi naanị mgbanwe na-eduga na steeti ndị ọzọ; Ntugharị ndị ọzọ agaghị adị ikpeazụ.

Otu esi echekwa usoro na mgbakwunye kernel na macOS

Mgbe ị na-aga na steeti DKA, enwere ike ịnwe ikpe 3.

  1. Eruola steeti ikpeazụ - echekwara ụzọ ahụ, anyị na-amachi ọrụ KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA na KAUTH_VNODE_DELETE_CHILD
  2. Eruteghị steeti ikpeazụ, mana ụzọ ahụ “kwụsịrị” (a ruru null terminator) - ụzọ bụ nne na nna, ọ dị mkpa ịgbachi KAUTH_VNODE_DELETE. Rịba ama na ọ bụrụ na vnode bụ folda, ịkwesịrị ịgbakwunye '/' na njedebe, ma ọ bụghị ya, ọ nwere ike kpachi ya na faịlụ "/foor/bar/t", nke ezighi ezi.
  3. Eruteghị steeti ikpeazụ, ụzọ ahụ akwụsịghị. Ọ nweghị prefixes ọ bụla dabara na nke a, anyị anaghị ewebata mmachi.

nkwubi

Ebumnuche nke ngwọta nchekwa a na-emepụta bụ ịbawanye ọkwa nchekwa nke onye ọrụ na data ya. N'otu aka ahụ, a na-enweta ihe mgbaru ọsọ a site na mmepe nke ngwaahịa software Acronis, nke na-emechi adịghị ike ndị ahụ ebe sistemụ arụmọrụ n'onwe ya dị "adịghị ike". N'aka nke ọzọ, anyị ekwesịghị ileghara iwusi akụkụ nchekwa ndị ahụ ike nke nwere ike imeziwanye n'akụkụ OS, karịsịa ebe ọ bụ na imechi adịghị ike dị otú ahụ na-abawanye nkwụsi ike nke anyị dị ka ngwaahịa. A kọọrọ ndị otu nchekwa ngwaahịa Apple adịghị ike ma edozi ya na macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).

Otu esi echekwa usoro na mgbakwunye kernel na macOS

Enwere ike ịme ihe ndị a niile ma ọ bụrụ na etinyela akụrụngwa gị n'ihu ọha na kernel. Ya bụ, enweghị oghere dị otú ahụ maka ngwanrọ mpụga na nke achọghị. Otú ọ dị, dị ka ị pụrụ ịhụ, ọbụna ichekwa omume ziri ezi dị ka antivirus na ndabere usoro chọrọ ọrụ. Mana ugbu a ngwaahịa Acronis ọhụrụ maka macOS ga-enwekwa nchebe ọzọ megide nbudata na sistemụ.

isi: www.habr.com

Tinye a comment