0x01 漏洞信息
Easy RM to MP3 Converter 是一款音频文件格式转换工具,根据 Exploit-DB 给出的信息可知,该工具在转换 .m3u 文件时存在栈溢出漏洞。此外,漏洞程序可在 Exploit-DB 中下载。
0x02 漏洞分析
调试环境如下:
操作系统:Windows7 SP1 64 bits
调试器:Windbg 10.0.10586
由于 Windows7 系统默认开启 DEP 保护,利用该漏洞时,为了返回到栈上执行 shellcode,需要把系统 DEP 关闭。
(1)“命令运行符” -> “以管理员身份运行”;
(2)运行 cdedit.exe/set {current} nx AlwaysOff
;
(3)重启计算机生效。
1. 漏洞复现
首先使用以下脚本生成一个 .m3u 文件。
WinDbg 中直接运行程序,加载 crash.m3u 文件后将会触发栈溢出,此时 eip 寄存器值为 0x41414141。
使用 mona.py 插件可计算出覆盖 eip 所需要填充的字符数量为 26094,从而精确控制 eip 指向的地址。
再次运行程序并加载 crash.m3u 文件,可看到 eip 执行 0x42424242。
2. 漏洞定位
由于程序崩溃时,查看调用栈不能得到有效的信息,无法通过栈回溯的方法定位到漏洞位置。
因为该程序未开启 ASLR,所以每次运行时栈中缓冲区的地址都相同。此外,栈溢出漏洞触发时必须要往缓冲区写数据,因此,在缓冲区起始地址处设置内存写断点,即可找到漏洞位置。
首先需要计算出缓冲区起始地址,程序崩溃时,esp-8 的位置为覆盖返回地址的数据。
根据前面计算出的偏移量,可倒推出缓冲区起始地址为 0x15901E(0x0015f60c-26094)。重新运行程序,使用以下命令设置断点后继续运行,载入文件之前触发的断点无需关注。
载入 crash.m3u 文件后继续运行,可触发 2 次断点。第二次断下的位置为 MSRMfilter03!Playlist_FindNextItem+0x53 (0x10008d93),该指令进行数据拷贝操作,即为漏洞触发点。
此时查看调用栈如下,MSRMfilter03!Playlist_FindNextItem 在 image00400000 中调用,且返回地址为 0041e3f6。
3. 漏洞成因
使用 IDA 加载 MSRMfilter03.dll,跟进到 0x10008d93 分析可知,Playlist_FindNextItem() 函数中使用 strcpy 将 v1 复制给 a1 时未进行长度检查,当复制过长数据到 a1 时会导致栈溢出。
接下来分析 strcpy 的两个参数,源字符串 v1 为 sub_10006850 函数的返回值。
因此在调用该函数的位置下断点,程序断下时查看其返回值为文件路径加上输入的数据。
接着分析目的字符串 a1,a1 为 Playlist_FindNextItem() 函数调用时传入的参数,根据函数调用栈可回溯到其调用位置在 RM2MP3Converter.exe 模块的 sub_41E2B0 函数中,可以看到是一个函数指针调用,其传入的参数为栈中的地址 [esp+8928h+Str]。
切换到伪代码界面,看到参数 Str 与 ebp 的偏移量为 0x6600 = 18(路径字符串长度) + 26094。
至此,已分析完漏洞成因,程序中处理文件中读取的数据时,未对输入数据长度进行检查的情况下,使用 strcpy 将其复制到栈中,从而可能导致栈溢出漏洞。
0x03 漏洞利用
在关闭 DEP 的情况下,可以把 shellcode 写入栈中,通过溢出覆盖返回地址为 jmp esp
指令的地址,跳转到栈中执行 shellcode。由于系统 DLL 加载时的内存基址相对固定,且在系统重启之前都不会改变,所以使用系统 DLL 中的跳板指令可较稳定地利用漏洞。
这里使用结果中的第一项 0x75ee3165 进行利用。
以上 exp 中有 2 点需要注意的。
由于是跳转到栈顶 esp 中执行 shellcode,eip 与 esp 的位置是紧挨着的,shellcode 执行过程中如果需要修改栈中数据将有可能把 shellcode 指令部分修改,因此要在 shellcode 前面预留一段内存作为栈空间,这里填充了 30 个 0x90。
由于 sub_41E2B0 函数在返回时使用
retn 4
清栈。123456789.text:0041E9D9 mov eax, 1.text:0041E9DE pop esi.text:0041E9DF pop ebp.text:0041E9E0 ; 208: dword_47BEA8 = 1;.text:0041E9E0 mov dword_47BEA8, eax.text:0041E9E5 pop ebx.text:0041E9E6 add esp, 8918h.text:0041E9EC retn 4.text:0041E9EC sub_41E2B0 endpretn 4
具体操作如下,因此需要在 shellcode 前填充 4 个字节,才能通过jmp esp
跳转到 shellcode 中执行。123pop eip跳转到 eipadd esp, 4
References:
[1] A Tale of Exploit “Easy RM 2 MP3
[2] Learn Corelan Exploit Writing Part 1