命名管道与进程令牌窃取
字数 1318 2025-08-06 12:20:48
命名管道与进程令牌窃取技术详解
命名管道提权技术
命名管道基础概念
命名管道(Named Pipe)是Windows系统中用于进程间通信(IPC)的一种机制,它允许不同进程(甚至不同计算机上的进程)进行数据交换。
关键特性:
- 命名管道有唯一名称,遵循格式:
\\.\pipe\pipe\pipename - 支持单向或双向通信
- 可用于网络通信(不同于匿名管道)
- 由管道服务器创建,管道客户端连接
命名管道服务器与客户端实现
管道服务器实现步骤
- 使用
CreateNamedPipe函数创建管道实例 - 使用
ConnectNamedPipe等待客户端连接 - 使用
ReadFile接收客户端数据
#include <windows.h>
#include <iostream>
int main() {
// 1. 创建命名管道
HANDLE lCreatePipe = CreateNamedPipe(
"\\\\.\\pipe\\pipe\\testname",
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE,
1, 2048, 2048, 0, NULL);
if (lCreatePipe == INVALID_HANDLE_VALUE) {
std::cout << "CreateNamedPipeA Error" << std::endl;
return 1;
}
std::cout << "CreateNamedPipeA Success" << std::endl;
// 2. 等待客户端连接
BOOL ConnectSuccess = ConnectNamedPipe(lCreatePipe, NULL);
if (ConnectSuccess == 0) {
std::cout << "ConnectNamedPipe Error" << std::endl;
return 1;
}
std::cout << "客户端成功连接到服务器" << std::endl;
// 3. 接收数据
char buf[2048];
BOOL Read = ReadFile(lCreatePipe, buf, 2048, NULL, NULL);
if (Read) {
std::cout << "Success receive:" << buf << std::endl;
}
return 0;
}
管道客户端实现步骤
- 使用
CreateFile连接到服务端 - 使用
WriteFile向服务端发送数据
#include <windows.h>
#include <iostream>
int main() {
// 1. 连接到命名管道服务器
HANDLE ConectionTo = CreateFile(
"\\\\.\\pipe\\pipe\\testname",
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (ConectionTo == INVALID_HANDLE_VALUE) {
std::cout << "CreateFileA Error:" << GetLastError() << std::endl;
return 1;
}
std::cout << "成功连接到服务端" << std::endl;
// 2. 发送数据
char message[] = "This is a test";
DWORD messageLenght = lstrlen(message) * 2;
BOOL Write = WriteFile(ConectionTo, message, messageLenght, NULL, NULL);
if (Write == 0) {
std::cout << "WriteFile Error" << std::endl;
return 1;
}
std::cout << "WriteFile to server success" << std::endl;
}
模拟命名管道客户端提权
核心原理:当命名管道服务器调用ImpersonateNamedPipeClient函数时,系统会根据客户端权限授予服务端相同权限。
提权条件(满足其一即可):
- 客户端通过RPC连接到服务器
- 服务器拥有
SeImpersonatePrivilege特权(管理员进程默认开启)
提权步骤:
- 创建命名管道服务器
- 使用
ImpersonateNamedPipeClient模拟客户端权限 - 使用
OpenThreadToken打开服务端线程令牌 - (可选)使用
DuplicateTokenEx复制线程令牌 - 使用
CreateProcessWithTokenW创建具有新令牌的进程
关键API:
OpenThreadToken:打开线程令牌DuplicateTokenEx:复制令牌CreateProcessWithTokenW:使用指定令牌创建进程(需要SE_IMPERSONATE_NAME特权)
进程令牌窃取技术
访问令牌基础
访问令牌包含以下安全信息:
- 用户账户的SID(安全标识符)
- 用户所属组的SID
- 登录会话的登录SID
- 用户或用户组持有的特权列表
- 所有者SID
- 主组SID
- 默认DACL(自主访问控制列表)
- 令牌类型(主要令牌或模拟令牌)
- 限制SID的可选列表
- 当前模拟级别
- 其他统计信息
令牌窃取实现步骤
- 使用
OpenProcess打开目标进程,获取句柄 - 使用
OpenProcessToken打开与进程关联的访问令牌 - 使用
DuplicateTokenEx复制令牌 - 使用
CreateProcessWithTokenW用新令牌创建进程
示例场景:从administrator账户窃取system进程(如winlogon.exe)的令牌,打开system权限的cmd窗口。
防御措施
- 限制
SeImpersonatePrivilege特权的分配 - 监控命名管道的创建和使用
- 实施最小权限原则
- 监控令牌复制和进程创建行为
- 定期审计特权账户活动
实际应用
- Metasploit的
getsystem命令利用了命名管道模拟技术 - 在内网渗透中常用于权限提升
- 红队评估中测试系统防御能力
注意:本文所述技术仅用于安全研究和防御目的,未经授权使用这些技术可能违反法律。