#include #include #include #include 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] = (int) shellcode; /* fd */ chunk[3] = (int) 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; }