glibc/tests/Regression/double_free_exploit/exploit.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;
}