Sida loo ilaaliyo hababka iyo kordhinta kernel ee macOS

Hello, Habr! Maanta waxaan jeclaan lahaa inaan ka hadlo sida aad uga ilaalin karto hababka weerarada weeraryahanada ee macOS. Tusaale ahaan, tani waxay faa'iido u leedahay antivirus ama nidaamka kaydinta, gaar ahaan maadaama macOS hoostiisa ay jiraan siyaabo dhowr ah oo loo "dilo" habka. Ka akhriso arrintan iyo hababka ilaalinta ee hoos ku qoran.

Sida loo ilaaliyo hababka iyo kordhinta kernel ee macOS

Habka caadiga ah ee loo "dilo" habka

Habka caanka ah ee loo "dilo" habka waa in loo diro calaamad SIGKILL habka. Bash waxaad wici kartaa heerka "kill -SIGKILL PID" ama "pkill -9 NAME" si aad u disho. Amarka "dilka" ayaa la yaqaan tan iyo maalmihii UNIX waxaana laga heli karaa oo keliya macOS, laakiin sidoo kale nidaamyada kale ee UNIX-sida.

Sida nidaamyada UNIX-la mid ah, macOS wuxuu kuu oggolaanayaa inaad farageliso calaamad kasta oo geeddi-socodka marka laga reebo laba - SIGKILL iyo SIGSTOP. Maqaalkani wuxuu ugu horreyn diiradda saari doonaa calaamadda SIGKILL oo ah calaamad sababeysa in habka loo dilo.

macOS gaar ah

MacOS, nidaamka dilaaga ah ee ku jira kernel-ka XNU wuxuu ugu yeeraa shaqada psignal (SIGKILL, ...). Aan isku dayno inaan aragno waxa ficilada kale ee isticmaalaha ee goobta adeegsadaha loogu yeeri karo shaqada psignal. Aynu ka saarno wicitaanada shaqada psignal ee hababka gudaha ee kernel (in kasta oo ay noqon karaan kuwo aan waxtar lahayn, laakiin waxaan u dhaafi doonaa maqaal kale πŸ™‚ - xaqiijinta saxeexa, khaladaadka xusuusta, bixitaanka / joojinta maaraynta, xadgudubyada ilaalinta faylka, iwm.

Aynu dib u eegis ku bilowno shaqada iyo nidaamka u dhigma wacitaanka ku joojiya_load_load. Waxaa la arki karaa in marka lagu daro wicitaanka dilka caadiga ah, ay jirto hab kale oo gaar ah nidaamka hawlgalka macOS oo aan laga helin BSD. Mabaadi'da hawlgalka ee labadaba nidaamka wicitaanada sidoo kale waa isku mid. Waa wicitaano toos ah oo ku socda psignal function kernel. Sidoo kale ogow in ka hor inta aan la dilin habka, jeeg "cansignal" ayaa la sameeyaa - haddii habka uu u diri karo calaamad hab kale; nidaamku ma ogola wax codsi ah inuu dilo hababka nidaamka, tusaale ahaan.

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

bilaabay

Habka caadiga ah ee loo abuuro daemons-ka nidaamka bilowga iyo xakamaynta noloshooda ayaa la bilaabay. Fadlan la soco in ilaha loogu talagalay noocii hore ee launchctl ilaa macOS 10.10, tusaalooyin kood ayaa loo bixiyay ujeeddooyin sawireed. Launcherctl casriga ah wuxuu soo diraa calaamado la bilaabay iyada oo loo sii marayo XPC, launchctl logic ayaa loo raray.

Aynu eegno sida saxda ah ee codsiyada loo joojiyo. Kahor intaadan dirin calaamada SIGTERM, arjiga waxaa la isku dayaa in la joojiyo iyadoo la isticmaalayo nidaamka "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));
		} 
...
<>

Daboolka hoostiisa, proc_terminate, in kasta oo magaciisa, ma soo diri karo fariin qoraal ah oo keliya SIGTERM, laakiin sidoo kale SIGKILL.

Dil aan toos ahayn - Xadka Kheyraadka

Kiis aad u xiiso badan ayaa lagu arki karaa wicitaanka nidaamka kale nidaamka_siyaasadda. Isticmaalka caadiga ah ee wicitaanka nidaamkan ayaa ah in la xaddido agabka codsiga, sida indexer si loo xaddido wakhtiga CPU iyo kootada xusuusta si aanu nidaamku si weyn hoos ugu dhicin hawlaha kaydinta faylalka. Haddii codsi uu gaaro xadka kheyraadka, sida laga arki karo shaqada proc_apply_resource_actions, calaamad SIGKILL ah ayaa loo diraa habka.

Inkasta oo wicitaanka nidaamkani uu dili karo hab-socodka, nidaamku si ku filan uma hubin xuquuqda habka wacitaanka nidaamka. Dhab ahaantii hubinta jiray, laakiin waa ku filan in la isticmaalo calanka kale ee PROC_POLICY_ACTION_SET si looga gudbo xaaladan.

Sidaa darteed, haddii aad "xakamayso" kootada isticmaalka CPU ee codsiga (tusaale ahaan, u oggolaanaya 1 ns oo keliya inuu shaqeeyo), markaa waxaad dili kartaa nidaam kasta oo nidaamka. Sidaa darteed, malware-ku wuxuu dili karaa nidaam kasta oo ku jira nidaamka, oo ay ku jiraan habka antivirus. Sidoo kale xiisaha ayaa ah saameynta ka dhalata marka lagu dilo nidaamka pid 1 (launchctl) - argagaxa kernel marka la isku dayayo in la farsameeyo calaamadaha SIGKILL :)

Sida loo ilaaliyo hababka iyo kordhinta kernel ee macOS

Sidee loo xalliyaa dhibaatada?

Habka ugu fudud ee looga hortagi karo habka in la dilo waa in la beddelo tilmaame hawleedka miiska wicitaanka nidaamka. Nasiib darro, habkani maaha mid fudud sababo badan dartood.

Marka hore, calaamada maamusha goobta xusuusta ee sysent maahan mid gaar u ah calaamadda kernel-ka ee XNU, laakiin lagama heli karo calaamadaha kernel-ka. Waa inaad isticmaashaa hababka raadinta heuristic, sida si firfircoon u kala dirida shaqada iyo raadinta tilmaame ku jira.

Marka labaad, qaab-dhismeedka jaantusku wuxuu ku xiran yahay calammada kernel-ka lagu soo ururiyay. Haddii calanka CONFIG_REQUIRES_U32_MUNGING lagu dhawaaqo, cabbirka qaab-dhismeedka waa la beddeli doonaa - goob dheeraad ah ayaa lagu dari doonaa sy_arg_munge32. Waa lagama maarmaan in la sameeyo hubin dheeraad ah si loo go'aamiyo calanka kernel-ka la sameeyay, ama beddelkeeda, ka hubi tilmaamayaasha shaqada ee kuwa la yaqaan.

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

Nasiib wanaag, noocyada casriga ah ee macOS, Apple waxay ku siisaa API cusub oo lagula shaqeynayo hababka. Amniga Endpoint API wuxuu u oggolaanayaa macaamiisha inay oggolaadaan codsiyo badan oo hababka kale ah. Markaa, waxaad xannibi kartaa calaamad kasta oo hab-socodka, oo ay ku jirto ishaarka SIGKILL, addoo isticmaalaya API-ga aan kor ku soo sheegnay.

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

Sidoo kale, Siyaasadda MAC waxaa laga diiwaan gelin karaa kernel-ka, kaas oo bixiya habka ilaalinta calaamadda (policy proc_check_signal), laakiin API si rasmi ah looma taageero.

Ilaalinta fidinta kernel

Marka lagu daro ilaalinta hababka nidaamka, ilaalinta fidinta kernel lafteeda (kext) sidoo kale waa lagama maarmaan. MacOS waxay siisaa qaab-dhismeed loogu talagalay horumariyeyaasha si ay si fudud u horumariyaan darawallada aaladda IOKit. Marka laga soo tago bixinta qalabka lagu shaqeeyo aaladaha, IOKit waxay siisaa habab loogu talagalay isugaynta darawalka iyadoo la adeegsanayo tusaalooyinka C++. Codsiga goobta adeegsaduhu wuxuu awood u yeelan doonaa inuu "helo" tusaale diiwaangashan ee fasalka si loo dhiso xiriirka kernel-userspace.

Si loo ogaado tirada xaaladaha fasalka ee nidaamka, waxaa jira utility ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Kordhin kasta oo kernel ah oo raba in uu iska diiwaan geliyo xidhmada darawalka waa in uu ku dhawaaqaa fasalka dhaxlaya adeegga IOS, tusaale ahaan my_kext_ioservice kiiskan. Isku xidhka codsiyada isticmaalaha waxay sababtaa abuurista tusaale cusub oo fasalka ah oo ka dhaxlaya IOUserClient, tusaale ahaan my_kext_iouserclient.

Markaad isku dayeyso inaad ka dejiso darawalka nidaamka (amarka kextunload), shaqada farsamada "bool terminate(IOOptionBits options)" ayaa loo yaqaan. Way ku filan tahay inaad been ku soo celiso wicitaanka si aad u joojiso marka aad isku dayayso inaad dejiso kextunload.

bool Kext::terminate(IOOptionBits options)
{

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

  return super::terminate(options);
}

Calanka IsUnloadAllowed waxaa dejin kara IOUserClient marka la soo shubayo. Marka ay jirto xadka soo dejinta, amarka kextunload wuxuu soo celin doonaa soosaarka soo socda:

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.

Ilaalinta la midka ah waa in loo sameeyaa IOUserClient. Tusaalooyinka fasallada waa la dejin karaa iyadoo la adeegsanayo IOKitLib shaqada goobta adeegsadaha "IOCatalogueTerminate(mach_port_t, calanka uint32_t, sharaxaad io_name_t);". Waxaad ku soo celin kartaa been markaad wacdo amarka "joojinta" ilaa codsiga goobta isticmaalaha "dhimanayo", taas oo ah, shaqada "clientDied" lama yeerin.

Ilaalinta faylka

Si loo ilaaliyo faylasha, waa ku filan inaad isticmaasho Kauth API, kaas oo kuu ogolaanaya inaad xaddido gelitaanka faylasha. Apple waxay siisaa horumariyeyaasha ogeysiisyada ku saabsan dhacdooyinka kala duwan ee baaxadda leh; anaga, anaga, hawlgallada KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA iyo KAUTH_VNODE_DELETE_CHILD waa muhiim. Habka ugu fudud ee lagu xaddidi karo gelitaanka faylalka waa dariiqa - waxaan isticmaalnaa "vn_getpath" API si aan u helno waddada faylka oo aan barbar dhigno horgalaha waddada. Ogsoonow in si loo wanaajiyo magac-beddelka dariiqyada galka faylka, nidaamku ma oggola gelitaanka fayl kasta, laakiin kaliya galka laftiisa ee la beddelay. Waa lagama maarmaan in la is barbar dhigo dariiqa waalidka oo loo xaddido KAUTH_VNODE_DELETE.

Sida loo ilaaliyo hababka iyo kordhinta kernel ee macOS

Khasaaraha habkani wuxuu noqon karaa waxqabad hooseeya marka tirada horgalayaasha ay korodho. Si loo hubiyo in isbarbardhigga uusan la mid ahayn O (horgagga * dhererka), halka horgaleyaashu yahay tirada horgalayaasha, dhererku waa dhererka xadhigga, waxaad isticmaali kartaa deterministic automaton (DFA), oo lagu dhisay horgalayaasha.

Aynu ka fikirno habka loo dhisayo DFA ee gogol horgalayaal ah oo la bixiyay. Waxaan bilownay cursors bilowga horgale kasta. Haddii dhammaan cursers ay tilmaamayaan isla dabeecad, ka dib ku kordhi cursor kasta hal xaraf oo xusuusnow in dhererka isla xariiqda uu ka weyn yahay hal. Haddii ay jiraan laba curors oo leh calaamado kala duwan, u qaybi cursors kooxo sida calaamadda ay tilmaamayaan oo ku celi algorithm koox kasta.

Xaaladda koowaad (dhammaan jilayaasha hoostooda waa isku mid), waxaan helnaa gobolka DFA oo leh hal wareejin oo keliya oo isla xariiq isku mid ah. Xaaladda labaad, waxaan helnaa jadwalka kala-guurka ee cabbirka 256 (tirada jilayaasha iyo tirada ugu badan ee kooxaha) ee gobollada xiga ee la helay iyadoo si isdaba-joog ah loogu yeero shaqada.

Bal aan tusaale u soo qaadano. Horgalayaasha horgalayaasha ah ("/foo/bar/tmp/", "/var/db/foo/", "/foo/bar/aba/", "foo/bar/aac/") waxaad heli kartaa kuwan soo socda DFA. Shaxanku waxa uu muujinayaa kala-guurka u horseedaya gobollo kale;

Sida loo ilaaliyo hababka iyo kordhinta kernel ee macOS

Marka la marayo gobolada DKA, waxaa jiri kara 3 xaaladood.

  1. Gobolkii ugu dambeeyay waa la gaarey - wadada waa la ilaaliyaa, waxaan xaddideynaa hawlgallada KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA iyo KAUTH_VNODE_DELETE_CHILD
  2. Gobolka kama dambaysta ah lama gaarin, laakiin dariiqa "dhamaatay" (terminator null waa la gaaray) - dariiqa waa waalid, waa lagama maarmaan in la xaddido KAUTH_VNODE_DELETE. Ogsoonow haddii vnode uu yahay gal, waxaad u baahan tahay inaad ku darto '/' dhamaadka, haddii kale waxay ku xaddidi kartaa faylka "/foor/bar/t", taas oo khaldan.
  3. Gobolkii ugu dambeeyay lama gaarin, wadadii ma dhammaan. Horgalayaasha midkoodna kan kama dhigna, ma soo bandhigno xaddidaadyo.

gunaanad

Hadafka xalalka amniga ee la sameeyay waa in la kordhiyo heerka amniga isticmaalaha iyo xogtiisa. Dhinaca kale, yoolkan waxaa lagu gaaraa horumarinta sheyga software Acronis, kaas oo xiraya dayacanka halka nidaamka hawlgalka laftiisa uu yahay "daciif". Dhanka kale, waa in aynaan dayacin xoojinta dhinacyada amniga ee lagu hagaajin karo dhinaca OS-ka, gaar ahaan maadaama xiritaanka dayacanka noocan oo kale ah ay kordhinayso xasilloonidayada badeecad ahaan. Nuglaanta waxaa loo sheegay Kooxda Ammaanka Alaabada Apple waxaana lagu hagaajiyay macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).

Sida loo ilaaliyo hababka iyo kordhinta kernel ee macOS

Waxaas oo dhan waxa la samayn karaa oo keliya haddii tamartaada si rasmi ah loogu rakibay kernel-ka. Taasi waa, ma jiraan daldaloolo noocan oo kale ah software dibadda iyo aan la rabin. Si kastaba ha noqotee, sida aad arki karto, xitaa ilaalinta barnaamijyada sharciga ah sida antivirus iyo nidaamyada kaydinta waxay u baahan tahay shaqo. Laakiin hadda alaabooyinka cusub ee Acronis ee macOS waxay yeelan doonaan ilaalin dheeraad ah oo ka dhan ah soo dejinta nidaamka.

Source: www.habr.com

Add a comment