记录一次栈迁移|Hgame2024-Elden Ring I
( ºΔº )
很有意义的一次做题,尤其对我这种。。
解题过程
按照流程应该先看一下保护和文件信息,但是因为我是知道答案找过程所以就略过。
然后看ida,找一下洞
看到开了沙箱,禁用了一些系统调用
然后进函数看
申请了100h空间写东西,但是允许你写130h,非常清楚的栈溢出,给了30h的操作空间
所以大概思路就是要用orw这样也能读到flag,然后30h写不下,所以需要一块可写的地方,还有足够的长度和写的指令。
看到vuln里面有read(),所以写的指令可以直接借这个。放orx的地方就选择可读可写的bss段,那么就要栈迁移一下。
好,那么exp的思路应该是:
1 | ... |
新的栈相当于全部都是可以利用的,所以基本不担心写不写得下orw。
然后来看需要的地址(除了ida能找到的和pwntools可以直接读到的)和代码片段:
- pop_rax_ret
- pop_rdi_ret
- pop_rsi_ret
- pop_rdx_ret
- open_addr
- read_addr
- write_addr
然后去找了一下代码片段
啊这根本不够用,而且知道open_addr也需要libc基址
所以显然再加一步泄露libc基址,啊因为这个题还是比较温柔的,vuln里一共就一个puts(),一个read(),很明显这个用过的puts()
可以拿来got表泄露一下。
我们已经能够控制rdi了,30h也足够把puts()泄露了
所以payload的思路就是:
1 | 第一次read:溢出泄露puts()拿到puts()的物理地址,回到函数 |
好的下面是exp
1 | from pwn import * |
一些问题复现与小知识
栈迁移
个人理解就是栈顶找栈底,然后把栈底的旧址改了就能把栈迁移走。
那么第一次leave ret就是栈顶回到没有申请栈的时候,栈底移走
第二次leave ret就是栈顶到了新栈底的地方,控制流就跟着栈顶走了
迁移到了哪?0x404090
原计划是要迁移到bss段,但是我看到ida上bss的开始其实还要更早
而实际写进去的位置大概在prgend这里,呃呃查了一些资料感受不出来这俩有啥要可以区分的
总之直接开调,先去vmmap里面只能看到数据段是从0x404000到0x405000很大一段
然后ida也能看到bss的起始地址,就试了一下把bss_add写得再小一点,是可以打通的
1 | ... |
后来我又试了一下把orw写到data(0x404050开始)上在这个题目里也是可以打通的,不过再往前和got.plt(0x404000)开始就不ok了,应该是影响到了函数调用(?
orw
这个东西之前接触过,但是和这次的调用逻辑不太一样,,,但是函数传参那套还是在的
emmm主要调试了一下这个第二个参数传的地址的变化,open要开的是’flag‘的地址,就是[add]=’flag’
,第一遍打通的时候其实没找准,主要是因为我用的最后一个gadget和参考的exp不一样长,然后填充长度也就不一样了。
所以后来改了一下,然后把计算过程写在前面的exp里了,也用tele
调试了几种不同的情况。
recv()
这个东西从我第一次打pwn到现在都在出问题(乐
首先这次是因为这个狗题puts(“…\n”)
然后recvline(keepends=True)默认接收换行符,且是接收到换行符结束
recvuntil(delims, drop=False),delims是字符串,drop表示是否丢弃中止标志
recv()接收指定字符长度
offset
计算
这个相对libc的偏移是固定的,只是libc的基址会变,所以可以取一次调试得到的装载后的地址puts_add
-这一次的基址就是每一次的偏移。
这个x指令我不是很会用,就用p凑合凑合了
然后十进制转一下十六进制。。
脚本
但是我本来就在想,既然偏移是固定的,那pwntools为什么不能直接解析文件呢。
而且本来脚本就有:
1 | open_add=libc_base+libc.sym["open"] |
这种东西,他们的偏移不就直接得出来。
然后我就试了一下这个
1 | print(hex(libc.sym['puts'])) |
返回0x84420,所以其实这玩意确实不用算。。
沙箱
装了一个工具,解决我只能硬看的问题
一些其他小问题
调到这里大部分问题都没有了,比较可惜的是其实没有机会复现寒假出现的问题了,可能确实那个时候就是环境一开始因为各种问题就是配的烂,所以有很多莫名其妙的东西出现,现在这个环境是我五一的时候重装的,这一次从头到尾都配很丝滑,所以好像也没有换glibc,patchelf有问题等一系列的毛病。
希望能早点做到一个需要换环境的题,因为这个我真不会。
收获
动态调试其实最重要的是我现在能理解到ret和pop了,之前不知道为什么就是对这两条指令的接收度不高,所以有些问题感觉都是好像懂了好像没懂。也可能是因为虽然代码写得多,但其实没怎么在实践中接触栈,对于栈顶的理解也不够深刻maybe.
- Title: 记录一次栈迁移|Hgame2024-Elden Ring I
- Author: M1aoo0bin
- Created at : 2024-05-24 23:33:55
- Updated at : 2024-09-03 21:05:20
- Link: https://redefine.ohevan.com/2024/05/24/懒得喷/
- License: This work is licensed under CC BY-NC-SA 4.0.