CTFshow 刷题记录 162-...持续更新
Last Update:
Page View: loading...
ctfshow-pwn-166
一道简单的double free
直接贴exp了
1 | |
ctfshow-pwn-165
堆利用里面放一个栈题也是没话说
先checksec一下吧
1 | |
没啥保护,看看ida
1 | |
edit:
1 | |
乍一看以为没有溢出,但是这个是_isoc99_scanf()函数,当我们读取字符串时,会在末尾自动添加 \0
这就造成了一个off_by_null
那有这个能干啥呢,调试看看
运行到edit输入部分
1 | |
我们先看看此时stack
1 | |
我们的offbynull就可以修改rbp的末位字节为00
还记得我们第一次输入菜单的时候
1 | |
这里为啥还要定义一个v5,看看汇编
1 | |
这里的一参是用rbp寻址的,那么我们就可以通过off by null修改这一值为%256s来打ret2csu来泄露libc,后面直接相同步骤getshell了
(为什么不打ret2libc,因为puts_plt表里的值为400A00会被__isoc99_scanf截断,ret2csu我们是只需要got的)
先贴一下exp:
1 | |
修改v5 = %256s
1 | |
1 | |
至于p2的偏移为什么是0x64,请看下文
这是调试到我们修改完v5 = %256s之后,rsp指向的返回地址为0x400f73,记住这rsp 0x7fffffffdf50

继续执行到下一次读入选项

此时我们读入的地址为0x7fffffffdeec,刚好0x7fffffffdf50-0x7fffffffdeec = 0x64
si进去调到最后,可以看见此时的返回地址也是0x7fffffffdf50,所以偏移就是0x64
1 | |
后面的话就是正常的ret2csu了就不讲了
最后在贴一下exp
1 | |
ctfshow-pwn-164
这是一道2.27的堆题
main:
1 | |
add():
1 | |
delete():
1 | |
transform:
1 | |
掌握的信息:
delete函数中存在uaf的,
libc为2.27最初的一版,可以直接double free,
程序用realloc来申请chunk的。
transform可以把ptr=0,但是只有一次机会
这里先提一下realloc的特性:
- 当
ptr == nullptr的时候,相当于malloc(size), 返回分配到的地址- 当
ptr != nullptr && size == 0的时候,相当于free(ptr),返回空指针- 当
size小于原来ptr所指向的内存的大小时,直接缩小,返回ptr指针。被削减的那块内存会被释放,放入对应的bins中去- 当
size大于原来ptr所指向的内存的大小时,如果原ptr所指向的chunk后面又足够的空间,那么直接在后面扩容,返回ptr指针;如果后面空间不足,先释放ptr所申请的内存,然后试图分配size大小的内存,返回分配后的指针
根据realloc的特性我们可以将ptr=0,达到申请多个chunk的目的,还可以进行溢出
思路:
- 先申请三个不同大小的chunk,chunk2为符合unsortedbin大小的chunk(我们得获取main_arena将其修改为IO_stdout),然后释放7次chunk2,填满tcachebins,然后释放将chunk2挂进unsortedbin中,使其与tcachebin重合
- 然后申请回chunk1,将ptr->chunk1,这时扩展chunk1使其可以溢出到chunk2修改其fd指针为IO_stdout(后三位字节是不变的,运行exp得多试)将其挂进bins,随后将ptr清零,打tcachebins dup,修改stdout的flag和write_base泄露出libc
- 与上面一样的方法打_free_hook->one_gadget
在exp中有更详细的注释
exp:
1 | |
参考链接:roarctf_2019_realloc_magic - LynneHuan - 博客园
ctfshow-pwn-163
1 | |
ctfshow-pwn-162
exp:
1 | |