# macOS .Net 应用程序注入
{{#include ../../../banners/hacktricks-training.md}}
**这是帖子 [https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/](https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/) 的摘要。请查看以获取更多详细信息!**
## .NET Core 调试
### **建立调试会话**
在 .NET 中,调试器与被调试程序之间的通信处理由 [**dbgtransportsession.cpp**](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/shared/dbgtransportsession.cpp) 管理。该组件为每个 .NET 进程设置两个命名管道,如 [dbgtransportsession.cpp#L127](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/shared/dbgtransportsession.cpp#L127) 所示,这些管道通过 [twowaypipe.cpp#L27](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/debug-pal/unix/twowaypipe.cpp#L27) 初始化。这些管道的后缀为 **`-in`** 和 **`-out`**。
通过访问用户的 **`$TMPDIR`**,可以找到可用于调试 .Net 应用程序的调试 FIFO。
[**DbgTransportSession::TransportWorker**](https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/coreclr/debug/shared/dbgtransportsession.cpp#L1259) 负责管理来自调试器的通信。要启动新的调试会话,调试器必须通过 `out` 管道发送一条以 `MessageHeader` 结构开头的消息,该结构在 .NET 源代码中详细说明:
```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];
}
```
要请求一个新会话,结构体如下填充,将消息类型设置为 `MT_SessionRequest`,并将协议版本设置为当前版本:
```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);
```
该标题随后通过 `write` 系统调用发送到目标,后面是包含会话 GUID 的 `sessionRequestData` 结构:
```c
write(wr, &sSendHeader, sizeof(MessageHeader));
memset(&sDataBlock.m_sSessionID, 9, sizeof(SessionRequestData));
write(wr, &sDataBlock, sizeof(SessionRequestData));
```
对`out`管道的读取操作确认调试会话建立的成功或失败:
```c
read(rd, &sReceiveHeader, sizeof(MessageHeader));
```
## 读取内存
一旦建立了调试会话,就可以使用 [`MT_ReadMemory`](https://github.com/dotnet/runtime/blob/f3a45a91441cf938765bafc795cbf4885cad8800/src/coreclr/src/debug/shared/dbgtransportsession.cpp#L1896) 消息类型读取内存。函数 readMemory 进行了详细说明,执行发送读取请求和检索响应所需的步骤:
```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;
}
```
完整的概念验证(POC)可在 [这里](https://gist.github.com/xpn/95eefc14918998853f6e0ab48d9f7b0b) 获取。
## 写入内存
类似地,可以使用 `writeMemory` 函数写入内存。该过程涉及将消息类型设置为 `MT_WriteMemory`,指定数据的地址和长度,然后发送数据:
```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;
}
```
相关的POC可以在[这里](https://gist.github.com/xpn/7c3040a7398808747e158a25745380a5)找到。
## .NET Core代码执行
要执行代码,需要识别一个具有rwx权限的内存区域,这可以通过使用vmmap -pages:来完成。
```bash
vmmap -pages [pid]
vmmap -pages 35829 | grep "rwx/rwx"
```
定位一个覆盖函数指针的位置是必要的,在 .NET Core 中,可以通过针对 **Dynamic Function Table (DFT)** 来实现。这个表在 [`jithelpers.h`](https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/coreclr/src/inc/jithelpers.h) 中详细描述,是运行时用于 JIT 编译辅助函数的。
对于 x64 系统,可以使用签名搜索来找到 `libcorclr.dll` 中符号 `_hlpDynamicFuncTable` 的引用。
`MT_GetDCB` 调试器函数提供了有用的信息,包括一个辅助函数的地址 `m_helperRemoteStartAddr`,指示 `libcorclr.dll` 在进程内存中的位置。然后使用这个地址开始搜索 DFT,并用 shellcode 的地址覆盖一个函数指针。
注入 PowerShell 的完整 POC 代码可以在 [这里](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}}