题目分析
例行安全检查
没有PIE,方面调试
partial relro意味着这题应该直接改GOT表就能做
菜单:
没有show功能,可以考虑吧某个函数(比如free的GOT)改为puts@plt
可以申请17个chunk,编号为0-16
每次分配结束后会显示分配内存的低12bits
而本题中还有一个特殊的地方,就是content数组(0x6020e0)里面放的地址是按照顺序放入的,而不是编号为i的就放在content[i],所以地址的最低4个字节就用来存放编号了
在删除或者编辑的时候,就会依次遍历每个地址,对比index
漏洞分析
如上所说,本题地址存放比较特别,但是如果index为16,并且原地址第五位为0,就会导致地址被修改
而我们第一次申请时候地址最低12bits一般为0x260,即0010 0110 0000,和16即0001 0000或,就变成了0010 0111 0000即为0x270,我们就可以在chunk0的content中伪造一个chunk头部,把它释放之后再申请我们就能利用它控制下一个chunk了
漏洞利用
- 添加一个note[0],编号为16,size为0x10,内容为p64(0)+p64(0x91),再添加一个note[1],编号为1,size为0xc0(这个大小正好可以包括住content和size数组)
- 释放note[0]和note[1],重新申请一个0x80大小的note[2],把note[1]头部size改为0x21,fd改为content数组0x6020e0
- 申请一个0xc0大小的note[3],再申请同样大小的note[4],填入free_got, puts_got+1和atoi_got-4,大小全部设为0x10
- 先把free_got改为puts@plt(edit 8——free@got&0xf=8,atoi@got&0xf=8,所以需要减4),然后delete(1)泄露puts地址
- edit 4把system地址写入,然后发送/bin/sh\x00即可
Exp
from pwn import *
r = remote("node3.buuoj.cn", 27223)
#r = process("./ciscn_2019_final_5/ciscn_2019_final_5")
context.log_level = 'debug'
DEBUG = 0