진짜로 막힌단다. 성공율은 80%정도, 코드 인젝션은 못 막지만 일반적인 방식의 인젝션은 막을 수 있단다.

Originally posted on rootkit.com
http://www.rootkit.com/blog.php?newsid=640

——————————————————————————————

This method was discovered when I was doing some random debugging. Sudden idea came to my mind when I inject some DLL into olly-debugged process. Olly log traced that one thread was created and terminated. Then I thought since the DLL loading takes place in user-mode, why cant I prevent it from loading by hooking some function ?

So I put a bp on kernel32.LoadLibraryA() and inject DLL again. ollydbg halted. I traced the stack frame to one function in kernel32.dll. I inject some DLL again, and yet I traced to the same function.

My sense tell me that is the function I’m looking for. So I began coding and hook that function. Voila, now Winject reports DLL-injection failed. But wait, our job is not done yet.

After more debugging I found that my hook was preventing the our own thread from creating too. So I need a method to distinguish rogue thread from our own thread.

Finally, I found a method used by Piotr Bania to prevent shellcode execution. He used VirtualProtect() to determine whether a code is rouge or not. Usually shellcode is injected as a result of stack-overflow or any other memory-based leak. These memory should be writable. If any pointer is pointing to a writable memory section, we can conclude that it is altered by the shellcode.

Yet, this method has a flaw. Most packer and protector modifies PE and mark the image as writable (to decompress or decrypt the content) and doesn’t bother to restore them. It would raise false alarm when we use VirtualProtect() to check the protection. So I thought of a better solution.

I used VirtualQuery() to check for memory type. Usually when we create a thread, it should point to code within the image. (marked by loader as MEM_IMAGE) Any VirtualAllocEx() allocated memory would not have that flag set.

——————————————————————————————

Trypanophobia
http://code.google.com/p/opcode0x90/source/browse/trunk/snippets/Trypanophobia/

——————————————————————————————

 


위 내용에 대한 자세한 설명 출처 : http://nerd.egloos.com/2940078
 

프로세스에 DLL Injection할 때 주로 사용하는 방법은 CreateRemoteThread()를 사용하여 
LoadLibrary()를 호출하여 원하는 DLL을 Load한다. 이런 방법을 사용하는 트로이 프로그램이나
Hook을 시도하는 녀석들을 감지해낼 수 있다.

CreateRemoteThread()가 Target Process를 향해 호출되면 Target Process내에서는 CreateThread()가
호출되며 CreateThread()를 리버싱해보면 다음과 같다.

KERNEL32!BaseThreadStartThunk:
77e964cb xor     ebp,ebp
77e964cd push    ebx
77e964ce push    eax
77e964cf push    0x0
KERNEL32!BaseThreadStart:
77e964d1 55               push    ebp
77e964d2 8bec             mov     ebp,esp
77e964d4 6aff             push    0xff
...snip...
77e9651d ff750c           push    dword ptr [ebp+0xc] <-- push the argument
                                                                                          to ThreadFunc
77e96520 ff5508           call    dword ptr [ebp+0x8] <-- DWORD WINAPI
                                                                                         ThreadFunc(LPVOID);
77e96523 50               push    eax
77e96524 e805000000       call    KERNEL32!ExitThread (77e9652e)
77e96529 e923f10000       jmp     KERNEL32!BaseThreadStart+0x81 (77ea5651)

여기서 제일 처음 호출되는 BaseThreadStartThunk() 함수를 Hooking 하여 Hook Procedure
에서 lpStartAddress(Thread의 시작주소-Stack에 존재)를 LoadLibrary나 GetProcAddress, 
FreeLibrary와 같은 함수의 Address와 비교하여 같을 경우, Injection이라고 간주한다.

이러한 탐지 방법은 단지 CreateRemoteThread()를 사용하여 DLL Injection하는 경우만
탐지가능하고, SetWindowsHookEx(), SetThreadContext()로 DLL Injection하는 경우는 탐지
불가능하다.

 

저작자 표시 비영리 변경 금지

댓글을 남겨주세요

Name *

Password *

Link (Your Homepage or Blog)

Comment

Secret