题目来自于pwnable.kr
平台的horcruxes
题目。
本题是根据漏洞利用ROP实现的。
ROP全程是Return-oriented Programming,该漏洞是利用buffer overflow实现攻击的一种。
但是与传统的buffer overflow不同之处在于ROP攻击可以绕过NX保护机制。NX保护机制是
通过设置栈所处的内存为不可执行区域从而实现的shellcode不可在栈中被执行。
然而ROP是通过覆盖正常程序函数的return
指针从而指向程序本身的机器代码(gadget),
然后配合跳转到的return
指针实现的一系列的连续跳转的程序执行。
本文通过一道CTF题目介绍了作者的解题思路和ROP漏洞的利用过程。
本人安全萌新最近弄了个博客,欢迎前去鄙人的博客查看更多的安全相关文章 XD
该程序并没有提供源代码,可以通过IDA或者GDB直观看到程序的运行逻辑:
可以明显发现可以被利用的漏洞代码gets()
,该函数没有指定buffer的大小,并从stdin
缓冲区读取数据,所以会导致栈中的return指针被覆盖。
首先检查一下程序开启了什么保护:
发现程序没有开启PIE也就是ASLR随机地址载入的保护机制。为buffer overflow 提供了很大的便捷
同样没有发现Canary对栈指针进行保护。但是可以明显发现该程序实现了NX栈不可执行的保护。
之后要看一下buffer的开始地址到覆盖ropme()
函数return地址的距离,并进行payload的设计
在IDA pro反汇编出的伪代码中已经标记出了s
buffer的大小和起始地址:[ebp - 0x74]
基于此我们可以推断出buffer的起始地址到ropme()
反回地址的距离应该为0x74 + 4
。
多出的这4个bytes长度是存放stack frame(原函数ebp地址)的数据长度。所以可以初步判断
padding
的大小为0x78 = 120
个bytes数据。
通过查看源码可以发现,其实只要通过下述这个判断flag就可以得到flag:
通过这个判断我有了两个思路,第一个思路是真正的达到判定条件,得到flag,
第二个思路是,在覆盖return指针后是否可以直接使得程序跳回到判断之后的语句。
第二种想法最简单,所以先尝试了这种想法。但是通过数次努力,发现ropme()
函数中的地址
是不可以被反回的。函数中的任意一个地址都不可以。
所以只能实行第二个思路,也是这个题目想让我们实现的方法。仔细看一下这个判断,首先通过
atoi()
函数将我们输入的到s
的buffer里的字符串转换为int
数据。
然后再与sum
数值进行比较,接下来就要知道sum
是如何计算出来的。
在IDA pro中很容易就会发现sum
生成的地方:
sum = a + b + c + d + e + f + g
,而这七个数值是随机生成的。此时会意识到在ropme()
函数中有命名为A B C D E F G
的函数,查看各个函数:
七个函数的作用都是与函数A()
类似,打印出在init_ABCDEFG()
函数中随机生成的各个数值。
基于这个特点,我们构造rop payload的思路应该是,逐次返回到各个函数,然后使其打印出随机的数值。
最后再返回到ropme()
函数,将得到的数值相加进行输入,即可得到flag。
首先我们知道了padding数据的大小应为120 bytes
。
然后在120 bytes
数据后可以拼接上A()
函数的其实地址:0x0809fe4b
。这样在ropme()
函数结束后就能够跳转并执行A()
函数。得到a的随机数值。
但是新的问题是,如何能在运行完A()
函数后执行,B()
函数。其实仔细观察栈的结构就很容易发现,
当函数A()
执行结束之后,会执行return指令,此时return的地址应该是在我们覆盖的ropme()
函数return指针的后4个bytes,也就是120 bytes + 0x0809fe4b
后buffer中的数据。
这样一来就很清楚了,直接将地址罗列在padding数据之后,函数会一个一个的进行跳转。
最后一个问题就是,最后还要返回到ropme函数,但是,这个函数的所有地址都不能被返回。
所以,可以通过返回到main
函数中调用ropme()
函数的地方执行ropme()
。
下面是找到的各函数和需要的地址:
所以构造出的payload
为:
'A' * 120 + 0x809fe4b + 0x809fe6a + 0x809fe89 + 0x809fea8 + 0x809fec7 +
0x809fee6 + 0x809ff05 + 0x809fffc
使用pwntools很容易就可以完成攻击脚本:
作者是ssh到服务器上在/tmp
文件加下建立并运行文件的,需要多跑几次,good luck!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)