batmanpriv/PH-Poc
GitHub: batmanpriv/PH-Poc
一个最小化的C++实现的Windows Process Hollowing概念验证工具,用于学习和演示进程注入的底层原理。
Stars: 0 | Forks: 0
# 🧬 Process Hollowing - POC
使用 C++ 实现的 Windows **Process Hollowing**。
用恶意的 PE payload 替换合法进程的内存。
## 📌 概述
Process Hollowing 是一种用于以下操作的技术:
- 创建一个处于挂起状态的进程(例如 `notepad.exe`)
- 取消映射其原始内存
- 注入自定义的 PE payload
- 恢复执行以运行注入的代码
此 POC 是**最小化的**、**简洁的**且具有**教育意义的**。
## 📸 演示
### Process Hollowing 实操
### 工作原理
## ⚙️ 编译
### 使用 MinGW / GCC
```
g++ -o hollow.exe Process-Hollowing.cpp
```
### 带优化编译
```
g++ -O2 -s -o hollow.exe Process-Hollowing.cpp
```
## 🚀 用法
```
hollow.exe
```
### 示例
```
hollow.exe notepad.exe payload.exe
```
### 使用完整路径的示例
```
hollow.exe "C:\Windows\System32\calc.exe" "C:\payload.exe"
```
## 📁 示例 Payload (Go)
在 `example/` 文件夹中:
```
// msgbox.go
package main
import (
"syscall"
"unsafe"
)
func main() {
user32 := syscall.NewLazyDLL("user32.dll")
messageBox := user32.NewProc("MessageBoxW")
title, _ := syscall.UTF16PtrFromString("Hollow")
msg, _ := syscall.UTF16PtrFromString("🔥 Payload Executed Successfully!")
messageBox.Call(0, uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(title)), 0)
}
```
### 编译 Payload
```
go build -ldflags="-H=windowsgui -linkmode=internal -buildmode=pie" -o payload.exe example/msgbox.go
```
## 📊 工作原理
| 步骤 | 描述 |
|------|-------------|
| 1 | 以 `CREATE_SUSPENDED` 状态创建目标进程 |
| 2 | 将 payload PE 文件读取到内存中 |
| 3 | 验证 DOS 和 NT 头 |
| 4 | 从 PEB 获取目标进程的基地址 |
| 5 | 取消映射原始可执行文件(`NtUnmapViewOfSection`) |
| 6 | 在目标进程中分配新内存 |
| 7 | 写入 PE 头和各个区块 |
| 8 | 在线程上下文中设置入口点 |
| 9 | 恢复线程以执行 payload |
## 🧪 测试环境
| 操作系统 | 架构 |
|----|--------------|
| Windows 10 | x64 / x86 |
| Windows 11 | x64 / x86 |
| Windows 7 | x64 / x86 |
| Windows Server 2019 | x64 |
| Windows Server 2022 | x64 |
## ⚠️ 环境要求
| 要求 | 描述 |
|-------------|-------------|
| 架构 | 宿主进程和 payload 必须匹配(同为 x64 或同为 x86) |
| 权限 | 建议使用管理员权限 |
| Payload 格式 | 位置无关可执行文件 (PIE) |
| 编译器 | 使用 GCC / MinGW 构建 hollowing 工具 |
| 依赖项 | Windows SDK(包含在 MinGW 中) |
## ❓ 问答
| 问题 | 回答 |
|----------|--------|
| ❓ 为什么我的 payload 会以 `0xc0000142` 崩溃? | 架构不匹配(32 位与 64 位)、payload 未编译为 PIE,或者缺少 DLL 依赖项。 |
| ❓ 这适用于 DLL 吗? | 不适用。此 POC 专为 **仅限 EXE payload** 设计。 |
| ❓ 我可以使用任何 EXE 作为 payload 吗? | 可以,但必须编译为位置无关可执行文件 (PIE)。 |
| ❓ 为什么使用 `-buildmode=pie`? | 允许 payload 在任何基地址运行,而不仅限于其首选地址。 |
| ❓ 如果 VirtualAllocEx 在 targetBase 处失败怎么办? | 代码会自动使用 `NULL` 重试,让系统自行选择地址。 |
| ❓ 杀毒软件会检测到这个吗? | 大多数杀毒软件会检测到 process hollowing。这**仅供教育目的使用**。 |
| ❓ 我可以注入到受保护的进程中吗? | 不可以。需要管理员权限,并且不适用于受保护的进程。 |
| ❓ payload 可以使用哪些语言? | 任何可以编译为 PE 格式(Go, C, C++, Rust 等)且支持 PIE 的语言。 |
| ❓ 它适用于 GUI 应用程序吗? | 适用,前提是它们被编译为 PIE 并且具有 GUI 入口点。 |
| ❓ 支持的最低 Windows 版本是多少? | Windows 7 及更高版本。 |
| ❓ 需要管理员权限吗? | 建议使用,但对于用户模式进程并不总是必需的。 |
| ❓ 我可以从 32 位进程注入到 64 位吗? | 不可以,工具必须与目标架构匹配。 |
| ❓ 有日志文件吗? | 有,会在当前目录下创建 `hollow.log`。 |
| ❓ 如果 payload 太小怎么办? | 某些杀毒软件会检测到小型 payload。可以通过添加填充来增加大小。 |
| ❓ 它适用于 .NET 应用程序吗? | 适用,但 .NET payload 需要系统上有可用的 .NET runtime。 |
| ❓ 我可以将其用于恶意软件吗? | 本工具仅用于研究和教育。严禁滥用。 |
| ❓ 如何调试失败? | 检查日志文件、验证架构并确保使用 PIE 编译。 |
## 🛡️ 免责声明
本工具**仅供教育和研究目的使用**。
请仅在获得适当授权的环境中使用。
作者不对因使用此工具而造成的任何滥用或损害负责。
## 🔗 链接
| 链接 | 描述 |
|------|-------------|
| [GitHub 仓库](https://github.com/batmanpriv/PH-Poc) | 源代码和文档 |
| [Telegram](https://t.me/BatmanPriv) | 联系作者 |
| [IRED Team 文章](https://www.ired.team/offensive-security/code-injection-process-injection/process-hollowing-and-pe-image-relocation) | 技术说明 |
| [Microsoft PE 格式](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format) | 官方 PE 规范 |
## ✨ 功能
| 特性 | 状态 |
|---------|--------|
| 最小化代码(约 150 行) | ✅ |
| 彩色控制台输出 | ✅ |
| 架构检测(x64/x86) | ✅ |
| PE 验证(DOS + NT 头) | ✅ |
| 带有意义消息的错误处理 | ✅ |
| 自动回退分配 | ✅ |
| 按区块注入 PE | ✅ |
| 生成日志文件 | ✅ |
| 跨平台(仅限 Windows) | ✅ |
| 支持 PIE payload | ✅ |
## 📝 注意事项
- 日志文件将保存为当前目录下的 `hollow.log`
- 两个进程必须具有相同的架构(32 位或 64 位)
- 对于 Go payload,始终使用 `-buildmode=pie`
- 对于 C/C++ payload,在 GCC 中使用 `-pie` 标志
- 对于 Rust payload,使用 `-C relocation-model=pic`
- 对于 .NET payload,请确保有可用的 .NET runtime
- 请始终先在受控环境中进行测试
- 该工具适用于任何支持重定位的 PE 文件
## 🚀 快速开始
```
# Clone 该 repository
git clone https://github.com/batmanpriv/PH-Poc.git
cd PH-Poc
# Compile 该 hollowing 工具
g++ -o hollow.exe Process-Hollowing.cpp
# Build 该 example payload
cd example
go build -ldflags="-H=windowsgui -linkmode=internal -buildmode=pie" -o payload.exe msgbox.go
cd ..
# Execute
hollow.exe notepad.exe example/payload.exe
```
## 📊 技术深入解析
### PE 重定位
当 payload 被加载到与其首选地址不同的基地址时,必须应用重定位。PIE 允许这样做。
### PEB (Process Environment Block)
该工具读取 PEB 以查找宿主进程的当前基地址。
### NTAPI 与 WinAPI
使用 `NtUnmapViewOfSection` 而不是 `VirtualFreeEx` 可确保正确取消映射宿主镜像。
### 线程上下文
修改线程上下文以指向新的入口点,从而允许 payload 执行。
## ⚡ 性能
| 指标 | 数值 |
|--------|-------|
| 工具大小 | ~50 KB(优化后) |
| 注入速度 | < 1 秒 |
| 内存使用 | ~5 MB |
| CPU 使用率 | 极低 |
## 🛠️ 故障排除
| 问题 | 解决方案 |
|---------|----------|
| 编译失败 | 确保已安装 MinGW 并将其添加到 PATH 中 |
| Payload 无法运行 | 检查架构是否不匹配 |
| 错误 0xc0000142 | 使用 PIE 编译 payload |
| 拒绝访问 | 以管理员身份运行 |
| 进程崩溃 | 验证 PE 的完整性 |
| 没有弹出消息框 | 检查 payload 的编译情况 |
| 被杀毒软件拦截 | 添加到排除项(仅用于测试) |
**献给安全研究社区 ❤️**
### 工作原理
## ⚙️ 编译
### 使用 MinGW / GCC
```
g++ -o hollow.exe Process-Hollowing.cpp
```
### 带优化编译
```
g++ -O2 -s -o hollow.exe Process-Hollowing.cpp
```
## 🚀 用法
```
hollow.exe 标签:C++, Gophish, SSH蜜罐, 免杀技术, 数据擦除, 暴力破解检测, 端点可见性, 进程注入, 进程镂空