forked from rpms/glibc
59 lines
1.7 KiB
C
59 lines
1.7 KiB
C
|
#include <unistd.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
int main(void) {
|
||
|
unsigned int *chunk;
|
||
|
int i;
|
||
|
unsigned int shellcode[10];
|
||
|
unsigned int ret_addr_2_change = 9;
|
||
|
|
||
|
/* Get some space */
|
||
|
chunk = malloc(0x8);
|
||
|
|
||
|
/* now setup the chunk to fool chunk_free()
|
||
|
By making prev_size negative it will look
|
||
|
_after_ this chunk in stead of in front of it
|
||
|
*/
|
||
|
chunk[0] = -0x10; /* prev_size */
|
||
|
chunk[1] = 0x8; /* size */
|
||
|
chunk[2] = shellcode; /* fd */
|
||
|
chunk[3] = shellcode; /* bk */
|
||
|
|
||
|
/* set fd to the adres of the return address - 3
|
||
|
the minus 3 is needed because fd[3] will become bk
|
||
|
bk will be set to point to our shellcode. Remember that
|
||
|
bk[2] will be changed to contain fd so that there should be
|
||
|
a jmp or so in the shellcode to skip that value.
|
||
|
*/
|
||
|
chunk[4+2] = (int) (&ret_addr_2_change - 3);
|
||
|
chunk[4+3] = (int) (shellcode);
|
||
|
|
||
|
/* set shellcode to 0 so that we can see the change */
|
||
|
memset(shellcode, 0, sizeof(shellcode));
|
||
|
|
||
|
i = ret_addr_2_change;
|
||
|
|
||
|
// printf("ret before call: %x\n", ret_addr_2_change);
|
||
|
// printf("address of ret: %x\n", &ret_addr_2_change);
|
||
|
// printf("address of shellcode: %x\n", shellcode);
|
||
|
/* remember we give mem to free which finds the chunk based on
|
||
|
that */
|
||
|
free(chunk+2);
|
||
|
|
||
|
// printf("ret now: %x\n", ret_addr_2_change);
|
||
|
|
||
|
if (ret_addr_2_change != i) {
|
||
|
printf("FAIL\n"); /* Exploit succeeded */
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
for (i = 0 ; i < 10; i++) {
|
||
|
if (shellcode[i] != 0) {
|
||
|
printf("FAIL\n"); /* Exploit succeeded */
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|