第一次打final 被打的头都炸了,555555。过去三周了,还是水一下这道签到题。
题目情况
作者搞到了一个ruby的jit——rubi,其中打了patch,让执行代码的区域变成不可写的情况。
1 | diff --git a/engine.c b/engine.c |
对于防护,有一个思路就是寻找那些没有被保护的地方,这个只保护了ruby代码区域,没有保护其他的栈或者一些特殊符号比如free_hook和malloc_hook。
漏洞点
1.格式化字符串漏洞
2.堆溢出二连,分别溢出了变量名和函数名
但是这个堆溢出有点无用,溢出之后无法有效控制
3.数组任意读写
这个威力很大,利用读取操作获得libc地址之后,可以直接改free_hook和malloc_hook。
方法一 利用格式化字符串
格式化字符串先泄露出libc地址,这个程序由于是32位的,所以会在栈上存储变量,这就给了我们向栈空间写数据的机会,可以输入很多参数的printf,覆盖栈空间的数据劫持控制流。
1 | fp = fopen("/tmp/t", "w") |
方法二 直接利用数组任意读写
首先在进入ruby执行空间的时候,eax为函数表地址,所以可以直接用[3]
获得到malloc的地址,这样我们就能够计算出libc地址,得到free_hook
的地址,直接写入system,然后free(‘/bin/sh’)拿到shell。
1 | x = [3] |
总结
看程序的时候,多注意一些危险操作,比如字符串读写,内存块读写,悬挂指针问题等等。在检查保护机制的时候,注意它的保护范围和保护原理,像这道题只保护了ruby代码执行区域我们可以在其他地方写数据来绕过,之前做的一道ptrace沙箱题目,绕过它的方法是利用系统中断int3
,强制进入一次系统中断让ptrace的检测点失效,从而绕过对系统调用的检测。