hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-.net-applications-injection.md

9.5 KiB
Raw Blame History

macOS .Net Applications Injection

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Це резюме поста https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/. Перевірте його для отримання додаткових деталей!

.NET Core Debugging

Establishing a Debugging Session

Обробка зв'язку між налагоджувачем і налагоджуваним у .NET управляється dbgtransportsession.cpp. Цей компонент налаштовує два іменовані канали для кожного процесу .NET, як видно в dbgtransportsession.cpp#L127, які ініціюються через twowaypipe.cpp#L27. Ці канали мають суфікси -in та -out.

Відвідавши $TMPDIR користувача, можна знайти FIFOs для налагодження .Net додатків.

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, за яким слідує структура 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));

Читання пам'яті

Once a debugging session is established, memory can be read using the MT_ReadMemory message type. Функція 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 це можна зробити, націлившись на Dynamic Function Table (DFT). Ця таблиця, детально описана в jithelpers.h, використовується середовищем виконання для допоміжних функцій компіляції JIT.

Для систем x64 можна використовувати полювання на сигнатури, щоб знайти посилання на символ _hlpDynamicFuncTable у libcorclr.dll.

Функція налагодження MT_GetDCB надає корисну інформацію, включаючи адресу допоміжної функції m_helperRemoteStartAddr, що вказує на місцезнаходження libcorclr.dll у пам'яті процесу. Ця адреса потім використовується для початку пошуку DFT і перезапису вказівника функції адресою shellcode.

Повний код POC для ін'єкції в PowerShell доступний тут.

References

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}