Shield from thread injection
Posted at 2011/10/25 17:16// Posted in 개발자 인생/프로그래밍 팁진짜로 막힌단다. 성공율은 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하는 경우는 탐지
불가능하다.
'개발자 인생 > 프로그래밍 팁' 카테고리의 다른 글
| How to get the CPU usage of a process (0) | 2011/11/18 |
|---|---|
| SHGetKnownFolderPath(), KNOWNFOLDERID (0) | 2011/11/02 |
| Shield from thread injection (0) | 2011/10/25 |
| URL Protocol View (0) | 2011/07/12 |
| 드라이브 체크 코드 - A:\ or Floppy Drive Not found 오류 , SetErrorMode (0) | 2011/01/07 |
| SetErrorMode - 윈도우 오류 핸들링 (0) | 2011/01/07 |
opcode0x90.zip