匿名管道实现远程CMD命令执行后门

​ 管道分为匿名管道和命名管道。匿名管道只能在父子进程间进行通信,不能在网络间通信,而且数据 传输是单向的,只能一端写,另一端读。命名管道可以在任意进程间通信,通信是双向的,任意一端都可 读可写,但是在同一时间只能有一端读、一端写

下面代码实现执行CMD并通过匿名管道的方法获取执行结果,以实现远程CMD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<Windows.h>
#include<stdio.h>
BOOL PipeCmd(char *szCmd,char *szResultBuffer,DWORD dwResultBufferSize);
int main()
{
char szCmd[] = "ping yeanhoo.com";
char szResultBuffer[0x10000]={0};
DWORD dwResultBufferSize = 0x10000;
PipeCmd(szCmd,szResultBuffer,dwResultBufferSize);
printf("CMD执行结果:\n%s\n",szResultBuffer);
getchar();


return 0;

}

BOOL PipeCmd(char *szCmd,char *szResultBuffer,DWORD dwResultBufferSize)
{
HANDLE hReadPipe = NULL;
HANDLE hWritePipe = NULL;
SECURITY_ATTRIBUTES securityAttributes = {0};
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};

//设定管道安全属性
securityAttributes.bInheritHandle = TRUE;
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;

//创建匿名管道
if(!CreatePipe(&hReadPipe,&hWritePipe,&securityAttributes,0))
{
return FALSE;
}
//设置新进程参数
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;//将匿名管道写入句柄赋值给新进程控制台窗口的缓存句柄

//创建管道写端新进程CMD执行命令,将执行结果写入到匿名管道
if(!CreateProcess(NULL,szCmd,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
{
return FALSE;
}
//等待执行结束
WaitForSingleObject(pi.hThread,INFINITE);
WaitForSingleObject(pi.hProcess,INFINITE);

//从管道另一端读取结果
RtlZeroMemory(szResultBuffer,dwResultBufferSize);
DWORD oBytes=0;
ReadFile(hReadPipe,szResultBuffer,dwResultBufferSize,&oBytes,NULL);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
return TRUE;
}