macOS .Net Applications Injection

Support HackTricks

рдпрд╣ https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/ рдкреЛрд╕реНрдЯ рдХрд╛ рд╕рд╛рд░рд╛рдВрд╢ рд╣реИред рдЖрдЧреЗ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рджреЗрдЦреЗрдВ!

.NET Core Debugging

рдбрд┐рдмрдЧрд┐рдВрдЧ рд╕рддреНрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛

.NET рдореЗрдВ рдбрд┐рдмрдЧрд░ рдФрд░ рдбрд┐рдмрдЧреА рдХреЗ рдмреАрдЪ рд╕рдВрдЪрд╛рд░ рдХрд╛ рдкреНрд░рдмрдВрдзрди dbgtransportsession.cpp рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдШрдЯрдХ рдкреНрд░рддреНрдпреЗрдХ .NET рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рджреЛ рдирд╛рдорд┐рдд рдкрд╛рдЗрдк рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ dbgtransportsession.cpp#L127 рдореЗрдВ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ twowaypipe.cpp#L27 рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрд░рдВрдн рд╣реЛрддреЗ рд╣реИрдВред рдЗрди рдкрд╛рдЗрдкреЛрдВ рдХреЗ рдЕрдВрдд рдореЗрдВ -in рдФрд░ -out рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ $TMPDIR рдкрд░ рдЬрд╛рдХрд░, .Net рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдбрд┐рдмрдЧрд┐рдВрдЧ FIFOs рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

DbgTransportSession::TransportWorker рд╕рдВрдЪрд╛рд░ рдкреНрд░рдмрдВрдзрди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдПрдХ рдирдпрд╛ рдбрд┐рдмрдЧрд┐рдВрдЧ рд╕рддреНрд░ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдбрд┐рдмрдЧрд░ рдХреЛ out рдкрд╛рдЗрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ MessageHeader рд╕рдВрд░рдЪрдирд╛ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ .NET рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рд╣реИ:

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

рдирдП рд╕рддреНрд░ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рднрд░рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕рдВрджреЗрд╢ рдкреНрд░рдХрд╛рд░ рдХреЛ MT_SessionRequest рдФрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

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

рдпрд╣ рд╣реЗрдбрд░ рдлрд┐рд░ write syscall рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рдХреНрд╖реНрдп рдкрд░ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рдж sessionRequestData рд╕рдВрд░рдЪрдирд╛ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕рддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ GUID рд╣реЛрддрд╛ рд╣реИ:

write(wr, &sSendHeader, sizeof(MessageHeader));
memset(&sDataBlock.m_sSessionID, 9, sizeof(SessionRequestData));
write(wr, &sDataBlock, sizeof(SessionRequestData));

out рдкрд╛рдЗрдк рдкрд░ рдПрдХ рдкрдврд╝рдиреЗ рдХрд╛ рдСрдкрд░реЗрд╢рди рдбрд┐рдмрдЧрд┐рдВрдЧ рд╕рддреНрд░ рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХреА рд╕рдлрд▓рддрд╛ рдпрд╛ рд╡рд┐рдлрд▓рддрд╛ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реИ:

read(rd, &sReceiveHeader, sizeof(MessageHeader));

рдореЗрдореЛрд░реА рдкрдврд╝рдирд╛

рдПрдХ рдбрд┐рдмрдЧрд┐рдВрдЧ рд╕рддреНрд░ рд╕реНрдерд╛рдкрд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдореЗрдореЛрд░реА рдХреЛ MT_ReadMemory рд╕рдВрджреЗрд╢ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдлрд╝рдВрдХреНрд╢рди readMemory рд╡рд┐рд╕реНрддреГрдд рд╣реИ, рдкрдврд╝рдиреЗ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЛ рднреЗрдЬрдиреЗ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХрджрдо рдЙрдард╛рддрд╛ рд╣реИ:

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

рдкреВрд░реНрдг рдкреНрд░рдорд╛рдг рдЕрд╡рдзрд╛рд░рдгрд╛ (POC) рдпрд╣рд╛рдБ рдЙрдкрд▓рдмреНрдз рд╣реИред

рдореЗрдореЛрд░реА рд▓рд┐рдЦрдирд╛

рдЗрд╕реА рддрд░рд╣, writeMemory рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореЗрдореЛрд░реА рд▓рд┐рдЦреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рдВрджреЗрд╢ рдкреНрд░рдХрд╛рд░ рдХреЛ MT_WriteMemory рдкрд░ рд╕реЗрдЯ рдХрд░рдирд╛, рдбреЗрдЯрд╛ рдХрд╛ рдкрддрд╛ рдФрд░ рд▓рдВрдмрд╛рдИ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛, рдФрд░ рдлрд┐рд░ рдбреЗрдЯрд╛ рднреЗрдЬрдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ:

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

рд╕рдВрдмрдВрдзрд┐рдд POC рдпрд╣рд╛рдБ рдЙрдкрд▓рдмреНрдз рд╣реИред

.NET Core рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди

рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреЛ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреА рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ rwx рдЕрдиреБрдорддрд┐рдпрд╛рдБ рд╣реЛрддреА рд╣реИрдВ, рдЬрд┐рд╕реЗ vmmap -pages: рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

vmmap -pages [pid]
vmmap -pages 35829 | grep "rwx/rwx"

рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рди рдвреВрдВрдврдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░ .NET Core рдореЗрдВ, рдпрд╣ рдбрд╛рдпрдирд╛рдорд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдЯреЗрдмрд▓ (DFT) рдХреЛ рд▓рдХреНрд╖рд┐рдд рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рддрд╛рд▓рд┐рдХрд╛, рдЬреЛ jithelpers.h рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рд╣реИ, рд░рдирдЯрд╛рдЗрдо рджреНрд╡рд╛рд░рд╛ JIT рд╕рдВрдХрд▓рди рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИред

x64 рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП, рд╕рд┐рдЧреНрдиреЗрдЪрд░ рд╣рдВрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ libcorclr.dll рдореЗрдВ рдкреНрд░рддреАрдХ _hlpDynamicFuncTable рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

MT_GetDCB рдбрд┐рдмрдЧрд░ рдлрд╝рдВрдХреНрд╢рди рдЙрдкрдпреЛрдЧреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛, m_helperRemoteStartAddr, рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдореЛрд░реА рдореЗрдВ libcorclr.dll рдХреЗ рд╕реНрдерд╛рди рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкрддреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ DFT рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рд╢реБрд░реВ рдХрд░рдиреЗ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдХреЛ рд╢реЗрд▓рдХреЛрдб рдХреЗ рдкрддреЗ рдХреЗ рд╕рд╛рде рдУрд╡рд░рд░рд╛рдЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

PowerShell рдореЗрдВ рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкреВрд░рд╛ POC рдХреЛрдб рдпрд╣рд╛рдБ рдЙрдкрд▓рдмреНрдз рд╣реИред

рд╕рдВрджрд░реНрдн

Support HackTricks

Last updated