# macOS .Net Applications Injection {{#include ../../../banners/hacktricks-training.md}} **Ovo je sažetak posta [https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/](https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/). Proverite za više detalja!** ## .NET Core Debugging ### **Usmeravanje Debugging Sesije** Upravljanje komunikacijom između debagera i debuggee u .NET-u se vrši putem [**dbgtransportsession.cpp**](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/shared/dbgtransportsession.cpp). Ova komponenta postavlja dve imenovane cevi po .NET procesu, kao što je prikazano u [dbgtransportsession.cpp#L127](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/shared/dbgtransportsession.cpp#L127), koje se iniciraju putem [twowaypipe.cpp#L27](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/debug-pal/unix/twowaypipe.cpp#L27). Ove cevi su sa sufiksima **`-in`** i **`-out`**. Posetom korisnikovom **`$TMPDIR`**, mogu se pronaći debugging FIFO dostupni za debugging .Net aplikacije. [**DbgTransportSession::TransportWorker**](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/shared/dbgtransportsession.cpp#L1259) je odgovoran za upravljanje komunikacijom iz debagera. Da bi se započela nova debugging sesija, debager mora poslati poruku putem `out` cevi koja počinje sa `MessageHeader` strukturom, detaljno opisanu u .NET izvoru: ```c struct MessageHeader { MessageType m_eType; // Message type DWORD m_cbDataBlock; // Size of following data block (can be zero) DWORD m_dwId; // Message ID from sender DWORD m_dwReplyId; // Reply-to Message ID DWORD m_dwLastSeenId; // Last seen Message ID by sender DWORD m_dwReserved; // Reserved for future (initialize to zero) union { struct { DWORD m_dwMajorVersion; // Requested/accepted protocol version DWORD m_dwMinorVersion; } VersionInfo; ... } TypeSpecificData; BYTE m_sMustBeZero[8]; } ``` Da biste zatražili novu sesiju, ova struktura se popunjava na sledeći način, postavljajući tip poruke na `MT_SessionRequest` i verziju protokola na trenutnu verziju: ```c static const DWORD kCurrentMajorVersion = 2; static const DWORD kCurrentMinorVersion = 0; // Configure the message type and version sSendHeader.m_eType = MT_SessionRequest; sSendHeader.TypeSpecificData.VersionInfo.m_dwMajorVersion = kCurrentMajorVersion; sSendHeader.TypeSpecificData.VersionInfo.m_dwMinorVersion = kCurrentMinorVersion; sSendHeader.m_cbDataBlock = sizeof(SessionRequestData); ``` Ova glava se zatim šalje cilju koristeći `write` syscall, nakon čega sledi `sessionRequestData` struktura koja sadrži GUID za sesiju: ```c write(wr, &sSendHeader, sizeof(MessageHeader)); memset(&sDataBlock.m_sSessionID, 9, sizeof(SessionRequestData)); write(wr, &sDataBlock, sizeof(SessionRequestData)); ``` Operacija čitanja na `out` cevi potvrđuje uspeh ili neuspeh uspostavljanja sesije debagovanja: ```c read(rd, &sReceiveHeader, sizeof(MessageHeader)); ``` ## Čitanje Memorije Kada je sesija debagovanja uspostavljena, memorija se može čitati koristeći [`MT_ReadMemory`](https://github.com/dotnet/runtime/blob/f3a45a91441cf938765bafc795cbf4885cad8800/src/coreclr/src/debug/shared/dbgtransportsession.cpp#L1896) tip poruke. Funkcija readMemory je detaljno opisana, obavljajući neophodne korake za slanje zahteva za čitanje i preuzimanje odgovora: ```c bool readMemory(void *addr, int len, unsigned char **output) { // Allocation and initialization ... // Write header and read response ... // Read the memory from the debuggee ... return true; } ``` Potpuni dokaz koncepta (POC) je dostupan [ovde](https://gist.github.com/xpn/95eefc14918998853f6e0ab48d9f7b0b). ## Pisanje u Memoriju Slično tome, memorija se može pisati koristeći funkciju `writeMemory`. Proces uključuje postavljanje tipa poruke na `MT_WriteMemory`, određivanje adrese i dužine podataka, a zatim slanje podataka: ```c bool writeMemory(void *addr, int len, unsigned char *input) { // Increment IDs, set message type, and specify memory location ... // Write header and data, then read the response ... // Confirm memory write was successful ... return true; } ``` Povezani POC je dostupan [ovde](https://gist.github.com/xpn/7c3040a7398808747e158a25745380a5). ## .NET Core Izvršavanje Koda Da bi se izvršio kod, potrebno je identifikovati memorijsku oblast sa rwx dozvolama, što se može uraditi koristeći vmmap -pages: ```bash vmmap -pages [pid] vmmap -pages 35829 | grep "rwx/rwx" ``` Lociranje mesta za prepisivanje pokazivača funkcije je neophodno, a u .NET Core, to se može uraditi ciljanjem na **Dynamic Function Table (DFT)**. Ova tabela, detaljno opisana u [`jithelpers.h`](https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/coreclr/src/inc/jithelpers.h), koristi se od strane runtime-a za JIT kompilacione pomoćne funkcije. Za x64 sisteme, pretraživanje potpisa može se koristiti za pronalaženje reference na simbol `_hlpDynamicFuncTable` u `libcorclr.dll`. Debugger funkcija `MT_GetDCB` pruža korisne informacije, uključujući adresu pomoćne funkcije, `m_helperRemoteStartAddr`, koja ukazuje na lokaciju `libcorclr.dll` u memoriji procesa. Ova adresa se zatim koristi za započinjanje pretrage za DFT i prepisivanje pokazivača funkcije sa adresom shellcode-a. Puni POC kod za injekciju u PowerShell je dostupan [ovde](https://gist.github.com/xpn/b427998c8b3924ab1d63c89d273734b6). ## References - [https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/](https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/) {{#include ../../../banners/hacktricks-training.md}}