天天看點

挖掘作業系統内部未導出函數,将注入進行到底

作 者: Anskya

時 間: 2006-06-29,15:43

鍊 接: http://bbs.pediy.com/showthread.php?threadid=28211

InjectCode for Win9x..

文章作者:Anskya

原文出處:看雪論壇

轉載請保留版權~謝謝

現在注入方式很多,不過無外複三種:

1.使用映射代碼然後建立遠端線程

2.利用消息鈎子插入DLL兩種

3.使用調試API.GetThreadContext,SetThreadContext來改變線程的環境啟動代碼

4.不過基本上Win9x下差不多都是使用消息鈎子挂鈎模式

當然EliCZ叔叔釋出的~EliRT可以讓我們在Win9x下也可以使用

CreateRemoteThread注入函數...這裡偶簡單的說一下另外一種注入方式

利用系統内部函數進行建立遠端線程.

這裡我就不多說一大堆理論了~相關文獻請參見EliCZ叔叔的文章...

當然這裡使用的注入方式~他的文章中并沒有提及...

1.原理

[1]定位目标

既然是誇程序的建立程序,首先我們懷疑的就是調試API

他們是如何作到調試遠端程序的,比如DebugActiveProcess,

他是如何挂起目标程序的...是以對目标程序進行逆向分析..

(關于次問題請到...exetools裡面檢視相關文章吧...裡面有讨論過)

(一下代碼是反彙編DebugActiveProcess函數的...這裡貼的是關鍵部分分析)

其實就在DebugActiveProcess下面幾行的位置處...自己分析一下就知道了

代碼:--------------------------------------------------------------------------------

; IDA output:

;.text:BFF9490D                 push    8                   ; const

;.text:BFF9490F                 push    edi

;.text:BFF94910                 push    offset sub_BFF9494D ; thread

;.text:BFF94915                 push    0FFFFF000h          ; tells kernel to allocate stack

;.text:BFF9491A                 push    edi                 ; pdb

;.text:BFF9491B                 call    CreateRemoteThread9x; arbitrary name

;0xE8 = call; 0x85 = push edi; 0xFFFF = higher part of 0xFFFFF000

特征碼:0E857FFFFh(看不懂嗎?自己反一下這個函數就知道了...16進制碼...請問IDA這裡怎麼用???為顯示不出...)

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

至少跟蹤發現這個函數不是WIndows導出的函數是以我們不能直接調用這個函數

(至少無法通過GetProcAddress函數搜尋出位址來...但是我們完全可以定位函數位址和傳入參數...分析代碼看下面的文章)

2.定位

知道原理了..開始逆向分析...這裡分析的目标是國外的一款非常恐怖的"Trojan"程式

Spirit(反向連接配接+遠端注入代碼,上傳DLL或者EXE并運作之...體積:1.55k,

還有系統資料庫添加,自删除等功能...支援Win9x下程序插入--一開始就對他很好奇^_^)

關鍵函數逆向分析部分:OD反出來的...

代碼:--------------------------------------------------------------------------------

00400158    68 40000000     push    40

0040015D    68 00300008     push    8003000

00400162    68 D5050000     push    5D5

00400167    57              push    edi

00400168    FF15 42144000   call    [401442]                         ; kernel32.VirtualAlloc

0040016E    68 08000000     push    8

00400173    57              push    edi

00400174    50              push    eax

00400175    57              push    edi

00400176    68 D1040000     push    4D1

0040017B    8D15 0E114000   lea     edx, [40110E]  ;這個位址是需要插入的代碼記憶體位址

00400181    52              push    edx

00400182    50              push    eax

00400183    56              push    esi

00400184    FF15 32144000   call    [401432]                         ; kernel32.WriteProcessMemory

0040018A    FF15 3E144000   call    [40143E]                         ; kernel32.GetCurrentProcessId

00400190    64:3305 3000000>xor     eax, fs:[30]

00400197    31C3            xor     ebx, eax

00400199    8B35 3A144000   mov     esi, [40143A]                    ;kernel32.DebugActiveProcess

0040019F    46              inc     esi

004001A0    813E FFFF57E8   cmp     dword ptr [esi], E857FFFF  ;比較是否是CreateRemoteThread9x記憶體特征

004001A6  ^ 75 F7           jnz     short 0040019F    ;不等繼續跳轉

004001A8    AD              lods    dword ptr [esi]    ;搜尋到以後開始擷取位址(掃描兩次)

004001A9    AD              lods    dword ptr [esi]

004001AA    01F0            add     eax, esi      

004001AC    68 00F0FFFF     push    -1000

004001B1    53              push    ebx

004001B2    FFD0            call    eax

004001B4    57              push    edi

004001B5    50              push    eax

004001B6    8B35 2A144000   mov     esi, [40142A]                    ; kernel32.OpenProcess

004001BC    46              inc     esi

004001BD    813E 50FF32E8   cmp     dword ptr [esi], E832FF50

004001C3  ^ 75 F7           jnz     short 004001BC

004001C5    AD              lods    dword ptr [esi]

004001C6    AD              lods    dword ptr [esi]

004001C7    01F0            add     eax, esi

004001C9    53              push    ebx

004001CA    FFD0            call    eax        ;調用此函數

004001CC    61              popad

004001CD    C3              retn

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

3.實作

不用說了吧~上面的代碼逆向寫一下就OK了...

既然注入代碼我們就作全套...

[1]申請遠端程序空間(C代碼實作)

WinNT下我就不多說了~反正大家都知道的

關鍵說說Win9x

逆向分析一下中國黑客病毒

(CreateKernelThread建立線程...和

MoveDataToKnl函數(WHG自己寫的具體看ChineseHacker代碼))

不過他好像不能讓我們将代碼注入到别的程序内部...

好了Google搜了一下文章...發現Win9x核心下0x8000000以上空間都是透明的?

Why?你最好别問我,我也不知道..我很菜...

是以以上反彙編出來的代碼是

代碼:--------------------------------------------------------------------------------

00400158    68 40000000     push    40

0040015D    68 00300008     push    8003000

00400162    68 D5050000     push    5D5

00400167    57              push    edi

00400168    FF15 42144000   call    [401442]                         ; kernel32.VirtualAlloc

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

啊~好了...寫一下具體代碼好了

代碼:--------------------------------------------------------------------------------

LPVOID My_VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD 

flProtect) 

{

  if (GetVersion() > 0x80000000)

  {

    return VirtualAlloc(lpAddress, dwSize, 0x8000000 + MEM_COMMIT, PAGE_EXECUTE_READWRITE);

  }else

  {

    return VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect);

  }

}

BOOL My_VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType) 

{

  if (GetVersion() > 0x80000000)

  {

    return VirtualFree(lpAddress, dwSize, MEM_RELEASE);

  }else

  {

    return VirtualFreeEx(hProcess, lpAddress, dwSize, dwFreeType);

  }

}

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

需要注意的是~在Win9x下申請空間和釋放空間以前需要~~OpenProcess

一下....在Win9x下申請空間還有一種方法:SharedMemoryAlloc函數

直接的Windows頭部裡面好像沒有...大家可以從ComCtl32.dll裡面導出...

這個函數使用非常簡單..就一個參數.申請空間長度...

建立遠端線程代碼在附件内....(把上面的OD反彙編代碼寫一遍就OK了~有必要嗎???)

具體示例代碼看:附件~注入代碼到記事本....支援Win9x下注入

參考文獻:

[1]EliCZ 的EliRT代碼,首頁.看雪上有友情連接配接

[2]y0da 的Invisibility代碼,首頁.看雪上有友情連接配接

文章作者:Anskya

原文出處:看雪論壇

轉載請保留版權~謝謝

終于可以上傳了~

代碼:--------------------------------------------------------------------------------

;======================================================

;遠端線程注入對話框示範 Ex By Anskya

;支援Win9x下代碼注入..

;Email:[email protected]

;======================================================

.586

.model flat

locals @@

include /D.N.ASM/include/useful.inc

include /D.N.ASM/include/MZ.INC

include /D.N.ASM/include/PE.INC

.data

  notepad db 'Notepad',0

injected:

    ;int 3

    pushad

    call @@delta

@@delta:

    pop ebp

    sub ebp,offset @@delta

    push 0

    lea eax,[ebp+offset cap]

    push eax

    lea eax,[ebp+offset msg]

    push eax

    push 0

    call [ebp+__MessageBoxA]

@@Exit:

    push 0

    call [ebp+__ExitThread]

    ;_invoke [ebp+__ExitThread],0

    popad

    ret

;------------------使用資料----------------------------------

  msg  db  "

  •  Hello World Coder! (C) Anskya.",0dh,0ah,0

      cap  db  "MsgBox By Anskya",0

        k32_api:

            db  'kernel32',0

              __ExitThread        dd  0058F9201h

              __WinExec          dd  028452C4Fh

              __OpenProcess        dd  033D350C4h

              __WriteProcessMemory    dd  00E9BBAD5h

            dd 0

        u32_api:

            db  'user32',0

              __MessageBoxA          dd  0D8556CF7h

              __FindWindowA        dd  085AB3323h

              __GetWindowThreadProcessId  dd  07B46AF5Eh

            dd 0

    injected_size equ $-injected

    .code

    public c entry

    entry:

    ;-------擷取相關API函數

        lea eax,k32_api

        push eax

        call get_apicrc

        lea eax,u32_api

        push eax

        call get_apicrc

    ;-------擷取完畢-------執行主函數部分

        ;call injected

        push 5

        push offset notepad

        call __WinExec

        push 0

        push offset notepad

        call __FindWindowA    ;擷取視窗句柄

        push eax

        push esp

        push eax

        call __GetWindowThreadProcessId

        pop eax

        mov ebx,eax

        push eax

        push 0

        push 1f0fffh                    ;PROCESS_ALL_ACCESS

        call __OpenProcess

        mov ebp,eax

        push 40h                        ;PAGE_EXECUTE_READWRITE

        push 3000h                  ;MEM_COMMIT or MEM_RESERVE

        push injected_size

        push 0

        push ebp                        ;pid

        call RT32_VirtualAllocEx

        mov edi,eax

        push eax

        push esp

        push injected_size

        lea eax,injected

        push eax

        push edi

        push ebp

        call __WriteProcessMemory

        pop eax

        push eax

        push esp

        push 0

        push esi

        push edi

        push 0

        push 0

        push ebx

        call RT32_CreateRemoteThread

        pop ecx

    ExitProc:

        push 0

        callw ExitProcess

        ret

    ;-------使用函數位址

    RT32_VirtualAllocEx:

        pushad

        mov ebx,[esp+8*4+4]

        mov ebp,[esp+8*4+8]

        mov edx,[esp+8*4+12]

        mov esi,[esp+8*4+16]

        mov edi,[esp+8*4+20]

        call get_k32base

        mov ecx,cs

        xor cl,cl

        jecxz @@os_nt

    @@os_9x:

        push edi

        or esi,8000000h

        push esi

        push edx

        push ebp

        push 04402890Eh                ;VirtualAlloc

        push eax

        call get_addr32crc

        call eax

        jmp @@finished

    @@os_nt:

        push 0DA89FC22h                ;VirtualAllocEx

        push eax

        call get_addr32crc

        push edi

        push esi

        push edx

        push ebp

        push ebx

        call eax

    @@finished:

        mov [esp+pushad_eax],eax

        popad

        ret 4*5

    RT32_CreateRemoteThread:

        pushad

        mov ebp,[esp+8*4+4]

        call get_k32base

        mov esi,eax

        push ebp

        push 0

        push 1f0fffh                   ;PROCESS_ALL_ACCESS

        push 033D350C4h                ;OpenProcess

        push esi

        call get_addr32crc

        call eax

        mov ebx,eax

        push 0CF4A7F65h                ;CreateRemoteThread

        push esi

        call get_addr32crc

        mov ecx,cs

        xor cl,cl

        jecxz @@os_nt

    @@os_9x:

        call get_obfs

        xor ebp,eax

        call search_crt9x

        jnc @@error

        mov esi,eax

        mov edi,[esp+8*4+16]

        mov eax,[esp+8*4+20]

        push 8

        push eax

        push edi

        push 0fffff000h

        push ebp

        call esi

        push eax

        call search_halloc9x

        jnc @@error

        mov edx,eax

        pop eax

        push 0

        push eax

        push ebp

        call edx

        jmp @@finished

    @@os_nt:

    ;   push dwo [esp+8*4+28+ 0]

    ;   push dwo [esp+8*4+24+ 4]

    ;   push dwo [esp+8*4+20+ 8]

    ;   push dwo [esp+8*4+16+12]

    ;   push dwo [esp+8*4+12+16]

    ;   push dwo [esp+8*4+8 +20]

        push 6

        pop ecx

    @@loop_push:

        push dwo [esp+8*4+28]

        loop @@loop_push

        push ebx

        call eax

    @@finished:

        mov [esp+pushad_eax],eax

        popad

        ret 4*7

    @@error:

        sub eax,eax

        dec eax

        mov [esp+pushad_eax],eax

        popad

        ret 4*7

    get_obfs:

        pushad

        push 0EB1CE85Ch                ;GetCurrentProcessId

        call get_k32base

        push eax

        call get_addr32crc

        call eax

        mov ebx,eax

        mov eax,fs:[30h]

        xor eax,ebx

        mov [esp+pushad_eax],eax

        popad

        retn

    search_halloc9x:

        pushad

        call get_k32base    

        push 033D350C4h                ;OpenProcess

        push eax

        call get_addr32crc

        mov esi,eax

        mov eax,0E832ff50h

        jmp search_compare

    search_crt9x:

        pushad

        call get_k32base    

        push 07FC598E3h                ;DebugActiveProcess

        push eax

        call get_addr32crc

        mov esi,eax

       ; IDA output:

       ;.text:BFF9490D                 push    8                   ; const

       ;.text:BFF9490F                 push    edi

       ;.text:BFF94910                 push    offset sub_BFF9494D ; thread

       ;.text:BFF94915                 push    0FFFFF000h          ; tells kernel to allocate stack

       ;.text:BFF9491A                 push    edi                 ; pdb

       ;.text:BFF9491B                 call    CreateRemoteThread9x; arbitrary name

       ;0xE8 = call; 0x85 = push edi; 0xFFFF = higher part of 0xFFFFF000

    ;  mov eax,0fffff000h    

       mov eax,0E857FFFFh

    ;  DEBUG: CloseHandle

    ;  mov eax,0E8560002h

    search_compare:    

        sub ecx,ecx

        mov cl,255     ;approx. size of DebugActiveProcess, just in case

    @@compare:

        cmp eax,[esi]

        jz @@save

        inc esi

        dec ecx

        jecxz @@exit

        jmp @@compare

    @@save:

        lodsd

        lodsd          ;eax = relative address of CreateRemoteThread9x()

        add eax,esi    ;absolute address

        mov [esp+pushad_eax],eax

        stc

    @@exit:

        popad

        retn

    ;--------The End~~~[^_^]  

    get_apicrc:

        pushad

        mov esi,[esp+8*4+4]

        call get_k32base

        push 04134D1ADh      ;LoadLibraryA

        push eax

        call get_addr32crc

        push esi

        call eax

        mov ebx,eax

        sub eax,eax

        lodsb

        test al,al

        jnz $-3

        mov edi,esi

    @@loop:

        lodsd

        test eax,eax

        jz @@end

        push eax

        push ebx

        call get_addr32crc

        stosd

        jmp @@loop

    @@end:

        popad

        retn 4

    ;void* get_addr32crc(DWORD base, DWORD crc32)

    get_addr32crc:

        pushad

        mov ebx,[esp+8*4+4]

        mov esi,[esp+8*4+8]

        sub ebp,ebp     ;counter

        mov edx,ebx

        add edx,[edx.mz_neptr]

        mov edx,[edx.pe_exportrva]

        add edx,ebx

        mov eax,[edx.ex_numofnamepointers]

        mov edi,[edx.ex_addresstablerva]

        add edi,ebx

        mov edi,[edx.ex_namepointersrva]

        add edi,ebx

        push edx

        mov edx,edi

    @@next:

        mov edx,[edi]

        add edx,ebx

        inc ebp

        pushad

        mov esi,edx

        sub ecx,ecx

        lodsb

        inc ecx

        test al,al

        jnz $-4

        mov [esp+pushad_ecx],ecx

        popad

    @@cmpstr:

        pushad

    ;   mov edx,edx

        sub eax,eax

        call xcrc32

        cmp eax,esi

        popad

        jz @@found

    ;    push eax

    ;    sub eax,eax

    ;    scasb

    ;    jnz $-1

    ;    pop eax

        add edi,4

        dec eax

        jz @@error

        jmp @@next

    @@found:

        pop edx

        dec ebp

        mov ecx,[edx.ex_ordinaltablerva]

        add ecx,ebx

        movzx eax,wo [ecx+ebp*2]

        mov ebp,[edx.ex_addresstablerva]

        add ebp,ebx

        mov eax,[ebp+eax*4]

        add eax,ebx

    @@error:

        mov [esp+pushad_eax],eax

        popad

        ret 4*2

    ;void* get_k32base();

    get_k32base:

        pushad

        sub eax,eax

        mov eax,fs:[eax+30h]

        test eax,eax

        js @@os_9x

    @@os_nt:

        mov eax,[eax+0ch]

        mov esi,[eax+1ch]

        lodsd

        mov eax,[eax+8]

        jmp @@finished

    @@os_9x:

        mov eax,[eax+34h]

        lea eax,[eax+7ch]

        mov eax,[eax+3ch]

    @@finished:

        mov [esp+pushad_eax],eax

        popad

        retn

    ; zhengxi's crc32(): optimised by Vecna

    ; input: EDX=data, ECX=size, EAX=crc 

    ; output: EAX=crc, EDX+=ECX, ECX=BL=0 

    xcrc32:

        pushad

        jecxz @@4 

        not eax 

    @@1: 

        xor al, [edx] 

        inc edx 

        mov bl, 8 

    @@2:

        shr eax, 1 

        jnc @@3 

        xor eax, 0EDB88320h 

    @@3:

        dec bl 

        jnz @@2 

        loop @@1 

        not eax 

    @@4:

        mov [esp+pushad_eax],eax

        popad

        ret

    end

繼續閱讀