Kif tipproteġi l-proċessi u l-estensjonijiet tal-kernel fuq macOS

Hello, Habr! Illum nixtieq nitkellem dwar kif tista' tipproteġi l-proċessi minn attakki minn attakkanti f'macOS. Pereżempju, dan huwa utli għal sistema antivirus jew backup, speċjalment peress li taħt macOS hemm diversi modi biex "joqtol" proċess. Aqra dwar dan u metodi ta 'protezzjoni taħt il-qatgħa.

Kif tipproteġi l-proċessi u l-estensjonijiet tal-kernel fuq macOS

Il-mod klassiku biex "joqtol" proċess

Mod magħruf sew biex "joqtol" proċess huwa li tibgħat sinjal SIGKILL lill-proċess. Permezz ta 'bash tista' ssejjaħ l-istandard "qatla -SIGKILL PID" jew "pkill -9 ISEM" biex toqtol. Il-kmand "joqtol" ilu magħruf minn żmien l-UNIX u huwa disponibbli mhux biss fuq macOS, iżda wkoll fuq sistemi oħra simili għal UNIX.

Eżatt bħal f'sistemi bħal UNIX, macOS jippermettilek li tinterċetta kwalunkwe sinjal għal proċess ħlief tnejn - SIGKILL u SIGSTOP. Dan l-artikolu se jiffoka primarjament fuq is-sinjal SIGKILL bħala sinjal li jikkawża proċess li jinqatel.

ispeċifiċitajiet macOS

Fuq macOS, is-sejħa tas-sistema tal-qtil fil-kernel XNU ssejjaħ il-funzjoni psignal(SIGKILL,...). Ejja nippruvaw naraw liema azzjonijiet oħra tal-utent fl-ispazju tal-utent jistgħu jissejħu mill-funzjoni psignal. Ejja ineħħu s-sejħiet għall-funzjoni psignal fil-mekkaniżmi interni tal-qalba (għalkemm jistgħu jkunu mhux trivjali, imma nħalluhom għal artikolu ieħor 🙂 - verifika tal-firma, żbalji fil-memorja, ħruġ/terminazzjoni tal-ġestjoni, ksur tal-protezzjoni tal-fajls, eċċ.

Ejja nibdew ir-reviżjoni bil-funzjoni u s-sejħa tas-sistema korrispondenti terminate_with_payload. Wieħed jista 'jara li minbarra s-sejħa klassika tal-qatla, hemm approċċ alternattiv li huwa speċifiku għas-sistema operattiva macOS u ma jinstabx fil-BSD. Il-prinċipji operattivi taż-żewġ sejħiet tas-sistema huma wkoll simili. Huma sejħiet diretti għall-funzjoni tal-kernel psignal. Innota wkoll li qabel ma jinqatel proċess, issir verifika ta '"cansignal" - jekk il-proċess jistax jibgħat sinjal lil proċess ieħor; is-sistema ma tippermetti ebda applikazzjoni biex toqtol proċessi tas-sistema, pereżempju.

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

launchd

Il-mod standard biex jinħolqu daemons fl-istartjar tas-sistema u jikkontrollaw il-ħajja tagħhom huwa mniedi. Jekk jogħġbok innota li s-sorsi huma għall-verżjoni l-antika ta' launchctl sa macOS 10.10, eżempji ta' kodiċi huma pprovduti għal skopijiet illustrattivi. Launchctl modern jibgħat sinjali launchd permezz XPC, il-loġika launchctl ġiet imċaqalqa lejha.

Ejja nħarsu lejn kif eżattament l-applikazzjonijiet jitwaqqfu. Qabel ma jintbagħat is-sinjal SIGTERM, l-applikazzjoni qed tipprova titwaqqaf bl-użu tas-sejħa tas-sistema “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));
		} 
...
<>

Taħt il-barnuża, proc_terminate, minkejja l-isem tiegħu, jista 'jibgħat mhux biss psignal ma' SIGTERM, iżda wkoll SIGKILL.

Qtil indirett - Limitu tar-Riżorsi

Każ aktar interessanti jista' jidher f'sejħa oħra tas-sistema proċess_politika. Użu komuni ta 'din is-sejħa tas-sistema huwa li jillimita r-riżorsi tal-applikazzjoni, bħal għal indiċjar biex jillimita l-ħin tas-CPU u l-kwoti tal-memorja sabiex is-sistema ma titnaqqasx b'mod sinifikanti mill-attivitajiet tal-caching tal-fajls. Jekk applikazzjoni tkun laħqet il-limitu tar-riżorsi tagħha, kif jidher mill-funzjoni proc_apply_resource_actions, jintbagħat sinjal SIGKILL lill-proċess.

Għalkemm din is-sejħa tas-sistema tista' potenzjalment toqtol proċess, is-sistema ma vverifikatx b'mod adegwat id-drittijiet tal-proċess li jsejjaħ is-sejħa tas-sistema. Attwalment verifika kien jeżisti, iżda huwa biżżejjed li tuża l-bandiera alternattiva PROC_POLICY_ACTION_SET biex tevita din il-kundizzjoni.

Għalhekk, jekk "tillimita" il-kwota tal-użu tas-CPU tal-applikazzjoni (pereżempju, tħalli 1 ns biss taħdem), allura tista 'toqtol kwalunkwe proċess fis-sistema. Għalhekk, il-malware jista 'joqtol kwalunkwe proċess fuq is-sistema, inkluż il-proċess antivirus. Interessanti wkoll l-effett li jseħħ meta jinqatel proċess b'pid 1 (launchctl) - paniku tal-qalba meta tipprova tipproċessa s-sinjal SIGKILL :)

Kif tipproteġi l-proċessi u l-estensjonijiet tal-kernel fuq macOS

Kif issolvi l-problema?

L-aktar mod sempliċi biex jiġi evitat li proċess jinqatel huwa li jissostitwixxi l-pointer tal-funzjoni fit-tabella tas-sejħiet tas-sistema. Sfortunatament, dan il-metodu mhuwiex trivjali għal ħafna raġunijiet.

L-ewwel, is-simbolu li jikkontrolla l-post tal-memorja tas-sysent mhuwiex biss privat għas-simbolu tal-qalba XNU, iżda ma jistax jinstab fis-simboli tal-qalba. Ikollok tuża metodi ta 'tfittxija euristiku, bħal żarmament dinamiku tal-funzjoni u tfittxija għal pointer fiha.

It-tieni nett, l-istruttura tal-entrati fit-tabella tiddependi fuq il-bnadar li bihom ġie kkompilat il-qalba. Jekk tiġi ddikjarata l-bandiera CONFIG_REQUIRES_U32_MUNGING, id-daqs tal-istruttura se jinbidel - se jiġi miżjud qasam addizzjonali sy_arg_munge32. Huwa meħtieġ li titwettaq verifika addizzjonali biex tiddetermina liema bandiera ġiet ikkumpilata l-kernel, jew alternattivament, iċċekkja l-indikaturi tal-funzjoni ma 'dawk magħrufa.

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

Fortunatament, fil-verżjonijiet moderni ta 'macOS, Apple tipprovdi API ġdida biex taħdem ma' proċessi. L-API Endpoint Security tippermetti lill-klijenti jawtorizzaw ħafna talbiet għal proċessi oħra. Għalhekk, tista 'tibblokka kwalunkwe sinjali għall-proċessi, inkluż is-sinjal SIGKILL, billi tuża l-API msemmija hawn fuq.

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

Bl-istess mod, Politika MAC tista 'tiġi rreġistrata fil-qalba, li tipprovdi metodu ta' protezzjoni tas-sinjal (policy proc_check_signal), iżda l-API mhix appoġġjata uffiċjalment.

Protezzjoni tal-estensjoni tal-kernel

Minbarra l-protezzjoni tal-proċessi fis-sistema, il-protezzjoni tal-estensjoni tal-kernel innifsu (kext) hija meħtieġa wkoll. macOS jipprovdi qafas għall-iżviluppaturi biex jiżviluppaw faċilment is-sewwieqa tal-apparat IOKit. Minbarra li jipprovdi għodda biex taħdem ma 'apparati, IOKit jipprovdi metodi għall-istivar tas-sewwieqa bl-użu ta' każijiet ta 'klassijiet C++. Applikazzjoni fl-ispazju tal-utent tkun tista' "ssib" istanza reġistrata tal-klassi biex tistabbilixxi relazzjoni bejn il-kernel u l-ispazju tal-utent.

Biex tiskopri n-numru ta 'istanzi ta' klassi fis-sistema, hemm l-utilità ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Kwalunkwe estensjoni tal-kernel li tixtieq tirreġistra mal-munzell tas-sewwieq għandha tiddikjara klassi li tirret minn IOService, pereżempju my_kext_ioservice f'dan il-każ. Il-konnessjoni tal-applikazzjonijiet tal-utent tikkawża l-ħolqien ta 'istanza ġdida tal-klassi li tirret minn IOUserClient, fl-eżempju my_kext_iouserclient.

Meta tipprova tħoll sewwieq mis-sistema (kmand kextunload), tissejjaħ il-funzjoni virtwali "bool terminate(IOOptionBits options)". Huwa biżżejjed li tirritorna falza fuq is-sejħa biex tittermina meta tipprova tħoll biex tiddiżattiva kextunload.

bool Kext::terminate(IOOptionBits options)
{

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

  return super::terminate(options);
}

Il-bandiera IsUnloadAllowed tista' tiġi ssettjata mill-IOUserClient waqt it-tagħbija. Meta jkun hemm limitu ta 'tniżżil, il-kmand ta' kextunload jirritorna l-output li ġej:

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.

Protezzjoni simili għandha ssir għal IOUserClient. L-istanzi tal-klassijiet jistgħu jinħattu bl-użu tal-funzjoni tal-ispazju tal-utent IOKitLib “IOCatalogueTerminate(mach_port_t, uint32_t flag, io_name_t description);”. Tista 'tirritorna falza meta ssejjaħ il-kmand "terminate" sakemm l-applikazzjoni tal-ispazju tal-utent "tmut", jiġifieri, il-funzjoni "clientDied" ma tissejjaħx.

Protezzjoni tal-fajls

Biex tipproteġi l-fajls, huwa biżżejjed li tuża l-API Kauth, li tippermettilek tirrestrinġi l-aċċess għall-fajls. Apple tipprovdi lill-iżviluppaturi b'notifiki dwar diversi avvenimenti fl-ambitu; għalina, l-operazzjonijiet KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA u KAUTH_VNODE_DELETE_CHILD huma importanti. L-eħfef mod biex tirrestrinġi l-aċċess għall-fajls huwa bil-mogħdija - nużaw l-API “vn_getpath” biex niksbu t-triq għall-fajl u nqabblu l-prefiss tal-mogħdija. Innota li biex tottimizza t-tismija mill-ġdid tal-mogħdijiet tal-folders tal-fajls, is-sistema ma tawtorizzax aċċess għal kull fajl, iżda biss għall-folder innifsu li ngħata isem ġdid. Huwa meħtieġ li titqabbel il-mogħdija ġenitur u tirrestrinġi KAUTH_VNODE_DELETE għaliha.

Kif tipproteġi l-proċessi u l-estensjonijiet tal-kernel fuq macOS

L-iżvantaġġ ta 'dan l-approċċ jista' jkun prestazzjoni baxxa hekk kif in-numru ta 'prefissi jiżdied. Biex tiżgura li t-tqabbil ma jkunx ugwali għal O (prefiss * tul), fejn il-prefiss huwa n-numru ta 'prefissi, it-tul huwa t-tul tas-sekwenza, tista' tuża awtomat finit deterministiku (DFA) mibni minn prefissi.

Ejja nikkunsidraw metodu għall-kostruzzjoni ta 'DFA għal sett partikolari ta' prefissi. Aħna inizjalizzaw il-cursors fil-bidu ta 'kull prefiss. Jekk il-cursors kollha jindikaw l-istess karattru, imbagħad żid kull cursor b'karattru wieħed u ftakar li t-tul tal-istess linja huwa akbar b'wieħed. Jekk hemm żewġ cursors b'simboli differenti, jaqsam il-cursors fi gruppi skond is-simbolu li jindikaw u rrepeti l-algoritmu għal kull grupp.

Fl-ewwel każ (il-karattri kollha taħt il-cursors huma l-istess), aħna nġibu stat DFA li għandu tranżizzjoni waħda biss tul l-istess linja. Fit-tieni każ, irridu nġibu tabella ta 'tranżizzjonijiet ta' daqs 256 (numru ta 'karattri u numru massimu ta' gruppi) għal stati sussegwenti miksuba billi ssejjaħ b'mod rikorsiv il-funzjoni.

Ejja nħarsu lejn eżempju. Għal sett ta’ prefissi (“/foo/bar/tmp/”, “/var/db/foo/”, “/foo/bar/aba/”, “foo/bar/aac/”) tista’ tikseb dan li ġej DFA. Il-figura turi biss tranżizzjonijiet li jwasslu għal stati oħra; tranżizzjonijiet oħra mhux se jkunu finali.

Kif tipproteġi l-proċessi u l-estensjonijiet tal-kernel fuq macOS

Meta tgħaddi mill-istati DKA, jista 'jkun hemm 3 każijiet.

  1. L-istat finali intlaħaq - il-mogħdija hija protetta, aħna nillimitaw l-operazzjonijiet KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA u KAUTH_VNODE_DELETE_CHILD
  2. L-istat finali ma ntlaħaqx, iżda l-mogħdija "intemmet" (it-terminatur null intlaħaq) - il-mogħdija hija ġenitur, huwa meħtieġ li jiġi limitat KAUTH_VNODE_DELETE. Innota li jekk vnode huwa folder, għandek bżonn iżżid '/' fl-aħħar, inkella tista' tillimitaha għall-fajl "/foor/bar/t", li mhux korrett.
  3. L-istat finali ma ntlaħaqx, it-triq ma spiċċatx. L-ebda prefiss ma jaqbel ma' dan, aħna ma nintroduċu restrizzjonijiet.

Konklużjoni

L-għan tas-soluzzjonijiet ta 'sigurtà li qed jiġu żviluppati huwa li jiżdied il-livell ta' sigurtà tal-utent u d-data tiegħu. Min-naħa waħda, dan l-għan jintlaħaq bl-iżvilupp tal-prodott tas-softwer Acronis, li jagħlaq dawk il-vulnerabbiltajiet fejn is-sistema operattiva nnifisha hija "dgħajfa". Min-naħa l-oħra, m'għandniex nittraskuraw it-tisħiħ ta 'dawk l-aspetti tas-sigurtà li jistgħu jittejbu min-naħa tal-OS, speċjalment peress li l-għeluq ta' vulnerabbiltajiet bħal dawn iżid l-istabbiltà tagħna stess bħala prodott. Il-vulnerabbiltà ġiet irrappurtata lit-Tim tas-Sigurtà tal-Prodott Apple u ġiet iffissata f'macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).

Kif tipproteġi l-proċessi u l-estensjonijiet tal-kernel fuq macOS

Dan kollu jista' jsir biss jekk l-utilità tiegħek tkun ġiet installata uffiċjalment fil-qalba. Jiġifieri, m'hemm l-ebda lakuni bħal dawn għal softwer estern u mhux mixtieq. Madankollu, kif tistgħu taraw, anki l-protezzjoni ta 'programmi leġittimi bħal sistemi antivirus u backup teħtieġ xogħol. Imma issa prodotti ġodda Acronis għal macOS se jkollhom protezzjoni addizzjonali kontra l-ħatt mis-sistema.

Sors: www.habr.com

Żid kumment