macOS .Net Toepassings Inspuiting
Reading time: 5 minutes
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Dit is 'n opsomming van die pos https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/. Kyk daarna vir verdere besonderhede!
.NET Kern Foutopsporing
Oopstel van 'n Foutopsporing Sessie
Die hantering van kommunikasie tussen die foutopsporing en die foutopsporing doelwit in .NET word bestuur deur dbgtransportsession.cpp. Hierdie komponent stel twee benoemde pype per .NET proses op soos gesien in dbgtransportsession.cpp#L127, wat geinitieer word via twowaypipe.cpp#L27. Hierdie pype is gesuffikseerd met -in
en -out
.
Deur die gebruiker se $TMPDIR
te besoek, kan 'n mens foutopsporing FIFOs vind wat beskikbaar is vir die foutopsporing van .Net toepassings.
DbgTransportSession::TransportWorker is verantwoordelik vir die bestuur van kommunikasie van 'n foutopsporing. Om 'n nuwe foutopsporing sessie te begin, moet 'n foutopsporing 'n boodskap via die out
pyp stuur wat begin met 'n MessageHeader
struktuur, soos in die .NET bronskode uiteengesit:
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];
}
Om 'n nuwe sessie aan te vra, word hierdie struktuur soos volg ingevul, wat die boodskap tipe op MT_SessionRequest
stel en die protokol weergawe op die huidige weergawe:
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);
Hierdie kop is dan na die teiken gestuur met die write
syscall, gevolg deur die sessionRequestData
struktuur wat 'n GUID vir die sessie bevat:
write(wr, &sSendHeader, sizeof(MessageHeader));
memset(&sDataBlock.m_sSessionID, 9, sizeof(SessionRequestData));
write(wr, &sDataBlock, sizeof(SessionRequestData));
'n Leesoperasie op die out
pyp bevestig die sukses of mislukking van die debugging-sessie se totstandkoming:
read(rd, &sReceiveHeader, sizeof(MessageHeader));
Geheue Lees
Sodra 'n foutopsporing sessie gevestig is, kan geheue gelees word met behulp van die MT_ReadMemory
boodskap tipe. Die funksie readMemory is gedetailleerd, en voer die nodige stappe uit om 'n leesversoek te stuur en die antwoord te verkry:
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;
}
Die volledige bewys van konsep (POC) is beskikbaar hier.
Skryf Geheue
Net so kan geheue geskryf word met die writeMemory
funksie. Die proses behels om die boodskap tipe op MT_WriteMemory
te stel, die adres en lengte van die data te spesifiseer, en dan die data te stuur:
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;
}
Die geassosieerde POC is beskikbaar hier.
.NET Core Kode Uitvoering
Om kode uit te voer, moet 'n geheuegebied met rwx-toestemmings geïdentifiseer word, wat gedoen kan word met vmmap -pages:
vmmap -pages [pid]
vmmap -pages 35829 | grep "rwx/rwx"
'n Plek om 'n funksie-aanwyser te oorskryf, is nodig, en in .NET Core kan dit gedoen word deur die Dynamiese Funksietabel (DFT) te teiken. Hierdie tabel, wat in jithelpers.h
beskryf word, word deur die runtime gebruik vir JIT-kompilasie-hulpfunksies.
Vir x64-stelsels kan handtekeningjag gebruik word om 'n verwysing na die simbool _hlpDynamicFuncTable
in libcorclr.dll
te vind.
Die MT_GetDCB
debuggingsfunksie verskaf nuttige inligting, insluitend die adres van 'n hulpfunksie, m_helperRemoteStartAddr
, wat die ligging van libcorclr.dll
in die prosesgeheue aandui. Hierdie adres word dan gebruik om 'n soektog na die DFT te begin en 'n funksie-aanwyser met die shellcode se adres te oorskryf.
Die volledige POC-kode vir inspuiting in PowerShell is beskikbaar hier.
Verwysings
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.