中秋放假打了下长城杯,干了两pwn,战绩不错,后面复现了企业组的pwn3,写个博客记录下。
K1ng_in_h3Ap_I
题目分析
菜单题目,没有show功能,漏洞还是挺多的,uaf和offbyone随便一个都够打,有leak3字节的地址就省去爆破倒数第四位的功夫了,打stdout来泄露地址,改malloc hook为one_gadget来拿shell。可以参考这位师傅的博客:https://bbs.pediy.com/thread-267632.htm
思路
通过风水布置堆块使得bin里的结构达到这个效果
此时可以利用题目给的偏移计算stdout地址,部分修改fd指针,将堆块申请到附近。
然后将缓冲区base地址指针改小就可以泄露指针范围的地址
改完以后是这个样子
然后就会输出该指针范围内的东西,最后面调用的就是_IO_new_do_write
得到地址就可以打malloc,然后用realloc调偏移
IO FILE系列的相关知识可以看看这位大佬的博客:https://ray-cp.github.io/archivers/IO_FILE_fopen_analysis
exp
1 | #coding=utf-8 |
K1ng_in_h3Ap_II
题目分析
菜单题功能很全但是malloc的chunk限制了大小,free后指针没有清空,存在uaf漏洞。开了沙盒保护。
思路
确实思路挺简单的,通过攻击 tcache_perthread_struct可以看到它的结构挺简单的,一个字符数组(tcachebins的计数器)和一个指针数组(最近一次释放的堆指针),然后就是堆初始化的时候申请的第一个chunk就是它。
1 | typedef struct tcache_perthread_struct |
通过uaf将该chunk申请出来
然后将结构体里的counts数组都填充成\x07
,也就是tcachebins存放chunk的最大范围,这样我们释放tcache_perthread_struct然,就可以得到地址了。
然后控制这个结构体就可以达到任意地址写。
然后劫持free hook为setcontext+53。
在释放的堆块里布置对应的寄存器。这样就可以通过rdi(也就是我们释放的堆块)来控制寄存器。然后就orw拿到flag
exp
1 | #coding=utf-8 |
~XLVXR5H9H6%5BQ%7DNON.png “”)
hellopwn(企业组)
题目分析
题目情况大概就是这样了,没有打印功能,限制了编辑和释放堆块的次数,chunk的大小范围控制在了large bin范围内。在释放堆块的时候,指针未清空,存在uaf漏洞。
思路
先通过magic打stdout泄露地址,和之前的方法一样,把缓冲区base地址的指针改小就可以了,然后就是通过large bin attack来完成后续的操作,下面讲一下。参考师傅的博客:https://www.anquanke.com/post/id/222948?display=mobile
在glibc2.31版本里常规的large bin attack被封杀了,但是large bin attack还有另一个分支可以利用
可以看到在glibc2.32版本里加了一个链表完整性的检测,但是他封杀的只是其中一个分支,还有一个分支可以利用,可以达到任意地址写一个我们可控的堆块地址。
通过控制large bin里的bk_nextsize来达到任意地址读写,再申请比unsorted bin还大的chunk来触发漏洞(unsorted bin里chunk的size要小于large bin里的size)
大概堆块布局的这样的
通过uaf控制large bin里的chunk,改写large bin里的chunk的bk_nextsize,来达到任意地址写一个堆块地址。
再申请一个大堆块触发漏洞
我们来看一下tcache部分的源码
1 | #if USE_TCACHE |
然后我们的目的就是将覆写mp_.tcache_bins的值为一个很大的地址,使得large bin大小范围的chunk被释放也会放到tcache bin里,后面就简单了,因为申请tcache bin的chunk不会检测size是否合法,所以我们就可以利用uaf达到任意地址写的效果。
exp
1 | #!/usr/bin/env python3 |