破解NetKeeper本地密碼讀取


轉載Tracy'BlogTracy_梓朋

http://www.purpleroc.com/html/623079.html

--------------------------------------------------------------------

有了在涉外混跡四年,寫下的《校園網那些事》的經歷后,寫這篇文章似乎要比以前容易些。來重慶也有1個半月了,一直昏昏忽忽的,總提醒自己要打起精神來,卻總打不起精神。可能是很久沒什么能夠刺激自己、給自己增加自信心吧,於是決定看看學校的客戶端。

以前做過類似的事,於是,也就有些思維固定,不想再去做同類型的事了,屬於眼高手低型。然而賬號到期了,又想起了以前做過的事。那,來找找自信吧~~不過,這客戶端比涉外的安騰高級了好幾倍~~~~                                      

其實,先前也看過這個客戶端,不過,一直想的是能夠實現linux下撥號上網。好了,廢話不多說了,進入正文吧。

 

先說目的:從文件中還原出我們撥號時輸入的賬號、密碼。那先從文件看起,看看是哪個文件保存了這些信息。

打開netkeeper的安裝目錄,看看每個文件是干嘛用的:


這個應該是沒可以理解的。那,保存密碼的文件應該是在bin或者是config文件夾中了(省去推論文字,沒看懂的可以先看看《校園網那些事》……)。其實,我們對比剛安裝好程序,和撥號一次之后文件夾中的內容就可以清楚的看到,在bin文件中多了一個Credit文件。那,它很有可能就是我們要找的文件了。

ok,我們拿出peid看看程序有沒加殼,


 

提示沒找到,不過,看區段就知道vmp的殼。我等菜鳥是沒想過要去挑戰它的。那,帶殼運行來調試吧。

OD載入(忽略所有異常),直接對下斷bp CreateFileA(分析見《校園網那些事》),F9跑起來,發現了類似如下call

 

0018785C   7266C4A4  つfr   /CALL 到 CreateFileA 來自 AcLayers.7266C4A1
00187860   00187CA0  爘.   |FileName = "\\.\Global\NPF_{C97F955E-E47F-4270-9432-764A2C7C41D3}"

 

我們暫且把它當作是vmp殼對程序自解壓時的一些操作吧(知道的還麻煩告知一聲),這也是為什么在我們確定了讀取文件的位置后不能直接對地址下斷,而必須每次都跑完對類似這些|FileName = "\\.\Global\NPF_文件的操作的原因。我理解為,因為程序還沒解壓完,你直接下斷,會引起程序解壓出錯,而導致程序出錯。

一直F9到FileName為C:\ChinaNetSn\時就要注意了。


 

一下下的摁F9,到出現讀取Credit文件:


 

取消斷點,Alt+F9返回用戶代碼區。我看到的是非常亂的數據:


 

沒關系,CTRL+A分析一下。就出現了我們可愛的反匯編代碼了:


 

我們可以看到,剛才程序僅僅是訪問Credit文件,而還沒進行讀取。以下是讀取片段。


 

為了節省篇幅,直接復制代碼吧:

0041B049   > \817C24 0C 8C1>cmp dword ptr ss:[esp+C],168C            ;  文件完整性校驗

0041B051   .  74 17         je short NetKeepe.0041B06A

……

0041B06A   > \56            push esi                                 ; /hObject

0041B06B   .  FF15 30425000 call dword ptr ds:[504230]               ; \CloseHandle

0041B071   .  6A 00         push 0

0041B073   .  57            push edi

0041B074   .  8BCB          mov ecx,ebx

0041B076   .  E8 25000000   call NetKeepe.0041B0A0                   ;  加解密入口

為什么判斷0041B076時解密入口呢?你可以自己直接F8過去,然后看寄存器啊,內存啊,等等之類的變化來確定。好吧,主題來了,我們要解決的就是這個call。

先看反匯編代碼以及我的注釋:(有點長,放到最后附錄一中。想看的忍一忍看完吧!)

這里解釋下主要代碼段:

 

這段標准的代碼中,我們可以看出,解密有三個步驟,第一和第三步是進行移位操作,第二部才是真正的各種轉換。

我們要進行解密,也就是把這段代碼換成我們的C語言,來進行解密。在解密入口處寫了個xinlides,其實我也不知道他是不是用的des。目測不是吧:

附上C程序解密代碼。(見附錄二)

這里解釋下主要代碼段:

void encode(char *buffer, int len)

{

   char *p;

   while (len)

   {

       p = encode1(buffer);//位置交換

       encode2(buffer, p);//解密

       encode3(buffer);//順序改回

       len = len - 8;

       buffer = buffer + 8;

   }

}

最難的問題應該在於第二步了,為了偷懶,少寫點代碼,就直接用C語言嵌套asm來實現。

不過這樣做的最困難的地方應該在於,保護現場以及,匹配好各傳入參數。我們來對比一下C和反匯編的代碼。

在反匯編代碼中,進行第二步加密中 mov eax, dword ptr [ecx]前,push了以下參數:

 

00404256  |.  68 80755400   push NetKeepe.00547580                   ;  要用到的pass

0040425B  |.  52            push edx                                 ;  放入地址

0040425C  |.  E8 DF000000   call NetKeepe.00404340                   ;  解密第二步

                       

               00404340  /$  51            push ecx

               00404341  |.  8B4C24 08     mov ecx,dword ptr ss:[esp+8]

               00404345  |.  53            push ebx

               00404346  |.  55            push ebp

               00404347  |.  56            push esi

 

那么,我們要做的就是,弄清楚這些push進去的東西,是什么,在后面用不用得上。

通過分析可以得到00404256處push的是要用到的解密矩陣。0040425B是什么要解密的內容(已被第一步解密的內容)。00404340是push此次要解密的最后一位數的地址。其實可以看作保護現場。00404341是把0040425B處放入的內容彈出,即ecx中保存的是實際上要進行解密的那四個字符。后面連續三個push是為了保護現場。

所以,在進行代碼嵌套的時候,我們要想這段反匯編代碼能夠按我們的想法運行,我們就要給他創造好條件。所以,在開頭,我們構造如下:

void encode2(char *buffer, char *key)

{

   __asm

   {

            lea eax, key

       push [eax]   //生成的key的地址壓棧  0018fe1c

       lea eax, pass

       push eax   //把pass的地址壓棧   0018fe18

       lea eax, buffer

       push [eax]    //剩余的要解密的內容入棧   0018fe14

       mov ecx, dword ptr [esp+8]   //把key給ecx

       push ebx   //10

       push ebp   //0c

       push esi   //08

       mov eax, dword ptr [ecx]

       mov edx, dword ptr [ecx+4]

       mov ecx, eax

       mov esi, edx

       shr ecx, 4

       and ecx, 0x0F0F0F0F

       and esi, 0x0F0F0F0F

       xor ecx, esi

     ……

       xor esi, eax               //esi中為解密后,前四個字節

       mov eax, dword ptr [esp+0x6C]   //將buffer的地址給eax    重點是,是否成功得到buffer地址

       xor edx, ecx              //edx中為解密后,后四位字節

       mov dword ptr [eax], esi    //寫入解密后的前四位字符

       pop esi

       pop ebp

       mov dword ptr [eax+4], edx  //寫入解密后的后四位字符

       pop ebx

       pop edx

            pop ecx

            pop ecx//后來自己加上去的(不然,彈出的esp恢復不了)

   }

}

當然,要嵌套好反匯編的asm為自己所用,你必須自己單步去一一調試,對比每一步得到的結果。有差異,就更改~~~

其中還有個很有趣的代碼如下:

原反匯編代碼中所有的類似如下的內存賦值:

mov ebp,dword ptr ds:[ebx*4+536408]

均被替換為:

push ecx

lea ecx, key3

mov ebp, dword ptr [ebx*4+ecx]

pop ecx

很巧妙的用到了堆棧作為臨時存儲點。

好吧,就寫到這里吧。

代碼實現的功能是:

把Credit文件中的所有賬號密碼解密后取出,以明文形式保存到Credit.txt文件中。

其實,我們還可想象下一些盜號程序的工作原理,我們設立一個服務端用作收信,程序把得到的buf發送到服務端,就是一個典型的盜號程序了。

好了,就寫到這,大家,看得懂的給點點評,看不懂的碰個人場吧。

下一步要做的,盡量找到心跳包原理,希望能夠完全脫離netkeeper吧,動態用戶名的生成算法網上已經有了。我也拿了分,不過,暫時沒用上,有想研究的,可以聯系我,一起努力把。                                              

最后,感謝monsterok  ,文中代碼是基於他的帖子中給出的代碼做的更改          :http://bbs.pediy.com/showthread.php?t=136534&highlight=%E9%97%AA%E8%AE%AF


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM