比赛做了四个pwn,差个c++
8-bit adventure
个人比较喜欢的一个题,觉得挺有意思的
只允许输入一个字节的指令(int 0x80)除外,中间用nop隔开了,同时还开了沙箱
既然这样的话,我们就需要利用单个字节的指令完成整个orw链
很明显,read和write的第一个参数和第三个都比较小,都可以通过inc和dec来直接计算出来
而第二个参数也不难,只需要一个任意可以读写的地址即可,如果寄存器里有的话就直接用,没有就栈上pop
难点在于”/flag\x00”的构造
很明显,使用inc和dec来计算出来并不实际,但是计算逐个字节的数据是可以的
那么如何逐个字节地写入某一地址呢?
这里我用的是movsb指令,它的作用就是把esi指向处的一个字节移入edi指向处,同时esi和edi的指针+1
只需要将栈上的某个栈地址pop进esi,在寄存器中逐个字节计算”/flag\x00”,push进栈(刚好是esi地址指向处),然后movsb,即可在edi指向处构造出”/flag\x00”的字符串
exp:
1 | from pwn import * |
strange_heap
问就是非预期,自动忽略check函数
由于程序基地址可知,申请到bss段修改show_edit_times_a和show_edit_times_b,使得次数不限
同时写chunks数组,与上面配合起来实现任意地址读写
泄露offset后读出bss段上的flag即可(一次只能输出0x20字节,需要泄露两次)
exp:
1 | from pwn import * |
strange_heap revenge
尴尬了,心疼出题人一秒,我还是非预期hhh
虽然这次出题人不再将flag放在bss段(运行了一下远端的bss段上好像还有是怎么回事),但接上述方法,这次要连着create_times一起控制,实现更多数据的写入
然后还是任意读写
泄露libc,然后泄露栈地址,再申请到栈上执行orw
exp:
1 | from pwn import * |
super32
很开心拿了这题的一血和唯一一个解,这题需要花点时间逆向,漏洞点如下:
mrctf!貌似本来是填充在加密字符后用的吧,这里解密的时候可以控制输入的话,就可以实现堆溢出了
实现溢出,造成堆块重叠,切割unsorted bin控制tcache指针
这题的加密解密等为实操增加了难度,到最后实现起来那一步的时候条件有点苛刻了,好嘛,那就不写system了,直接one_gadget写到free_hook就完事
(脚本里是写到malloc_hook,不过都是ok的)
exp:
1 | from pwn import * |