希望能够趁着放假时间多做一点题,下学期可能做项目就真的没时间了。题目量挺多,然后有几道题找不到文件了。
VM_PWN
程序分析
这道题应该算是十分纯正的vm_pwn了。
1 | init_0(); |
首先含有regs含有5个寄存器,分别是:rdi, rsi, rdx 和 rsp 、 rip。
然后后续的各种操作,我们只分析其中典型的操作:
1 | case 0x20: // rdi=rsp |
这个操作已经十分完整了。而且程序会运行自己的一些指令,这里从 vidar
的wp学到了直接将字节码转换为指令的脚本,以后如果有类似题目应该可以直接用了:
1 |
|
我们可以得到程序的处理逻辑,我们可以发现三处可疑点:
1 | 0x2a0: 0x44 push reg0 |
1 | 0x320: 0x10 mov reg0, rsp |
1 | 0x39c: 0x8f syscall write |
程序总共有两次读取,这两次读取的size
都非常大。而最后 ret
时会先将 rsp
增加 0x100
,此时 rsp
是一个堆地址,然后将 rsp
的值赋给 rip
,然后此时由于 rip
为 0xff
所以会执行 ret
。
那么,我们可以通过第一次 read,连接到 该堆地址处,再通过write
将其输出,得到 我们输入数据存储的堆地址。
通过第二次read
,覆盖该堆地址 为我们的输入地址。那么程序执行 ret
时就会进入我们的输入数据中,去执行我们自己的逻辑。
利用分析
上面已经讲了如何控制程序执行流。
还有几个关键点,程序开启了沙箱,只能执行 orw
。由于不自带 open
,所以我们需要先泄露 libc
地址。
这里可以先 free
一个大的chunk
,再输出该地址。
为了执行 open
,我们需要覆盖程序可执行的4个函数中的 free
,所以我们需要得到程序的基址。这里我采用先通过 environment
泄露出栈地址,再通过栈地址,泄露出程序的运行地址,最后得到 free
的地址,将其覆盖为 open
。
最后就是常规的 orw
。
EXP
1 | from pwn import * |
card
程序分析
1 | char *__fastcall sub_1497(char *a1, unsigned int a2) |
漏洞点在 edit
函数,这里使用了 strcpy
。如果我们先用 大size
的字符串 覆盖了 src
,然后再用 小 size
时,memset
只会清空小 size
,而调用 strcpy
时就存在堆溢出。
然后,存在一个后门可以调用3次正常的 edit
,可以输入 \x00
。
利用分析
首先是常规的堆溢出,修改 chunk_size
,并释放到 unsortdebin
,得到 libc
地址。
这里需要注意的是泄露地址时,我们需要先构造两个 free tcache
,再通过堆溢出,将 free chunk1
的 next
指向一个已分配的含有 Libc
地址的堆块。这样就将libc
地址放到了 tcache
中,然后修改 libc
的后两位指向 stdout
来泄露地址。
最后是提权的方法。
这里只能执行 orw
,所以常规思路:
- 将 free_hook改为
magic_addr
- 构造一个
frame
结构,在里面布置好setcontex+61
的地址,和将rsp
设置为orw
的地址,将rip
设置为ret
- 这样最后就能通过
setcontext
执行ret
到orw
处,执行 rop
1 | frame_addr = free_hook |
EXP
1 | from pwn import * |
student_manager
程序分析
很简单的 2.27 uaf 漏洞。
1 | v1 = *(unsigned int *)(chunk_list[i] + 32LL); |
但是,我却做了很久,主要是用不了自己带符号的libc
,调试堆时很不方便。二是修改 next
指针时 只能修改 4位,需要构造各种错位。
利用分析
劫持 tcache_struct_perthread
来泄露地址。
最后劫持 free_hook
来 getshell
。(但是,最后失败了,我真的一脸懵逼)。
后面看了 wp,发现出题人是把 free_hook
给 patch了,导致只能通过 IO_FILE
来做。(没符号,调试IO 直接自闭了:)
IO_FILE
攻击,覆写 _IO_2_1_stdout
的 vtable
指向 _io_str_jumps
的 finish
。将 _IO_2_1_stdout+0xe8
覆盖为 system
地址。在 输出流中写入';sh'
。
EXP
1 | from pwn import * |
feedback
做这些题,我时常质问我为什么这么菜。
程序分析
1 | char *__fastcall sub_1065(char *a1, unsigned int a2) |
程序漏洞存在于输入时,有一个 off-by-null
漏洞。
利用分析
这道题,和我之前分析 house-of-storm
时做的题十分类似,都需要利用 largebin attack
来泄露地址,最后是利用 house of orange
的方法攻击 IO
来执行 orw
。但是,这道题,由于需要使用自己编译的 libc
,调试时没有符号,十分阴间题目。
- 泄露地址
构造一次 largebin attack
来修改 IO_2_1_stdout
的 flags
;再利用一次 unsortedbin attack
来修改 IO_2_1_stdout
的 IO_write_base
。按理说,largebin attack
可以将两个地址修改为 unsortedbin
的地址,这里为什么不直接用一次 largebin attack
将 flags
和 IO_write_base
都修改了,原因是由于 这里的 largedbin
的 fd_nextsize
不含有 libc
地址,我们不能直接伪造其指向 IO_2_1_stdout
- getshell
泄露地址后,getshell
的方法就类似于 house of orange
,这里程序含有一个后门函数作用是修复 unsortedbin
链表。也就是我们使用后门函数后,可以正常使用 house of orange
攻击,不过这里开启了沙箱。需要最后去调用执行 orw
。
EXP
1 | from pwn import * |
- 本文作者: A1ex
- 本文链接: http://yoursite.com/2020/12/19/2020GACTF/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!