清明假期打了两场比赛,感觉最近题目的风格都变了,喜欢在pwn题里加上一大堆逆向,能逆就能解。还有就是疯狂套娃,出了两道arm+vm的形式,那以后可以出 mips+vm,riscv64+arm的题了。最后,希望后面可以学习更多的逆向知识。
Maybe_fun_game
题目分析
1 | void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) |
程序总体逻辑是一个菜单题,包含 add、edit、show
三种功能。这三种功能没发现有啥问题。但是需要注意的是 ptr
这个堆块,其在add
功能读取输入结束后,会进行一次 free
。而 ptr
的生成是在 get_input
函数中。
在输入和输出函数中都套了一个格式,和用 Base64进行加密了。
1 | const char *sub_1070() |
这个读取输入函数总体逻辑也很清晰,但是加了一个格式,逆出来的格式如下。其中 str_size
是我们输入字符的size
,op_size
是我们的 Head
。
1 | f1 = 0x1234567812345678 |
这里输入函数,有几个问题:
- op_size由我们指定,可以通过malloc(op_size),申请任意大小的堆块
- str_size由我们指定,可以通过calloc(op_size)申请任意大小的堆块
- 发生错误时,依次释放了
ptr
和head_chunk
那么当我们在 add
输入content
时,使得输入发生错误,则会依次释放 ptr
和 head_chunk
,然后 add
功能结束 会再次释放 ptr
,存在 double free
利用分析
- 泄露地址
首先通过 op_size
申请大块,释放后放到 unsortedbin
。然后通过 add
得到 libc
地址
- 劫持 malloc_hook
由于是在 2.23
,在 fastbin
中构造 double free
,劫持 __malloc_hook
,修改为 one_gadget
来 getshell
。
EXP
1 | #encoding=utf-8 |
appollo
一道 arm的 vm题,逆向难度挺大的,因为 ida伪代码有一些不全。首先hint给了这是一个 车在地图上走的程序
程序分析
1 | void menu() |
首先如 vm
题一样有很多功能,这里有一个函数表如下所示共有10个函数,同时还有一个指令表与函数表一一对应:
1 | .data:0000000000014010 off_14010 DCQ sub_EB8 ; DATA XREF: menu+20↑o |
1 | .rodata:0000000000003770 dword_3770 DCD 0xA, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB |
这里我们需要从指令表中 获取相应的偏移,然后才能在函数表中执行对应的函数。比如这里想要执行第一个函数 create
,那么需要输入 42
,才能从指令表中获得 1。这里翻译过来的指令如下:
1 | M_R = 42 |
然后分别看几个功能,首先必须初始化地图,这里 v1
就是我们的输入,会依次读取我们的输入,和正常的 vm
一样。
1 | __int64 game_init() |
这个是创建车,输入4个参数,分别是 车初始化所在的位置 list
和 row
表示,以及车的 size
,分别是 size&0xff
和 size>>8
。
1 | void create() |
这里是删除车,两个参数,车的坐标 list
和 row
。删除车后,会将对应坐标点置为0.
1 | void Delete() |
这个是给地图设置边界,输入三个参数边界所在坐标,以及边界值。但是前提是该边界没有值,且值只能为 2,3,4.
1 | void pos_set() |
这是将边界清空。
1 | void set_zero() |
后面4个函数就是控制车的移动。分别是 up、down、left、right
。这里我们以 down
分析。首先会判断向纵坐标走一步时,前面是否有边界,如果边界为0则直接向前走,并将坐标设置为 5。如果有边界,边界等于 2或3时,会向前走两个纵坐标,并将纵坐标加2。最后会在 map
的现在车辆坐标处写上当前 行动次数。
1 | void down() |
那么这里就存在一个漏洞。首先看一下 state、maps
和车的三个堆块的布局,可以看到 maps
和 car
是相连的。
1 | 0x40009d32a0: 0x0000000000000000 0x0000000000000081 //state |
当我们通过 set
将 state
的边界 设置在 state+0x70
处,并设置为2。然后通过 down
函数不断纵坐标加,当遇到我们设置的 边界2
时,即会将 y+2
,就是跳过边界,实现溢出。而如果我们将 row
设置为 8
,跳过边界后,此时 y+2
后,刚好溢出 0x10
,最后执行如下代码时:
1 | *(_BYTE *)(maps + y * Row + x) = v1; //maps中当前车坐标处写上行动次数 v1 |
就能溢出改写 car
的 size
。如果我们精准的将 v1
的值置为 0x20
,那么 car
的堆块 size
扩大,即实现了堆重叠。
利用分析
- 泄露地址
可以利用 释放大块到unsortedbin
,来泄露地址。
- getshell
利用上面的堆溢出 修改 car
的 chunk
为 0x121
,然后释放其后面相邻的堆块到 tcache
。在释放 car
到 tcache
。在申请 0x120
的堆块,就能覆盖后面空闲的堆块的 堆头和next
指针。最后劫持 free_hook
即可。
EXP
1 | from pwn import * |
quiet
程序分析
又是一道 arm+vm
,但是这道放的时间比较晚,所以觉得应该很简单。首先通过 mmap
申请了一个大块,并赋予了 可读可写可执行权限。所以猜测应该是跳转到这个堆块执行 shellcode
。
1 | __int64 sub_E40() |
找到了如下功能,能够跳转到 0x100000000000
地址执行
1 | .text:0000000000001098 0C0 MOV X0, X23 |
然后就是输入,有一个 getchar()
功能,能够向 0x100000000000
输入一个字符。x22
为写指针,初始为 0x100000000000
1 | .text:0000000000001154 -C0 LDR X0, [X25] |
然后就是找能够使 x22
加1
的功能,找到如下
1 | .text:00000000000011C4 loc_11C4 ; DATA XREF: .data:off_12018↓o |
利用分析
那么就很简单,利用 getchar()
和 写指针加1,向 堆块写入shllcode
。
最后跳转执行shellcode
即可。
EXP
1 | from pwn import * |
moregirlfriend
程序分析
1 | __int64 dele() |
在 delete
时,判断了 i<=del_num
,这里存在越界。当 del_num=8
可以多 释放一个堆块,也即9个堆块。而 free_list
只能 装8个堆块,紧邻的是 chunk_list
。也就是这里可以多释放一次堆块。
1 | .bss:0000000000004060 free_list dq 8 dup(?) ; DATA XREF: leave+E1↑o |
利用分析
我们可以先把 chunk_list[0]
放入 free_list
中释放,然后释放8个堆块时,会将紧邻的 chunk_list[0]
再次释放。也就是存在一个 double free
。
2.31
的 double free
在不能修改 key
时,可以考虑将 double free
放入 fastbin
中。通过 fastbin
的 double free
来实现分配任意堆块。
- 泄露地址
这里泄露地址比较麻烦,主要是我们不能通过 释放到 unsortedbin
在申请回来输出,因为输出会在后面添上 \x00
。我这里采用了堆合并,将 3个 大堆块 按照 1,3,2的顺序 释放到 unsortdebin
中,然后在第一个和第三个 留下了 libc
地址。然后通过 申请一个占位,再申请一个大堆块,使得其末尾刚好位于第三个堆块的 libc
地址。例如 申请 一个大堆块 0x400
,使其 0x408
处刚好为 libc
地址。然后再释放该堆块,即可泄露libc
地址。
- double free
按照上述的方法,在 fastbin
中构造 double free
。而且这样还可以泄漏堆地址。我们构造如下:
1 | chunk[0]->chunk[7]->chunk[0] |
当我们将 tcache
清空,再申请一个 fastbin
chunk0
时 ,整个 fastbin
链会被移入 tcache
中,我们将 chunk[0]
的 next
指针指向一个 0x400 大堆块的上方,构造堆重叠。最后通过堆重叠,实现劫持0x400
指向 free_hook
。最后 orw
。
EXP
1 | #encoding=utf-8 |
1 | 79 6f 75 20 73 75 63 63 65 73 73 66 75 6c 79 20 72 6f 62 62 65 64 20 79 6f 75 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 72 6f 62 62 65 64 20 |
- 本文作者: A1ex
- 本文链接: http://yoursite.com/2021/04/05/2021红明谷and虎符题解/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!