Sut i amddiffyn prosesau ac estyniadau cnewyllyn ar macOS

Helo, Habr! Heddiw hoffwn siarad am sut y gallwch amddiffyn prosesau rhag ymosodiadau gan ymosodwyr yn macOS. Er enghraifft, mae hyn yn ddefnyddiol ar gyfer system gwrthfeirws neu wrth gefn, yn enwedig gan fod yna sawl ffordd o “ladd” proses o dan macOS. Darllenwch am hyn a dulliau amddiffyn o dan y toriad.

Sut i amddiffyn prosesau ac estyniadau cnewyllyn ar macOS

Y ffordd glasurol o “ladd” proses

Ffordd adnabyddus o “ladd” proses yw anfon signal SIGKILL i'r broses. Trwy bash gallwch chi alw'r safon “lladd -SIGKILL PID” neu “pkill -9 NAME” i ladd. Mae'r gorchymyn “lladd” wedi bod yn hysbys ers dyddiau UNIX ac mae ar gael nid yn unig ar macOS, ond hefyd ar systemau tebyg i UNIX.

Yn union fel mewn systemau tebyg i UNIX, mae macOS yn caniatáu ichi ryng-gipio unrhyw signalau i broses ac eithrio dau - SIGKILL a SIGSTOP. Bydd yr erthygl hon yn canolbwyntio'n bennaf ar y signal SIGKILL fel signal sy'n achosi i broses gael ei lladd.

manylion macOS

Ar macOS, mae galwad y system ladd yn y cnewyllyn XNU yn galw'r swyddogaeth psignal(SIGKILL,...). Gadewch i ni geisio gweld pa gamau defnyddwyr eraill yn y gofod defnyddwyr y gellir eu galw gan y swyddogaeth psignal. Gadewch i ni chwynnu galwadau i'r swyddogaeth psignal ym mecanweithiau mewnol y cnewyllyn (er y gallant fod yn ddibwys, byddwn yn eu gadael ar gyfer erthygl arall 🙂 - dilysu llofnod, gwallau cof, trin ymadael / terfynu, troseddau diogelu ffeiliau, ac ati .

Gadewch i ni ddechrau'r adolygiad gyda'r swyddogaeth a'r alwad system gyfatebol terfynu_gyda_llwyth tâl. Gellir gweld, yn ogystal â'r alwad lladd clasurol, fod yna ddull amgen sy'n benodol i system weithredu macOS ac nad yw i'w gael yn BSD. Mae egwyddorion gweithredu galwadau'r ddwy system hefyd yn debyg. Maent yn alwadau uniongyrchol i'r swyddogaeth cnewyllyn psignal. Sylwch hefyd, cyn lladd proses, bod gwiriad “cansignal” yn cael ei berfformio - a all y broses anfon signal i broses arall; nid yw'r system yn caniatáu i unrhyw gais ladd prosesau system, er enghraifft.

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

lansio

Mae'r ffordd safonol o greu daemons wrth gychwyn system a rheoli eu hoes yn cael ei lansio. Sylwch fod y ffynonellau ar gyfer yr hen fersiwn o launchctl hyd at macOS 10.10, darperir enghreifftiau cod at ddibenion enghreifftiol. Mae launchctl modern yn anfon signalau wedi'u lansio trwy XPC, mae rhesymeg launchctl wedi'i symud iddo.

Gadewch i ni edrych ar sut yn union ceisiadau yn cael eu stopio. Cyn anfon y signal SITERM, ceisir atal y cais gan ddefnyddio'r alwad system “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));
		} 
...
<>

O dan y cwfl, gall proc_terminate, er gwaethaf ei enw, anfon nid yn unig psignal gyda SITERM, ond hefyd SIGKILL.

Lladd Anuniongyrchol - Terfyn Adnoddau

Gellir gweld achos mwy diddorol mewn galwad system arall polisi_proses. Defnydd cyffredin o'r alwad system hon yw cyfyngu ar adnoddau cymhwysiad, fel mynegeiwr i gyfyngu ar amser CPU a chwotâu cof fel nad yw'r system yn cael ei arafu'n sylweddol gan weithgareddau storio ffeiliau. Os yw rhaglen wedi cyrraedd ei derfyn adnoddau, fel y gwelir o'r swyddogaeth proc_apply_resource_actions, anfonir signal SIGKILL i'r broses.

Er y gallai'r alwad system hon o bosibl ladd proses, nid oedd y system yn gwirio hawliau'r broses sy'n galw'r alwad system yn ddigonol. Gwirio mewn gwirionedd bodoli, ond mae'n ddigon defnyddio'r faner amgen PROC_POLICY_ACTION_SET i osgoi'r amod hwn.

Felly, os ydych chi'n “cyfyngu” ar gwota defnydd CPU y cais (er enghraifft, gan ganiatáu dim ond 1 ns i redeg), yna gallwch chi ladd unrhyw broses yn y system. Felly, gall y malware ladd unrhyw broses ar y system, gan gynnwys y broses gwrthfeirws. Diddorol hefyd yw'r effaith sy'n digwydd wrth ladd proses gyda pid 1 (launchctl) - panig cnewyllyn wrth geisio prosesu'r signal SIGKILL :)

Sut i amddiffyn prosesau ac estyniadau cnewyllyn ar macOS

Sut i ddatrys y broblem?

Y ffordd fwyaf syml o atal proses rhag cael ei lladd yw disodli'r pwyntydd swyddogaeth yn y tabl galwadau system. Yn anffodus, nid yw'r dull hwn yn ddibwys am lawer o resymau.

Yn gyntaf, mae'r symbol sy'n rheoli lleoliad cof sysent nid yn unig yn breifat i'r symbol cnewyllyn XNU, ond ni ellir ei ddarganfod mewn symbolau cnewyllyn. Bydd yn rhaid i chi ddefnyddio dulliau chwilio hewristig, megis dadosod y swyddogaeth yn ddeinamig a chwilio am bwyntydd ynddi.

Yn ail, mae strwythur y cofnodion yn y tabl yn dibynnu ar y fflagiau y lluniwyd y cnewyllyn â nhw. Os bydd y faner CONFIG_REQUIRES_U32_MUNGING yn cael ei datgan, bydd maint y strwythur yn cael ei newid - bydd maes ychwanegol yn cael ei ychwanegu sy_arg_munge32. Mae angen cynnal gwiriad ychwanegol i benderfynu pa faner y lluniwyd y cnewyllyn â hi, neu fel arall, gwirio pwyntiau swyddogaeth yn erbyn rhai hysbys.

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

Yn ffodus, mewn fersiynau modern o macOS, mae Apple yn darparu API newydd ar gyfer gweithio gyda phrosesau. Mae'r Endpoint Security API yn caniatáu i gleientiaid awdurdodi llawer o geisiadau i brosesau eraill. Felly, gallwch rwystro unrhyw signalau i brosesau, gan gynnwys y signal SIGKILL, gan ddefnyddio'r API uchod.

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

Yn yr un modd, gellir cofrestru Polisi MAC yn y cnewyllyn, sy'n darparu dull amddiffyn signal (polisi proc_check_signal), ond nid yw'r API yn cael ei gefnogi'n swyddogol.

Amddiffyniad estyniad cnewyllyn

Yn ogystal â diogelu prosesau yn y system, mae angen amddiffyn yr estyniad cnewyllyn ei hun (kext) hefyd. Mae macOS yn darparu fframwaith i ddatblygwyr ddatblygu gyrwyr dyfais IOKit yn hawdd. Yn ogystal â darparu offer ar gyfer gweithio gyda dyfeisiau, mae IOKit yn darparu dulliau ar gyfer pentyrru gyrwyr gan ddefnyddio enghreifftiau o ddosbarthiadau C ++. Bydd rhaglen yn y gofod defnyddiwr yn gallu “dod o hyd i” enghraifft gofrestredig o'r dosbarth i sefydlu perthynas cnewyllyn-defnyddiwr gofod.

I ganfod nifer yr achosion dosbarth yn y system, mae'r cyfleustodau ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Rhaid i unrhyw estyniad cnewyllyn sy'n dymuno cofrestru gyda'r pentwr gyrrwr ddatgan dosbarth sy'n etifeddu o IOService, er enghraifft my_kext_ioservice yn yr achos hwn. Mae cysylltu cymwysiadau defnyddiwr yn achosi creu enghraifft newydd o'r dosbarth sy'n etifeddu o IOUserClient, yn yr enghraifft my_kext_iouserclient.

Wrth geisio dadlwytho gyrrwr o'r system (gorchymyn kextunload), gelwir y swyddogaeth rithwir “terfynu bool (opsiynau IOOptionBits)”. Mae'n ddigon i ddychwelyd ffug ar yr alwad i derfynu wrth geisio dadlwytho i analluogi kextunload.

bool Kext::terminate(IOOptionBits options)
{

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

  return super::terminate(options);
}

Gall yr IOUserClient osod baner IsUnloadAllowed wrth lwytho. Pan fydd terfyn lawrlwytho, bydd y gorchymyn kextunload yn dychwelyd yr allbwn canlynol:

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.

Rhaid gwneud amddiffyniad tebyg ar gyfer IOUserClient. Gellir dadlwytho enghreifftiau o ddosbarthiadau gan ddefnyddio swyddogaeth gofod defnyddiwr IOKitLib “IOCatalogueTerminate (mach_port_t, baner uint32_t, disgrifiad io_name_t);”. Gallwch ddychwelyd ffug wrth alw'r gorchymyn “terfynu” nes bod y cymhwysiad userspace yn “marw”, hynny yw, ni elwir y swyddogaeth “clientDied”.

Diogelu Ffeil

Er mwyn diogelu ffeiliau, mae'n ddigon i ddefnyddio'r API Kauth, sy'n eich galluogi i gyfyngu mynediad i ffeiliau. Mae Apple yn rhoi hysbysiadau i ddatblygwyr am wahanol ddigwyddiadau yn y cwmpas; i ni, mae'r gweithrediadau KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA a KAUTH_VNODE_DELETE_CHILD yn bwysig. Y ffordd hawsaf i gyfyngu mynediad i ffeiliau yw trwy lwybr - rydym yn defnyddio'r API “vn_getpath” i gael y llwybr i'r ffeil a chymharu rhagddodiad y llwybr. Sylwch, er mwyn gwneud y gorau o ailenwi llwybrau ffolder ffeiliau, nid yw'r system yn awdurdodi mynediad i bob ffeil, ond dim ond i'r ffolder ei hun sydd wedi'i ailenwi. Mae angen cymharu'r llwybr rhiant a chyfyngu ar KAUTH_VNODE_DELETE ar ei gyfer.

Sut i amddiffyn prosesau ac estyniadau cnewyllyn ar macOS

Gall anfantais y dull hwn fod yn berfformiad isel wrth i nifer y rhagddodiaid gynyddu. Er mwyn sicrhau nad yw'r gymhariaeth yn hafal i O (rhagddodiad * hyd), lle mae rhagddodiad yn nifer y rhagddodiaid, hyd yw hyd y llinyn, gallwch ddefnyddio awtomaton terfynedig penderfynol (DFA) a adeiladwyd gan rhagddodiaid.

Gadewch i ni ystyried dull ar gyfer llunio DFA ar gyfer set benodol o rhagddodiaid. Rydym yn cychwyn y cyrchyddion ar ddechrau pob rhagddodiad. Os yw pob cyrchwr yn pwyntio at yr un cymeriad, yna cynyddwch bob cyrchwr o un nod a chofiwch fod hyd yr un llinell yn fwy gan un. Os oes dau gyrchwr gyda symbolau gwahanol, rhannwch y cyrchwyr yn grwpiau yn ôl y symbol maen nhw'n pwyntio ato ac ailadroddwch yr algorithm ar gyfer pob grŵp.

Yn yr achos cyntaf (mae'r holl nodau o dan y cyrchwyr yr un peth), rydyn ni'n cael cyflwr DFA sydd â dim ond un trawsnewidiad ar hyd yr un llinell. Yn yr ail achos, rydym yn cael tabl o drawsnewidiadau maint 256 (nifer y cymeriadau a'r nifer uchaf o grwpiau) i wladwriaethau dilynol a geir trwy alw'r swyddogaeth yn ailadroddus.

Gadewch i ni edrych ar enghraifft. Ar gyfer set o rhagddodiaid (“/ foo/bar/tmp/”, “/var/db/foo/”, “/ foo/bar/aba/”, “foo/bar/aac/”) gallwch gael y canlynol DFA. Mae'r ffigur yn dangos trawsnewidiadau sy'n arwain at wladwriaethau eraill yn unig; ni fydd trawsnewidiadau eraill yn derfynol.

Sut i amddiffyn prosesau ac estyniadau cnewyllyn ar macOS

Wrth fynd trwy daleithiau DKA, gall fod 3 achos.

  1. Mae'r cyflwr terfynol wedi'i gyrraedd - mae'r llwybr wedi'i warchod, rydym yn cyfyngu ar y gweithrediadau KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA a KAUTH_VNODE_DELETE_CHILD
  2. Ni chyrhaeddwyd y cyflwr terfynol, ond "daeth y llwybr i ben" (cyrhaeddwyd y terfynydd null) - rhiant yw'r llwybr, mae angen cyfyngu ar KAUTH_VNODE_DELETE. Sylwch, os yw vnode yn ffolder, mae angen i chi ychwanegu '/' ar y diwedd, fel arall gall ei gyfyngu i'r ffeil “/foor/bar/t”, sy'n anghywir.
  3. Ni chyrhaeddwyd y cyflwr terfynol, ni ddaeth y llwybr i ben. Nid oes yr un o'r rhagddodiaid yn cyd-fynd â'r un hwn, nid ydym yn cyflwyno cyfyngiadau.

Casgliad

Nod yr atebion diogelwch sy'n cael eu datblygu yw cynyddu lefel diogelwch y defnyddiwr a'i ddata. Ar y naill law, cyflawnir y nod hwn trwy ddatblygu cynnyrch meddalwedd Acronis, sy'n cau'r gwendidau hynny lle mae'r system weithredu ei hun yn “wan”. Ar y llaw arall, ni ddylem esgeuluso cryfhau'r agweddau diogelwch hynny y gellir eu gwella ar ochr yr OS, yn enwedig gan fod cau gwendidau o'r fath yn cynyddu ein sefydlogrwydd ein hunain fel cynnyrch. Adroddwyd am y bregusrwydd i Dîm Diogelwch Cynnyrch Apple ac mae wedi'i drwsio yn macOS 10.14.5 ( https://support.apple.com/en-gb/HT210119 ).

Sut i amddiffyn prosesau ac estyniadau cnewyllyn ar macOS

Dim ond os yw'ch cyfleustodau wedi'i osod yn swyddogol yn y cnewyllyn y gellir gwneud hyn i gyd. Hynny yw, nid oes unrhyw fylchau o'r fath ar gyfer meddalwedd allanol a diangen. Fodd bynnag, fel y gwelwch, mae hyd yn oed amddiffyn rhaglenni cyfreithlon fel gwrthfeirws a systemau wrth gefn yn gofyn am waith. Ond nawr bydd gan gynhyrchion Acronis newydd ar gyfer macOS amddiffyniad ychwanegol rhag dadlwytho o'r system.

Ffynhonnell: hab.com

Ychwanegu sylw