mips练习
mips-题目练习
前言
上次学mips的时候就打算在buuctf上写两道题目看看效果,巩固一下。但是当天buuctf不知道怎么回事,g掉了。写不了题目了,直到现在,才有时间写这两道题目。
这两道题目应该也是非常经典了,网上有很多对这个的分析,题解。mips的前置知识呢写在了其他博客里面,在这里就啰嗦了。直接上题目。
axb_2019_mips
这是一道ret2shellcode 的题目,非常的经典. 因为mips架构,不会开启NX 和 ASLR,所以我们可以往栈上,写shellcode,栈地址空间每次也都是一样的.所以非常好绕,不用泄露信息什么的.
但是,因为远程环境和本地环境的区别,远程和本地的地址空间不一定一样.所以远程还是不能直接这么打.继续看题
ida分析

非常简单的程序,没有什么利用点,看vuln()

发现溢出漏洞了,可以修改返回地址,但是要看汇编确定$ra的位置。

说真的,有的时候看汇编比看伪代码好。通过这个代码段,我们也可以了解到mips架构调用函数的一个流程。
进入之后,先把$sp往上移动0x40,然后分别把$ra和$fp放在$sp+0x3c和$sp+0x38 的位置.
在read时,会往$sp+0x18的位置读入0x200字节.所以输入0x20字节数据后就可以覆盖$fp和$ra.
思路分析
- 之前说过可以直接写shellcode在栈上,然后把返回地址设置成栈上的地址就可以了,这个在本地完全可以这么打,但是远程的栈地址和本地会不一样,也不要想着爆破.
- 所以,我们转换思路,通过返回到read 函数,把shellcode 写到bss段上,在返回到bss段上执行,也是非常简便的方法.
- 如何控制read 的buf呢?在
0x40080c的位置,有两条指令,分别是从栈上取出保存的$fp和$ra,那么只要我们覆盖到这里,就可以控制,取出来之后的这两个寄存器. 同时注意到read 是通过$fp来计算buf 的,所以控制了$fp,就控制了buf. - 那么如何控制程序跳转到shllcode呢?或者说,第二次的返回地址应该写在哪呢?因为
$fp和$ra都是通过$sp寻找的,所以要特别关注$sp的变化,发现在read的结束之后又一条指令move $sp, $fp,这会是$sp移到$fp的位置,所以第二次的返回地址,写在第二次的payload里,计算好偏移即可.
exp
1 | from esy import * |
ycb_2020_mipspwn
一回生,二回熟.再次看到同样,或者类似的read就非常得心应手
ida分析

表面上是一个菜单,实际上核心只有description ,直接点进去看

继续

直接看汇编,除了偏移不一样,没有任何变化.和上一道题完全一样的方法
思路分析
- 那我们想如何快速的计算出偏移呢?首先要确定fp 和 ra 的偏移,分别是0x50 和 0x54, 直接可以出来.然后是buf 的偏移,0x18.可以通过ida 反汇编看出来.
- 所以要写0x38的垃圾数据.所以如果都用0x50+var_xxx这种形式,直接看buf,这里xxx是多少,就是写多少垃圾数据.非常快速的找到偏移.
- 第二次shellcode 的偏移 也很好找.假设你第一次payload 设置的fp 是 bss_addr.那么第二次返回地址就是
p32(bss_add+0x18+0x40) - 0x18 是, read时 的偏移. 0x40 是,前面的垃圾数据,假设这个地址本身的长度.因为我们都会把shellcode 写在这个地址的后面.
exp
1 | from esy import * |
后记
写两道题,对mips下的程序的一个调用一下就开朗了.对shellcode ,寄存器的运用也提高了,还是收获不小.这两道题上手也是非常的快.
不过第一道题似乎需要uClibc,我是之前分析DIR-815固件时,binwalk提取出来这个libc ,我就直接用了.
第二道题直接给了uClibc,可以直接写.



