easy_pwn
1 | // off-by-one |
write 函数中只要输入的size 减去原先的 = 10就能多写一个字节,因为堆块的申请是用calloc所以不能直接free一个unsortbin再申请出来的方式漏泄地址;申请三个堆块chunk0,chunk1,chunk2覆写chunk1的size为chunk1.size+chunk2.size,free(1),这样chunk2就被放到unsortbin中去了,再申请chunk1.size大小的堆块就能把main_arena写到chunk2去,再show。接着就malloc_hook填onegadget
exp:
1 | #coding:utf-8 |
easy_heap
程序开始会有两个输入,username,inof,都是存放到bss段的
4个功能
1 | 1、add 通过malloc申请一个堆块放到全局变量buf中去,大小限制为(<0x80),且该变量只能存放一个堆指针 |
思路:
只要能用show,这题基本就算是解决了,那现在要解决的是如何修改qword_602090
的值为0xDEADBEEFDEADBEEFLL
,我的做法的构造double free
先calloc(0xa0,1)
再free(ptr)
这时ptr中就放着top chunk,再mallloc(0x60)
两次就能使ptr,buf两个指针放着现个大小相同的堆,接下来就可以实现double free了。将username作为fack chunk申请出来修改qword_602090
,之后将malloc_hook填为onegadget即可
但是这里有个坑导致我在赛中没能做出来,就是4个onegadget都用不了,利用realloc调偏移也无济于事。也是在赛后师兄提醒下才知道的,可以连续free一个堆块两次来解发malloc_hook,这样做的好处就是在调用malloc_hook前会先调用malloc_printer,所以会改变堆的结构,再利用realloc调偏移就有更大的可能满足onegadget的条件了。
这里有个问题我没法解释的,希望如果有大佬明白的话还请不吝赐教,如下图:明明在show函数中已经把标准输出及错误输出关闭了,那为什么在getshell后ls能打印出东西呢?
exp:
1 | #coding:utf-8 |
realloc_magic
程序64位保护全开,功能有3个
1 | 1、realloc(size) |
思路:程序没有show函数,所以要泄露地址应该攻击IO_file,环境是ubuntu18,所以有tcache
因为程序开启了PIE,所以得想办法让tcache链上main_arena而且能够修改fd然后申请出来:
1 | realloc(0x78,'a') |
直接将_IO_2_1_stdout_
申请出来,泄露完地址后修改free_hook
为onegadget
,建议先关闭ASLR做
exp:
1 | #coding:utf-8 |
参考题目:https://xz.aliyun.com/t/6259#toc-0
easy_rop
保护:
1 | Arch: amd64-64-little |
没有开canary ,而且程序存在很明显的栈溢出
1 | while ( !feof(stdin) ) |
这里可以无限输入直到遇到’\n’,相当于gets,但是需要注意一下下标,各个变量在栈中的布局是这样的
1 | -0000000000000424 var_424 dd ? |
所以不能直接0x428个垃圾字符填过去,修改下标v10到ret即可
还有一点,程序禁用了execve,所以要用orw来读取flag,用rop实现和写shellcode都行
exp:
1 | #coding:utf-8 |