Anti-Revering Techniques
Transcript of Anti-Revering Techniques
Anti-Revering Techniques
http://zer0day.tistory.com
๊น ํ ์ฐฌ
2016/9/29
Contents 1. Introduction ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 3
1.1 Reversing ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 3
1.2 Anti Reversing ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 3
2. Anti-Debugging ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 4 2.1 Based on API Calls ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 4
2.2 Based on Windows Internals ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 9
2.3 Based on Exception ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 16
2.4 Based on Break Points ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 21
2.5 Based on Flags ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 22
2.6 Based on VM Detection ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 26
2.7 Based on Timing ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 37
2.8 Based on Checksums ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 38
2.9 Etc ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 39
3. Anti-Disassembly ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 41 3.1 Code Obfuscating ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 41
3.2 Packing ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 43
3.3 Anti Dumping ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 44
3.4 Etc ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 47
4. Conclusion ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 50
5. Reference ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท 51
1. Introduction ์ด๋ฒ ๋ฌธ์์์๋ ์ํฐ ๋ฆฌ๋ฒ์ฑ ๊ธฐ๋ฒ์ ๋ํ ์ ๋ฐ์ ์ธ ๋ด์ฉ์ ๊ฐ๋ตํ๊ฒ ๋ค๋ค๋ณผ ๊ฒ์ด๋ค.
์ด์ ๋ํ ์ธ๋ถ์ ์ธ ๋ด์ฉ์ ์ธํฐ๋ท ๋ฑ์ ์ฝ๊ฒ ๊ฒ์์ผ๋ก ์ฐพ์ ์ ์๊ธฐ ๋๋ฌธ์ ์์ธํ
์ค๋ช ์ ์๋ตํ๊ฒ ๋ค.
1.1. Reversing
์ฐ๋ฆฌ๊ฐ ํํ ๋งํ๋ Reversing ์ Reverse Engineering ์ ๊ฐ๋ตํ๊ฒ ์ค์ฌ ๋งํ๋ ๊ฑฐ๋ค.
Reversing ์ด๋ ๊ทธ ๋ป ๊ทธ๋๋ก ์ญ์ผ๋ก ๋ถ์์ ํ๋ ๊ฑฐ๋ค. ์ฐ๋ฆฌ๊ฐ ์ฃผ๋ก ํ๊ฒ์ผ๋ก ํ๋
๋ฆฌ๋ฒ์ฑ ๋์์ .dll, .exe, .sys ํ์ผ ๋ฑ์ด ๋๊ฒ ๊ณ ์ด๋ฌํ ์คํ ํ์ผ๋ค์ ๋์์ผ๋ก
์ฐ๋ฆฌ๋ ์์ ์ฝ๋๋ค์ ๋ถ์ํด์ ํ๋ก๊ทธ๋จ์ด ์ด๋ค ์ญํ ์ ํ๋์ง ์์๋ด๋ ์์ ์ ํ๋ค.
๋ฌผ๋ก ๋ถ์์ ์ํด์ ํด๋น ํ์ผ๋ง๋ค ๋ค๋ฅธ ์ธ์ด, ๋ค๋ฅธ ์ํคํ ์ณ์์ ์์ฑ ๋์์ผ๋ ๊ฐ
assembly ์ธ์ด๋ ์ ์๊ณ ์์ด์ผ ํ๋ค.
1.2. Anti Reversing
์ด๋ฒ์ ์ค์ ์ ์ผ๋ก ๋ค๋ฃฐ Anti-Reversing ์ด๋ ์ฃผ์ ๋ ๊ฐ๋ตํ๊ฒ ๋งํด์ ํ๋ก๊ทธ๋จ์ ๋ถ์ํ
์์ ๋ถ์ํ๋ ์ฌ๋์ด ๋ถ์์ ์ด๋ ต๊ฒ ๋ง๋๋ ์์ ์ ๋งํ๋ค. ์๋ฅผ ๋ค์ด ์ฝ๋๋ฅผ ๋๋ ํ ํด
๋๊ฑฐ๋ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฅ์ ๋ฃ์ด ๋๋ฒ๊น ์ด ์ด๋ ต๊ฒ ๋ง๋ค ๋๊ฐ. ๊ทธ๋์ ์ฃผ๋ก ์ด๋ฐ ๊ธฐ๋ฒ๋ค์
์์ฉ ๊ฒ์์ด๋ ์์ ๋ฐ ๋ ธ๋(DRM), ์ ์ฑ์ฝ๋ ๋ฑ์ ์ฌ์ฉ๋์ด ๋ถ์์ด ๋๋ ๊ฒ์ ์ต๋ํ
๋ฐฉ์งํ๋ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ค. ํ์ง๋ง ํ๋์๋ ์ด๋ฌํ ๊ธฐ๋ฒ๋ค์ด๋ ๊ธฐ์ ๋ค์ด ๋๋ถ๋ถ ์๋ ค์ ธ
์๊ณ ๋ถ์ํ๋ ํด์ด ์ข์์ง๊ณ ๋ถ์๊ฐ์ ์ค๋ ฅ์ด ๋๋ ์ด ๋์์ ธ ์๋ฌด๋ฆฌ ๊ฒฌ๊ณ ํ๊ฒ ๋ง๋ค์ด๋
ํฌ๋์ด ๋๊ธฐ ๋๋ฆ์ด๋ค. ๊ทธ๋์ ํ๋์ ์ํฐ ๋ฆฌ๋ฒ์ฑ ๊ธฐ๋ฒ์ ๋ชฉ์ ์ โ๋ซ๋ฆฌ์ง ์์ ์ฅ์นโ ๊ฐ
์๋ โ์ต๋ํ ๋ถ์์ ์ง์ฐ์ํค๋โ ์ฅ์น๋ก ์ฌ์ฉ๋๋ค. ์ด๋ฒ ๋ฌธ์์์ ๋ค๋ฃฐ ๊ธฐ๋ฒ๋ค์ ์
์๋ ค์ ธ ์๋ ์ํฐ ๋ฆฌ๋ฒ์ฑ ๊ธฐ๋ฒ๋ถํฐ ์ ์๋ ค์ง์ง ์์ ๊ธฐ๋ฒ์ด๋ ์ ์ฑ์ฝ๋์์ ์ฌ์ฉ๋๊ณ
์๋ ์ํฐ ๋ฆฌ๋ฒ์ฑ ๊ธฐ๋ฒ ๋ฑ๊น์ง ๊ฐ๋ตํ๊ฒ ๋ค๋ค ๋ณผ ์์ ์ด๋ค. ๊ธฐ๋ฒ ์ค๋ช ์ ๋ค์ด๊ฐ๊ธฐ ์์์
ํฌ๊ฒ 2 ๋ถ์ผ๋ก ๋๋ ๋ณด์๋ฉด ์ํฐ ๋๋ฒ๊น ๊ณผ ์ํฐ ๋ฆฌ๋ฒ์ฑ์ธ๋ฐ, ์ํฐ ๋๋ฒ๊น ์์ ๋๋ฒ๊ฑฐ๋ฅผ
๋์์ผ๋ก ํ์งํ๋ ๋ฐฉ๋ฒ๋ถํฐ ์์ฆ ์ฃผ๋ก ๋ถ์ ํ๊ฒฝ์ธ VM ์ด๋ Sandbox ์์์์ ํ์ง
๊ธฐ๋ฒ๊น์ง ์์๋ณผ ๊ฒ์ด๋ค. ์ํฐ ์ด์ ๋ธ๋ฆฌ ํํธ ์์๋ ์ฝ๋ ๋๋ ํ์ ์ฌ๋ฌ ๋ฐฉ๋ฒ๋ถํฐ ์ํฐ
๋คํ๊น์ง ์์๋ณผ ๊ฒ์ด๋ค.
2. Anti-Debugging ์๋์ฒ๋ผ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ์ ํฌ๊ฒ 7 ๊ฐ์ง๋ก ๋ถ๋ฅํด ๋ดค๋ค. ์๋ ๊ธฐ๋ฒ๋ค์ ์๋์ฐ
๋ฐ์ด๋๋ฆฌ๋ฅผ ๋์์ผ๋ก ํ ๊ธฐ๋ฒ๋ค์ด๋ค. ๋ฌผ๋ก ํน์ ์๋์ฐ ๋ฒ์ (ex) Vista, NT ๊ณ์ด์ด ์๋
Windows)์ด๋ ์ํคํ ์ณ(x86, x64)์ ์ฐจ์ด๊ฐ ๋ ์ ์์์ ๋ช ์ํ๋ค.
2.1. Based on API Calls A) CheckRemoteDebuggerPresent
์ด๋ฒ ํจ์๋ IsDebuggerPresent ํจ์์ ๋์ผํ ์ญํ ์ ํ๋๋ฐ ๋ค๋ฅธ ์ ์ ํ์ฌ ์์ ์
๊ธฐ์ค์ผ๋ก ๊ฐ์ ๋ถ๋ฌ์ค๋ ์ ์ด๋ค. ์ฆ, ํธ์ถ ๋ ๋๋ง๋ค ๊ฐ์ ์ป์ด ์ค๊ธฐ ๋๋ฌธ์
IsDebuggerPresent ์ ๋ฌ๋ฆฌ BeingDebugged ๊ฐ์ด ์๋์ผ๋ก ๋ฐ๊ฟ ํ์ง๋ฅผ ๋ชปํ๋ ๊ฒ์ ๋ํ
๋ฌธ์ ๋ ์์ด์ง๋ค.
๊ตฌํ์ ํด ๋ณด์๋ฉด ์๋์ ๊ฐ๋ค.
void main() { BOOL Debugged; CheckRemoteDebuggerPresent(GetCurrentProcess(), &Debugged); if (Debugged) printf("Debugged\n"); }
B) FindWindow
๋ค์ API ๋ ํ์ฌ ์คํ๋์ด ์๋ ์๋์ฐ ์ฐฝ์ ํ์ดํ ๋ช ์ผ๋ก ๊ฒ์์ ํ๋ ํจ์์ด๋ค. ์ฆ.
์ด ํจ์๋ก ํ์ฌ ์คํ๋์ด ์๋ ๋๋ฒ๊ฑฐ์ ํ์ดํ ๋ช (ex) OLLYDBG, MyDEBUG, IDA, etcโฆ)
์ผ๋ก ๊ฒ์์ ํด ๋ง์ฝ ์์ผ๋ฉด ๋๋ฒ๊ฑฐ ์ฌ์ฉ ์ค์ด๋ผ ํ์ง๋ฅผ ํ๋ ๋ฐฉ์์ด๋ค.
๊ตฌํ์ ํด ๋ณด์๋ฉด ์๋์ ๊ฐ๋ค.
void main() { HWND ck = FindWindow(L"MyDEBUG", 0); if (ck != NULL) printf("Debugged"); }
C) OpenProcess
ํด๋น ๊ธฐ๋ฒ์ OpenProcess ํจ์๋ก csrss.exe ๋ฅผ PROCESS_ALL_ACCESS ๊ถํ์ผ๋ก ์คํํด
๋ง์ฝ ์คํจํ๋ฉด ๋๋ฒ๊น ์ค์ด ์๋ ๊ฒ์ด๊ณ ์ฑ๊ณตํ๋ฉด ๋๋ฒ๊น ์ค์ธ ๊ฒ์ด๋ค. ์๋ํ๋ฉด
์ผ๋ฐ์ ์ธ ์คํ ๋๋ ํด๋น ๊ถํ์ผ๋ก ์คํ์ ํ ์ ์์ง๋ง ๋๋ฒ๊น ์์๋ ์ด๋ฏธ ํด๋น ๊ถํ์
์ฌ์ฉํด ํ๋ก์ธ์ค๋ฅผ attach ํ๊ฑฐ๋ open ํ๊ธฐ ๋๋ฌธ์ ์ฑ๊ณต์ ์ผ๋ก
PROCESS_ALL_ACCESS ๊ถํ์ผ๋ก ์ด ์ ์๋ค.
๊ตฌํ์ ํด ๋ณด์๋ฉด ์๋์ ๊ฐ๋ค.
void main() { FARPROC proc = GetProcAddress( GetModuleHandle(L"ntdll.dll"), "CsrGetProcessId" ); DWORD PID = proc(); // Get csrss.exe PID HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); if (h != NULL) // If it fails, return 0 printf("Debugged"); }
D) Self-Debugging
์ด ๊ธฐ๋ฒ์ ๊ฐ๋จํ๊ฒ ๋งํ๋ฉด ์๊ธฐ ์์ ์ ๋๋ฒ๊น ํ๋ ๊ธฐ๋ฒ์ผ๋ก, ์์ ํ๋ก์ธ์ค๋ฅผ ๋ง๋ค๊ณ
๊ทธ ํ๋ก์ธ์ค๊ฐ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ฅผ ๋๋ฒ๊น ํ๋ ๋ฐฉ์์ผ๋ก ์ด๋ค์ง๋ค. ํ๋ฒ์ ํ ํ๋ก์ธ์ค๋ฅผ
๋๋ฒ๊น ํ ์ ์๋ ์ฌ์ค์ ์ด์ฉํด ์ธ๋ถ ๋๋ฒ๊ฑฐ๊ฐ ๋๋ฒ๊น ์ ํ์ง ๋ชปํ๊ฒ ํ ์ ์๋ ์ข์
๊ธฐ๋ฒ ์ค ํ๋๋ค. ํ์ง๋ง ์ด ๊ธฐ๋ฒ์ ๋จ์ ์ EPROCESS ๊ตฌ์กฐ์ฒด์ DebugPort ๊ฐ์ 0 ์ผ๋ก
์ค์ ์ ํ๋ฉด ์ฐํ๊ฐ ๊ฐ๋ฅํ๋ค.
๊ตฌํ์ ํด ๋ณด์๋ฉด ์๋์ ๊ฐ๋ค.
void Self_Debugging() { DEBUG_EVENT de; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&de, sizeof(DEBUG_EVENT)); ZeroMemory(&si, sizeof(STARTUPINFO)); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); GetStartupInfo(&si); CreateProcess(NULL, GetCommandLine(), NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi); // Create a Copy of itself
ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, DBG_CONTINUE); // Continue WaitForDebugEvent(&de, INFINITE); } void main() { Self_Debugging(); }
E) OutputDebugString
ํด๋น API ๋ ๋ง์ฝ debugging ์ค์ด๋ฉด ์ฑ๊ณต์ ์ผ๋ก ๋ฌธ์์ด์ ์ถ๋ ฅํ๊ณ ๋ง์ฝ ์๋๋ฉด
์๋ฌ์ฝ๋๋ฅผ ๋ฐ์์ํจ๋ค. (์ถ๋ ฅ์ ํ ๋ ๋ด๋ถ์ ์ผ๋ก DbgPrint ์ฌ์ฉ). ์ฆ ์ฌ์ฉ ํ์ ์
์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์ผ๋ฉด ๋๋ฒ๊น ์ค์ด๋ผ๋ ๋ป์ด๋ค. ์ฐธ๊ณ ๋ก OllyDbg ํจ์น๊ฐ ์ ์ฉ๋์ง ์์
๊ตฌ ๋ฒ์ ์์ %s ๊ฐ์ด ์ฌ๋ฌ ๊ฐ์ ํฌ๋งท์คํธ๋ง์ OutputDebugString ์ผ๋ก ๊ฑด๋ค ์ฃผ๊ฒ ๋๋ฉด
crash ๊ฐ ๋๋ ํ์์ด ๋ฐ์ํฉ๋๋ค.
์ด๋ฒ์ ์์ ์ฝ๋๊ฐ ์งง์์ ๊ฐ๋จํ๊ฒ SEH ๋ ์ถ๊ฐํด์ ๊พธ๋ฉฐ ๋ณด์๋ค. ๋ฌผ๋ก GetLastError
ํจ์๋ฅผ ์ฌ์ฉํด ๊ฐ์ด 0 ์ผ ๋๋ฅผ ๋น๊ตํด ๋๋ฒ๊น ์ค์ด๋ผ๋ ๊ฑธ ํ๋ณ ํ ์๋ ์๋ค.
void main() { __try { OutputDebugStringW(L"asdf"); __asm { mov ebx, [eax] } // EAX would be 0 or 1 // Windows XP, 10 -> 1, 7 -> 0 printf("Debugged"); } __except (EXCEPTION_EXECUTE_HANDLER) { ; } }
[+] ํ๋ OutputDebugString ํจ์ ์ํ์ ๋ํด ์ฌ๋ฏธ์๋ ์ ์ ๋ฐ๊ฒฌํ ์ ์์๋๋ฐ. ์ด์
๋ฒ์ ์ outputDebugString ํจ์ ์ํ์ ์๋์ ๊ฐ์๋ค.
void WINAPI OutputDebugStringA(LPCSTR lpOutputString) { ULONG_PTR args[2]; args[0] = (ULONG_PTR)strlen(lpOutputString) + 1; args[1] = (ULONG_PTR)lpOutputString; __try { RaiseException(0x40010006, 0, 2, args); printf("Debugged"); } __except (EXCEPTION_EXECUTE_HANDLER) {
; } }
์์ธ ์ฒ๋ฆฌ ์ฝ๋๊ฐ DBG_PRINTEXCEPTION_C(0x4001006) ์๋๋ฐ ์ด๊ฒ Windows 10 ์ผ๋ก
๋์ด์ค๋ฉด์ ์์ธ ์ฒ๋ฆฌ ์ฝ๋๊ฐ ์๋ก์ด ๊ฒ ์๊ฒผ๋ค.
void WINAPI _OutputDebugString(LPCWSTR lpOutputString) { char outputDebugStringBuffer[1000] = { 0, }; ULONG_PTR args[4]; WideCharToMultiByte(CP_ACP, 0, lpOutputString, -1, outputDebugStringBuffer, sizeof(outputDebugStringBuffer), 0, 0); // Unicode args[0] = (ULONG_PTR)wcslen(lpOutputString) + 1; args[1] = (ULONG_PTR)lpOutputString; //Ansi for compatibility args[2] = (ULONG_PTR)wcslen(lpOutputString) + 1; args[3] = (ULONG_PTR)outputDebugStringBuffer; __try { RaiseException(0x4001000A, 0, 4, args); printf("Debugged"); } __except (EXCEPTION_EXECUTE_HANDLER) { ; } }
DBG_PRINTEXCEPTION_WIDE_C(0x4001000a)๊ฐ ์๋ก ์๊ฒผ๋ค. ๋ํ Unicode ์ด์ธ์ ANSI
๋ฒ์ ์ ๋ํ ๊ฐ๋ ์์ฒญ์ ํ๋ค.
F) BlockInput
์๋ง ์ง๊ธ๊น์ง ๋ณธ ํจ์ ์ค์์ ์ฌ์ฉ๋ฒ์ด ์ ์ผ ๊ฐ๋จํ ๊ธฐ๋ฒ์ธ ๊ฑฐ ๊ฐ๋ค. ์ด ํจ์๋ ๋จ์ํ
ํค๋ณด๋๋ ๋ง์ฐ์ค์์ ๋ฐ์๋ ์ด๋ฒคํธ ๋ค์ ๋ง์์ฃผ๋ ์ญํ ์ ํ๋ค. ์ธ์ ๊ฐ์ผ๋ก 1 ์ ๋ฃ๊ฒ
๋๋ฉด block ๋ชจ๋๊ฐ ๋๊ณ 0 ์ ๋ฃ์ผ๋ฉด unblock ๋ชจ๋๊ฐ ๋๋ค. ํ์ง๋ง Ctrl + Alt +
Delete ๋ฅผ ๋๋ฅด๋ฉด ์ฐํ๊ฐ ๊ฐ๋จํ ๋๋ค.
์ฌ์ฉ๋ฒ์ ์๋์ ๊ฐ๋ค.
BlockInput(1); // block
BlockInput(0); // unblock
G) DeleteFiber
ํด๋น API ๋ Fiber ์ ๊ด๋ จ๋ ๋ชจ๋ ์ ๋ณด๋ฅผ ์ง์ฐ๋ ํจ์์ด๋ค. ๊ทธ ๋ชจ๋ ์ ๋ณด์๋ ๋ฌผ๋ก
์คํ ๋ด, ๋ ์ง์คํฐ์ ์ผ๋ถ๋ถ, ํผ๋ฒ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ค. ํน์ง์ผ๋ก ๋๋ฒ๊น ์ค์ ํจ์ ์ฌ์ฉ
์ ์๋ฌ ๋ฐํ ๊ฐ์ด 0x57 ์ด ์๋ ๊ฐ์ด ๋๋ค. ์ด๊ฑธ ์ด์ฉํด์ ํ์ง๊ฐ ๊ฐ๋ฅํ๋ค.
๋ด๋ถ์ ์ผ๋ก ํด๋น ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
MOV EAX,DWORD PTR FS:[18] // TEB Structure
MOV ECX,DWORD PTR DS:[EAX+10] // Access TIB Structure -> FiberData Area
MOV ESI,DWORD PTR SS:[EBP+8] // lpFiber Value
CMP ECX,ESI // compare lpFiber & FiberData
ํ์ NtFreeVirtualMemory ๋ฅผ ์ฌ์ฉํด stack ์ ๋น์์ฃผ๊ณ ExitThread ๋ก ํจ์๋ฅผ
์ข ๋ฃํ๋ค.
๊ตฌํ์ ํด ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
void main() { char fiber[1024] = { 0, }; DeleteFiber(fiber); if (GetLastError() != 0x57) printf("Debugged"); }
H) LDR
์ด๋ฒ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ์ผ๋ก๋ PEB ๊ตฌ์กฐ์ฒด์ 12 ๋ฒ์งธ์ ์๋ Ldr ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์ฉํด์
๋๋ฒ๊น ์ ํ์ง ํ ์ ์๋ค. ๋๋ฒ๊น ๋นํ๋ ํ๋ก์ธ์ค๋ Heap ๋ฉ๋ชจ๋ฆฌ์ ์์ ์ด ๋๋ฒ๊น
๋นํ๋ ํ๋ก์ธ์ค๋ค ๋ผ๋ ํ์๋ก ์ฌ์ฉ๋์ง ์์ Heap ์์ญ์ 0xfeeefeee ์ 0xabababab
๊ฐ์ผ๋ก ์ฑ์ด๋ค. ์ด Heap ์ฃผ์๊ฐ Ldr ์ ์ ์ฅ์ด ๋๊ณ , ํด๋น ์ฃผ์๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ ๊ฐ์
๋ฐ์ดํฐ๋ค์ ๊ฒ์ํด ๋๋ฒ๊น ์ ํ์ง ํ ์ ์๋ค.
- PEB Structure
- typedef struct _PEB {
- BYTE Reserved1[2];
- BYTE BeingDebugged;
- ...
- Struct _PEB_LDR_DATA * Lrd; // PEB+0xC
- } PEB, *PPEB;
๊ตฌํ์ ํด ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
void main() { FARPROC proc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCurrentTeb"); UINT teb = (UINT)proc(); // TEB Address UINT peb = *(UINT *)(teb + 0x30); // PEB Address UINT ldr = *(UINT *)(peb + 0xC); // PEB+0xC -> Ldr __try { for (int i = 0; ; ++i) { if (*(UINT *)(ldr + i) == 0xfeeefeee || *(UINT *)(ldr + i) == 0xabababab) printf("Debugged"); } } __except (EXCEPTION_EXECUTE_HANDLER) { ; } }
2.2. Based on Windows Internals A) NtQueryObject
๋จผ์ NtQueyrObject ํจ์๋ Debug Object ์ ๋ฆฌ์คํธ๋ฅผ ๋ฝ์์ค๋ ์ญํ ์ ํ๋ ํจ์์ด๋ค.
Debug Object ๋ XP ๋ ์ฒ์ ๋ํ๋ฌ์ผ๋ฉฐ ๋๋ฒ๊น ์์ ์ด ๊ฐ์ฒด๊ฐ ์์ฑ์ด ๋๋ค. ์ฆ ํด๋น
ํจ์๋ก ๋ฆฌ์คํธ๋ฅผ ๋ฝ์์์ ์กด์ฌํ๋ ๊ฐ์ฒด์ ๊ฐ์๋ฅผ ์นด์ดํ ํด์ ๋๋ฒ๊น ์ ํ์ง ํ ์๊ฐ
์๋ค. ๊ฐ์ฒด์ ๊ฐ์๊ฐ 1 ๊ฐ์ผ ๋๋ง ๋๋ฒ๊ฑฐ๊ฐ ๋ฐ๊ฒฌ๋์ง ์์ ๋์ด๋ค.
๊ตฌํ์ ํด ๋ณด์๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; typedef struct _OBJECT_TYPE_INFORMATION { UNICODE_STRING TypeName; ULONG TotalNumberOfHandles; ULONG TotalNumberOfObjects; } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; typedef struct _OBJECT_ALL_INFORMATION { ULONG NumberOfObjects;
OBJECT_TYPE_INFORMATION ObjectTypeInformation[1]; } OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION; typedef NTSTATUS(NTAPI *pNtQueryObject)(HANDLE, UINT, PVOID, ULONG, PULONG); void main() { ULONG size = 0; pNtQueryObject nqo = (pNtQueryObject)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtQueryObject"); NTSTATUS stat = nqo(NULL, 3, // ObjectAllTypesInformation &size, 4, &size); PVOID pMemory = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // Get Object List stat = nqo((HANDLE)-1, 3, pMemory, size, NULL); if (stat != 0) { VirtualFree(pMemory, 0, MEM_RELEASE); return; } POBJECT_ALL_INFORMATION pObjectAllInfo = (POBJECT_ALL_INFORMATION)pMemory; PUCHAR pObjInfoLocation = (PUCHAR)pObjectAllInfo->ObjectTypeInformation; ULONG NumObjects = pObjectAllInfo->NumberOfObjects; for (int i = 0; i < NumObjects; ++i) { POBJECT_TYPE_INFORMATION pObjectTypeInfo = (POBJECT_TYPE_INFORMATION)pObjInfoLocation; if (wcscmp(L"DebugObject", pObjectTypeInfo->TypeName.Buffer) == 0) { // Check num of Objects is 1 if (pObjectTypeInfo->TotalNumberOfObjects != 1) printf("Debugged or Debug Tool Found"); } pObjInfoLocation = (PUCHAR)pObjectTypeInfo->TypeName.Buffer; pObjInfoLocation += pObjectTypeInfo->TypeName.Length; ULONG tmp = ((ULONG)pObjInfoLocation) & -4; pObjInfoLocation = ((PUCHAR)tmp) + sizeof(ULONG); } VirtualFree(pMemory, 0, MEM_RELEASE); }
B) NtQuerySystemInformation
ํด๋น ํจ์๋ ํ์ฌ ์ด์์ฒด์ ์ ์ ๋ณด๋ค์ ๊ฐ์ ธ์ค๋ ํจ์๋ก ์ฃผ๋ก ์ด์์ฒด์ ๊ฐ ๋๋ฒ๊ทธ ๋ชจ๋๋ก
๋ถํ ๋ฌ๋์ง ์ ๋ฌ๋์ง๋ฅผ ํ๋ณํ๋ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ์ผ๋ก ์ฃผ๋ก ์ฌ์ฉ๋๋ค. ํด๋น ํด๋์ค์
์กด์ฌํ๋ 35 ๋ฒ์งธ์ ์กด์ฌํ๋ SystemKernelDebuggerInformation(0x23)์ ์ฌ์ฉํ๋ฉด
SYSTEM_KERNEL_DEBUGGER_INFORMATION ๊ตฌ์กฐ์ฒด์ DebuggerEnabled ๊ฐ์ด ์ธ์ง๋ฅผ ํ์ธ
ํ๋ค. ๋ฐํ ๊ฐ์ผ๋ก EAX ์ ๊ฐ์ด ๋ฐํ๋๋๋ฐ al ์ KdDebuggerEnabled ๊ฐ์ด ๋ค์ด๊ฐ๊ณ , ah
์ KdDebuggerNotPresent ๊ฐ์ด ๋ค์ด๊ฐ๋ค. ์ฆ ah ์ 0 ์ด ๋ค์ด๊ฐ ์์ผ๋ฉด ๋๋ฒ๊น ์ค์ด๋ผ๋
๋ป์ด๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION { BOOLEAN KdDebuggerEnabled; BOOLEAN KdDebuggerNotPresent; } SYSTEM_KERNEL_DEBUGGER_INFORMATION; typedef NTSTATUS(WINAPI *ntqsi)(ULONG, PVOID, ULONG, PULONG); void main() { SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi; ntqsi qsi = (ntqsi)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation"); qsi(0x23, // SystemKernelDebuggerInformation &skdi, 2, NULL); if (skdi.KdDebuggerEnabled && !skdi.KdDebuggerNotPresent) printf("Debugged"); }
C) NtSetInformationThread
Windows 2000 ์ฏค์ ์ํฐ ๋๋ฒ๊น ์ ๋ชฉ์ ์ผ๋ก ๋ง๋ค์ด์ง(?) class ๊ฐ ์์๋๋ฐ ๊ทธ๊ฒ์ด ๋ฐ๋ก
NtQueryInformationThread ๋ค. ์ด๋ฒ์ ๋ค๋ค ๋ณผ ๊ฒ์ ThreadInformationClas ์
์กด์ฌํ๋ 17 ๋ฒ์งธ ๋ฉค๋ฒ์ธ ThreadHideFromDebugger ์ด๋ค. ํด๋น ๋ฉค๋ฒ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด
ํ๋ก๊ทธ๋จ์ด ๊ณ์ ์คํ์ด ๋๋ ๋๋ฒ๊ฑฐ๋ ํด๋น Thread ๋ก๋ถํฐ ์ด๋ ์ด๋ฒคํธ๋ ๋ฐ์ง ์๊ฒ
์ผ์ข ์ ์๋์ ํ ์ ์๊ฒ ๋๋ค.
๊ตฌํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
typedef NTSTATUS(NTAPI *ntsit)(HANDLE, UINT, PVOID, ULONG); void main() { ntsit sit = (ntsit)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtSetInformationThread"); NTSTATUS stat = sit(GetCurrentThread(), 0x11, // ThreadHideFromDebugger 0, 0); if (stat == 0) printf("Hide"); }
๋ฌผ๋ก GetCurrentThread ๋ก ํ์ฌ Thread ๋ฅผ ๋ฃ๋ ๋์ ์์ ์ด ๋ฃ๊ณ ์ถ์ Thread ๋ฅผ
๋ฃ์ด๋ ๋๋ค.
D) NtSetDebugFilterState
์ด ํจ์๋ ๋๋ฒ๊ทธ ํํฐ๋ฅผ ์์ ํ๋ ํจ์์ธ๋ฐ, ๋๋ฒ๊น ์์๋ ์ด ํํฐ ๊ฐ ๋ณ๊ฒฝ์ด
๋ถ๊ฐ๋ฅํ ์ ์ ์ด์ฉํด ๋๋ฒ๊ฑฐ๋ฅผ ํ์งํ ์ ์๋ค. ๋ง์ฝ ๋๋ฒ๊น ์ค ์์ ํ๋ ค๊ณ ํ๋ฉด
STATUS_ACCESS_DENIED(0xc0000022)์์ธ๊ฐ ๋ฐ์ํ๋ค. ๋จ์ ์ผ๋ก๋ ์ด ๊ธฐ๋ฒ์ผ๋ก๋
ํ๋ก์ธ์ค๊ฐ ๋๋ฒ๊ฑฐ์ attach ๋ ๊ฒฝ์ฐ์๋ง ํ์ง๊ฐ ๊ฐ๋ฅํ๋ค๋ ์ ์ด๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
typedef NTSTATUS(WINAPI *ntsdfs)(ULONG, ULONG, BOOLEAN); void main() { ntsdfs sdfs = (ntsdfs)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtSetDebugFilterState"); NTSTATUS stat = sdfs(0, 0, TRUE); if (stat == 0) printf("Debugged"); }
E) NtQueryInformationProcess
์ด๋ฒ์ ์๊ฐ ํ ํจ์๋ก๋ ํฌ๊ฒ 4 ๊ฐ์ง๋ฅผ ์ด์ฉํด ์ํฐ ๋๋ฒ๊น ์ ๊ตฌํ ํ ์ ์๋ค.
- ProcessBasicInformation(0x0)
ํด๋น ๊ธฐ๋ฒ์ ์ฝ๊ฐ Aggressive ํ ๊ธฐ๋ฒ์ธ๋ฐ, ๊ธฐ๋ณธ์ ์ผ๋ก ์๋์ฐ ์์์ ํ๋ก๊ทธ๋จ์
์คํํ๊ฒ ๋๋ฉด ์์ ํ๋ก์ธ์ค๋ค(์คํ ํ๋ก๊ทธ๋จ)๋ค์ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ explorer.exe ๋ค.
(๋ฌผ๋ก ์๋ ๊ฒฝ์ฐ๋ ์์). ์ด๋ฅผ ์ด์ฉํด ๋๋ฒ๊น ์์๋ ๋๋ฒ๊ฑฐ ํ๋ก์ธ์ค์ ์์์ผ๋ก
attach ํ๋๊น ํ์ฌ ์์ ์ ๋ถ๋ชจ ํ๋ก์ธ์ค PID ๋ฅผ explorer.exe ํ๊ณ ๋น๊ตํ๋ ๊ธฐ๋ฒ์ด๋ค.
ํด๋น ์ธ์๋ก NtQueryInformationProcess ๋ฅผ ์คํํ๊ฒ ๋๋ฉด ๋ฆฌํด ๊ฐ์ผ๋ก
PROCESS_BASIC_INFORMATION ๊ตฌ์กฐ์ฒด๊ฐ ๋ฆฌํด ๋๋๋ฐ, ํด๋น ๊ตฌ์กฐ์ฒด์์
typedef struct _PROCESS_BASIC_INFORMATION { NTSTATUS ExitStatus; PVOID PebBaseAddress; PVOID AffinityMask; PVOID BasePriority; ULONG_PTR UniqueProcessId; ULONG_PTR ParentProcessId; } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
์ฃผ์ ๊น๊ฒ ๋ณผ ๊ฑด ๋ง์ง๋ง ๋ฉค๋ฒ์ธ InheritedFromUniqueProcessId ๋ค. ํด๋น ๋ฉค๋ฒ์ ๋ถ๋ชจ
ํ๋ก์ธ์ค์ pid ๊ฐ ๋ด๊ฒจ์๋ค. ์ด ๊ฐ๊ณผ explorer.exe pid ๋ฅผ ๋น๊ตํด ๋ง์ฝ ํ๋ฆฌ๋ฉด ๋๋ฒ๊น
์ค์ด๋ผ ํ๋จ ํ ์ ์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
typedef struct _PROCESS_BASIC_INFORMATION { NTSTATUS ExitStatus; PVOID PebBaseAddress; PVOID AffinityMask; PVOID BasePriority; ULONG_PTR UniqueProcessId; ULONG_PTR ParentProcessId; } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; typedef NTSTATUS(WINAPI *qip)(HANDLE, UINT, PVOID, ULONG, PULONG); DWORD ExplorerPID() { DWORD pid = 0; GetWindowThreadProcessId(GetShellWindow(), &pid); return pid; } DWORD ParentProcessPID() { PROCESS_BASIC_INFORMATION pbi;
ZeroMemory(&pbi, 24); qip proc = (qip)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess" ); NTSTATUS stat = proc(GetCurrentProcess(), 0, // ProocessBasicInformation &pbi, 24, 0); if (stat == 0) return pbi.ParentProcessId; return 0; } BOOL IsParentExplorerExe() { return ParentProcessPID() == ExplorerPID(); } void main() { if (!IsParentExplorerExe()) printf("Debugged"); }
- ProcessDebugPort(0x7)
์ด ๊ธฐ๋ฒ์ ์ด๋ฏธ ๊ฐ์ ์ ์ผ๋ก ํ๋ฒ ์ ํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์์์ ์์ธํ ์ค๋ช ์ ์ ํ์ง๋ง,
CheckRemoteDebuggerPresent ํจ์ ๋ด๋ถ๋ฅผ ๋ถ์ํ๋ฉด ๋ด๋ถ์ ์ผ๋ก
NtQueryInformationProcess ๋ฅผ ์ฌ์ฉํด Debug Port ๋ฅผ ํ์ธํ๋ ์ฝ๋๊ฐ ์๋ค.
ํ๋ก์ธ์ค๊ฐ ๋๋ฒ๊น ์ค์ผ ๋ Debug Port ๊ฐ ํ ๋น๋๊ฒ ๋๋๋ฐ ๋ง์ฝ ๋๋ฒ๊น ์ค์ด๋ผ๋ฉด -1 ์
์ฃผ๊ณ ๋๋ฒ๊น ์ค์ด ์๋๋ฉด 0 ์ ๋ฐํํ๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
typedef NTSTATUS(WINAPI *ntqip)(HANDLE, UINT, PVOID, ULONG, PULONG); void main() {
DWORD flag; ntqip qip = (ntqip)GetProcAddress(
GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess");
NTSTATUS stat = qip(GetCurrentProcess(),
0x7, // DebugPort &flag, 4, NULL);
if (stat == 0 && flag == -1)
printf("Debugged"); }
- ProcessDebugObjectHandle(0x1e)
Windows XP ๋ถํฐ, ์ด๋ค ํ๋ก๊ทธ๋จ์ด ๋๋ฒ๊น ์ด ๋๋ฉด ๋๋ฒ๊น ์ธ์ ์ด ์์ฑ๋๊ณ ๊ทธ ๊ฐ์ฒด์
๋ํ ํธ๋ค๋ ์์ฑ๋์๋ค. ๋ฌผ๋ก ๊ทธ ํธ๋ค์ ๋๋ฒ๊น ์ด ๋๊ณ ์๋ค๋ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ค. ์ฆ,
NtQueryInformationProcess ํจ์๋ฅผ ์ฌ์ฉํด ๊ทธ ๊ฐ์ฒด์ ์ ๊ทผ ํด ํธ๋ค ์ ๋ณด๋ฅผ ๋ฐ์์
๋๋ฒ๊น ์ ํ์ง ํด ๋ผ ์ ์๋ค. 0x1e ๋ฒ์งธ ๋ฉค๋ฒ๋ฅผ ๋ณด๋ฉด ProcessDebugObjectHandl ์ด๋
๊ฒ์ ์ฌ์ฉํ๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
typedef NTSTATUS(WINAPI *ntqip)(HANDLE, UINT, PVOID, ULONG, PULONG); void main() {
HANDLE h; ntqip qip = (ntqip)GetProcAddress(
GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess");
NTSTATUS stat = qip(GetCurrentProcess(),
0x1e, // ProcessDebugObjectHandle &h, 4, NULL);
if (stat == 0 && h) printf("Debugged");
}
- ProcessDebugFlags(0x1f)
๋ค์์ ProcessDebugFlags ๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ฒ์ด๋ค. 3 ๋ฒ์งธ ์ธ์์ EPROCESS ๊ตฌ์กฐ์ฒด์
NoDebugInherit ๊ฐ์ ์ญ์ธ ๊ฐ์ ๋ฐํํ๋ค. ์ฆ ๋ฆฌํด ๊ฐ์ด 0 ์ด๋ฉด ๋๋ฒ๊น ์ค ์ธ ๊ฒ์ด๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
typedef NTSTATUS(WINAPI *ntqip)(HANDLE, UINT, PVOID, ULONG, PULONG); void main() { DWORD nodebug; ntqip qip = (ntqip)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess"); NTSTATUS stat = qip(GetCurrentProcess(), 0x1f, // ProcessDebugFlags &nodebug, 4, NULL); if (stat == 0 && !nodebug) printf("Debugged"); }
2.3. Based on Exception A) UnHandledExceptionFilter
์์ธ๊ฐ ๋ฐ์ํ์ ๋ ๋ฑ๋ก๋ ์์ธ ์ฒ๋ฆฌ ๋ฌธ ์ด๋ SEH Chain ์ด ์๋ค๋ฉด ์ตํ์
๋ณด๋ฃจ(?)๋ก UnHandledExceptionFilter ํจ์๊ฐ ์คํ์ด ๋๋ค. ํ๋ง๋๋ก Top Level ์์ธ
์ฒ๋ฆฌ ์ฅ์น๋ค. ๋ง์ฝ ๋๋ฒ๊ฑฐ๊ฐ attach ๋๋ฉด ๋ค๋ฅธ ์์ธ ํธ๋ค๋ฌ์ ๋ค๋ฅด๊ฒ ๊ณ์ ์คํ๋์ง ์๊ณ
๋ฐ๋ก ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํ๋ค. ๊ทธ ๋๋ฒ๊ฑฐ๋ฅผ ํ์งํ ๋๋ ๋ด๋ถ์ ์ผ๋ก
NtQueryInformationProcess ํจ์์ ProcessDebugPort ๊ฐ ์ฌ์ฉ๋๋ค.
Divide by zero ๋ฅผ ์์๋ก ๊ตฌํ์ ํด ๋ณด๋ฉด
LONG WINAPI UnhandledExcepFilter(PEXCEPTION_POINTERS pExcepPointers) { SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) pExcepPointers->ContextRecord->Eax); pExcepPointers->ContextRecord->Eip += 2; // Skip Exception Codes return EXCEPTION_CONTINUE_EXECUTION; } int main() { SetUnhandledExceptionFilter(UnhandledExcepFilter); __asm {xor eax, eax} __asm {div eax} // Divide by zero printf("Not Debugged"); }
B) CloseHandle
ํด๋น ํจ์๋ ํ์์๋ ๋ง์ด ์ฌ์ฉํ๋ฏ์ด ์ฌ์ฉ๋ ํธ๋ค์ ์ข ๋ฃํ๋ ํจ์์ด๋ค. ํ์ง๋ง
์์ฑ๋์ง ์์ ํธ๋ค์ ์ข ๋ฃํ๊ฒ ํจ์ผ๋ก ์์ธ๋ฅผ ๋ฐ์์์ผ ๋๋ฒ๊ฑฐ๋ฅผ ํ์งํด ๋ผ ์ ์๋ค.
์ผ๋ฐ์ ์ผ๋ก ์คํ์ ํ๋ฉด ์์ธ ๋ฐ์ ์์ด ์ง๋๊ฐ์ง๋ง ๋๋ฒ๊ฑฐ๊ฐ ์กด์ฌํ ์์๋
EXCEPTION_INVALID_HANDLE(0xc0000008)์ด ๋ฐ์ํ๊ฒ ๋๋ค. ์ฐธ๊ณ ๋ก x64 ์ด์์ฒด์ ์์๋
EXCEPTION_HANDLE_NOT_CLOSABLE(0xc0000235)๊ฐ ๋ฐ์ํ๋ค.
๊ตฌํ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
void main() { __try { CloseHandle((HANDLE)0x12345678); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("Debugged");
} }
C) INT 3
INT 3 ์ธ์คํธ๋ญ์ ์ Software Break Point ๋ก ์ฐ๋ฆฌ๊ฐ ๋ง์ด ์ฌ์ฉํ๋ break point ์ค
ํ๋๋ค. ๋ง์ฝ ๋๋ฒ๊น ์ค์ด๋ผ๋ฉด ์ด ์ธ์คํธ๋ญ์ ์ด ์คํ๋ ๋ break point ๊ฐ ํธ๋ฆฌ๊ฑฐ ๋๋ฉด์
์์ฐ์ค๋ฝ๊ฒ BP ๋ก ์ธ์ํด ๋์ด๊ฐ๊ฒ ๋์ง๋ง ์๋ ๋๋ STATUS_BREAKPOINT(0x80000003)
์์ธ๊ฐ ๋ฐ์ํ๋ฉฐ ์์ธ ๊ตฌ๋ฌธ์ ๊ฑธ๋ฆฌ๊ฒ ๋๋ค.
ํด๋น ๊ตฌํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __try { __asm { int 3 } } __except (EXCEPTION_EXECUTE_HANDLER) { printf("Not Debugged"); } }
D) INT 2D
INT 2d ์ ๋ ํนํ๊ฒ ์คํ์ด ๋ ๋ ์์ธ ์ฃผ์๋ก ํ์ฌ EIP ์ฃผ์๋ฅผ ์ฐ๊ณ 1 ์ ์ฆ๊ฐ์ํจ๋ค.
ํ์ง๋ง EAX ๊ฐ์ 1, 3, 4 ๊ฐ ์์ ๊ฒฝ์ฐ๋ง์ด๋ค(Vista ๋ง 5). ๋ํ ๋๋ฒ๊ฑฐ๊ฐ ์กด์ฌํ ๋
์คํ๋๋ฉด ์์ธ๋ฅผ ๋ฐ์ ์ํค๊ณ ์๋ ๋ ๋ฐ์์ ์ํค์ง ์๋๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __try { __asm { int 0x2d } } __except (EXCEPTION_EXECUTE_HANDLER) { printf("Not Debugged"); } }
E) INT 41
์ด ์ธ์คํธ๋ญ์ ์ ์ปค๋ ๋๋ฒ๊ฑฐ๋ฅผ ํ์งํ ๋ ์ฃผ๋ก ์ฌ์ฉ๋๋ ์ธ์คํธ๋ญ์ ์ด๋ค. ์ฃผ๋ก ์ด
๋ช ๋ น์ ring 3 ๋ชจ๋ ์ฆ ์ ์ ๋ชจ๋์์ ์คํ์ด ์๋๋ ๋ช ๋ น์ด๋ค. ๋ง์ฝ ์คํ์ ํ๊ฒ ๋๋ฉด
int d ๊ฐ ์ํ ๋ EXCEPTION_ACCESS_VIOLATION(0xc0000005)์์ธ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
๊ทธ๋ฐ๋ฐ int 41 ์ ์ฃผ๋ก DPL ๊ฐ์ 0 ์ผ๋ก ๊ฐ์ง๊ณ ์๋๋ฐ ๋ช๋ช ๋๋ฒ๊ฑฐ ๋ค์ ์ด ์ธ์คํธ๋ญ์ ์
ring 3 ๋ชจ๋์์ ์คํํ๊ธฐ ์ํด 3 ์ผ๋ก ๊ฐ์ง๊ณ ์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __try { __asm { int 0x41 } } __except (EXCEPTION_EXECUTE_HANDLER) { printf("Not Debugged"); } }
F) Prefix Handling
Prefix handling ๊ธฐ๋ฒ์ prefix ์ธ์คํธ๋ญ์ ์ ์ฌ์ฉํด ๋๋ฒ๊น ํ ๋๋ prefix rep ๋ช ๋ น์
์๋ต, step over ๊ฐ ๋์ ๊ทธ๋ฅ ๋์ด๊ฐ ์ง๋๋ฐ ๋ค์ 0xf1 ์ธ์คํธ๋ญ์ (ice breakpoint)๋
์๋ต ๋๊ฒ ๋ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ์ SINGLE_STEP_EXCEPTION ์์ธ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค. ์ฐธ๊ณ ๋ก
ICE ๋ In-Circuit-Emulator ์ ์ฝ์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __try { __asm __emit 0xf3 __asm __emit 0x64 // prefix rep __asm __emit 0xf1 // ice break point } __except (EXCEPTION_EXECUTE_HANDLER) { printf("Not Debugged"); } }
G) CMPXCHG8B and LOCK Prefix
LOCK prefix๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผ ๊ถํ์ด ์๋ ํ๋ก์ธ์์ ํน๋ณํ pin์ ํธ๋ฅผ ์ฃผ๊ฒ ๋์ด
ํ๋ก์ธ์๋ฅผ LOCKํ๋ ์ญํ ์ ํ๋ ์ธ์คํธ๋ญ์ ์ด๋ค. ๋ํ CMPXCHG8B prefix๋ CMPํ๊ณ
XCHG, ๊ฐ์ ๋ฐ๊พธ๋ ์ญํ ์ ํ๋ ์ธ์คํธ๋ญ์ ์ด๋ค. ํ์ง๋ง ์ด ๋ ์ธ์คํธ๋ญ์ ์ด ๊ฐ์ด
์ฌ์ฉ๋๋ ๊ฒฝ์ฐ์๋ ์ ๋๋ก ์๋ํ์ง ์์ EXCEPTION_ILLEGAL_INSTRUCTION
(0xc000001d)์์ธ๊ฐ ๋ฐ์ํ๋ค. ๋๋ฒ๊ฑฐ๋ฅผ ์ฌ์ฉํ๊ณ ์์ ๋ ํด๋น ์์ธ๊ฐ ๋ฐ์ํด
ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ์์ธ ํธ๋ค๋ฌ์ ์ํด ์ฒ๋ฆฌ๋์ด ์ ์์ ์ผ๋ก ์คํ์ด ๋๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void error(void) { printf("Not Debugged");
}
void main() { SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)error); __asm { __emit 0xf0 __emit 0xf0 // LOCK prefix __emit 0xc7 __emit 0xc8 // CMPXCHG8B prefix }
}
H) Guard Pages
ํด๋น ๊ธฐ๋ฒ์ PAGE_GUARD ๋ชจ๋๋ก ๋ณดํธ๊ฐ ๋ ๋ฉ๋ชจ๋ฆฌ์ ๋๋ฒ๊ฑฐ๊ฐ ์ ๊ทผ์ ํ ๋ ์์ธ๋ฅผ
๋ฐ์์ํค๋ ๊ฒ์ ์ด์ฉํ ๊ธฐ๋ฒ์ ๋๋ค. EXCEPTION_GUARD_PAGE(0x80000001)์์ธ๊ฐ
๋ฐ์ํ์ ๋ ๊ณ์ ๋๋ฒ๊น ์ ํ๊ฒ ๋๋ฉด ์์ธ๋ฅผ ๊ทธ๋ฅ ์ง๋์น๊ฒ ๋๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { DWORD oProt; PVOID func = VirtualAlloc(NULL, 0x10, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memset(func, 0x10, 0xc3); // filled with c3 : ret VirtualProtect(func, 0x10, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &oProt); FARPROC proc = (FARPROC)func;
__try { proc(); }
__except (EXCEPTION_EXECUTE_HANDLER) {
printf("Not Debugged"); } }
I) CLI & STI
ํด๋น ์ธ์คํธ๋ญ์ ๋ค์ ring 3(์ ์ ๋ชจ๋) ๊ฐ ์๋ ring 0(์ปค๋ ๋ชจ๋)์ฉ ์ด์ ๋ธ๋ฆฌ๋ค์ด๋ค.
์ด ๋ช ๋ น์ด๋ค์ ring 3 ์์ ์ฌ์ฉํ๋ฉด STATUS_PRIVILEGED_INSTRUCTION(0xc0000096)
์์ธ๊ฐ ๋ฐ์ํ๋ค. ์ฐธ๊ณ ๋ก cli ๋ ์ธํฐ๋ฝํธ๋ค์ disable ํ๊ณ sti ๋ ๊ทธ ๋ฐ๋์ ์ญํ ์
ํ๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค. ์๋๋ ๊ฐ๋จํ ์์ ์ด๊ณ ์ง์ SEH ๋ VEH ๋ฑ ์ง์ ์์ธ ์ฒ๋ฆฌ
๋ฃจํด์ ์ ์ํด ์ฌ์ฉํ๋ฉด ๋๋ค.
void main() { __try { __asm { sti cli } } __except (EXCEPTION_EXECUTE_HANDLER) { printf("ring 3"); } }
J) SEH
์ด๋ฒ์๋ asm ์ผ๋ก ๊ฐ๋จํ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ SEH ๋ฅผ ์ ์ํด ๋ณผ ๊ฑฐ๋ค. ๋๋ถ๋ถ์ ๋ฉ์จ์ด๋
ํจ์ปค์์๋ ์ฝ๋ ๋๋ ํ๋ ์ํฐ ๋์ค์ด์ ๋ธ๋ฆฌ ๋ฑ์ ๋ชฉ์ ์ผ๋ก custom seh handler ๋ฅผ
์ง์ ๋ง๋ค์ด ์ฝ๋ encrypt ๋ decrypt, ์์ธ ์ฒ๋ฆฌ ๋ฑ์ ํ๋ค.
Closehandle ํจ์์ INVALID_HANDLE ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
EXCEPTION_DISPOSITION handler(PEXCEPTION_RECORD pExceptionRecord, PVOID pEstablisherFrame, PCONTEXT pContextRecord, PVOID pDispatcherContext) { if (EXCEPTION_INVALID_HANDLE == pExceptionRecord->ExceptionCode) printf("debugged"); return ExceptionContinueExecution; } void main() { __asm { push handler // seh handler push fs : [0] mov fs : [0], esp nop push 0xdeadbeef
call CloseHandle // EXCEPTION_INVALID_HANDLE nop mov eax, [esp] // restore handler mov fs : [0], eax add esp, 8 } }
2.4. Based on Break Points A) Hardware Break Point
ํ๋์จ์ด breakpoint ๋ ์ธํ ์ํคํ ์ณ์ ์กด์ฌํ๋ ๊ฒ ์ค ํ๋๋ก ์ด๊ฒ๋ค์ ๋ค๋ฃจ๊ธฐ ์ํด
Dr0 ~ Dr7 ์ ํน์ํ ๋ ์ง์คํฐ๋ฅผ ์ฌ์ฉํ๋ค. Dr0 ๋ถํฐ Dr3 ๋ ์ง์คํฐ๋ 32bit ๋ ์ง์คํฐ๋ก
breakpoint ์ฃผ์๋ฅผ ๋ด๋๋ฐ ์ฌ์ฉ๋๊ณ , Dr4 ~ Dr5 ๋ ์ง์คํฐ๋ ๋ค๋ฅธ ๋ชฉ์ ์ ์ํด ์์ฝ๋
๋ ์ง์คํฐ, Dr6 ~ Dr7 ์ breakpoint ์ ํ๋์ ์ ์ดํ๊ธฐ ์ํด์ ์ฌ์ฉ๋๋ค. ์ฆ, ํ๋์จ์ด
breakpoint ๋ฅผ ํ์งํ๊ธฐ ์ํด์ Dr0 ๋ถํฐ Dr3 ๋ ์ง์คํฐ๋ฅผ ํ์ธํด ๊ฐ์ด ๋ค์ด์์ผ๋ฉด
ํ๋์จ์ด breakpoint ๊ฐ ์ค์ ๋ ๊ฒ์ด๋ค.
๊ตฌํ ํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { UINT bps = 0; CONTEXT c; ZeroMemory(&c, sizeof(CONTEXT)); c.ContextFlags = CONTEXT_DEBUG_REGISTERS; if (GetThreadContext(GetCurrentThread(), &c) != 0) { if (c.Dr0 != 0) ++bps; if (c.Dr1 != 0) ++bps; if (c.Dr2 != 0) ++bps; if (c.Dr3 != 0) ++bps; } printf("%d bps", bps); }
2.5. Based on Flags A) BeingDebugged
ํด๋น ํจ์๋ TEB(Thread Environment Block)๊ณผ PEB(Process Environment Block)๋ฅผ
์ฌ์ฉํ๋๋ฐ, PEB ๊ตฌ์กฐ์ฒด์ BeingDebugged flag ๋ฅผ ๊ฒ์ฌํด ๋๋ฒ๊น ์ ํ์ธ ํ ๋๋ฒ๊น
์ค์ด๋ฉด TRUE, ์๋๋ฉด FALSE ๋ฅผ ๋ฐํํ๋ค.
- PEB Structure
- typedef struct _PEB {
- BYTE Reserved1[2];
- BYTE BeingDebugged;
- ...
- } PEB, *PPEB;
ํด๋น ํจ์๋ฅผ disassemble ํด ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ๋ณผ ์ ์๋๋ฐ, ์ง์ PEB ๊ตฌ์กฐ์ฒด์
์ ๊ทผํด์ BeingDebugged ๊ฐ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
mov eax, fs:[0x18] // TEB ์ ๊ทผ, FS:[18] ์ TEB ์ฃผ์๊ฐ ์์
mov eax, ds:[eax+0x30] // PEB ์ ๊ทผ, TEB 0x30 ์ PEB ๊ฐ ์์
movzx eax, ds:[eax+0x2] // PEB 2๋ฒ์งธ BeingDebugged ๊ฐ์ eax ์ ๋ฃ์
์ฝ๋๋ก ๊ตฌํ์ ํด ๋ณด์๋ฉด ์๋์ ๊ฐ๋ค.
void main() { if (IsDebuggerPresent()) printf("Debugged\n"); }
B) Trap Flag
TF(Trap Flag)๋ EFLAGS ๋ ์ง์คํฐ์ 9 ๋ฒ์งธ bit ์ ์กด์ฌํ๋ฉฐ ํด๋น ๊ฐ์ 1 ๋ก ์ธํ ์ ํ๋ฉด
CPU ๋ Single Step mode ๋ก ๋ณ๊ฒฝ๋๊ณ , ์ด ๋ชจ๋์ผ ๊ฒฝ์ฐ์ ๋ช ๋ น์ด๋ฅผ 1 ๊ฐ ์คํํ๊ณ
EXCEPTION_SINGLE_STEP(0x80000004)๋ฅผ ๋ฐ์์ํจ๋ค. ๊ทธ ํ TF ๊ฐ์ ๋ค์ 0 ์ผ๋ก
์ธํ ํ๋ค. ๋๋ฒ๊น ์ค์๋ ํด๋น ๋ ์ง์คํฐ์ ์ํฅ์ ์ฃผ์ง ์์ ๊ฒ์ด๊ณ ์ฆ ์์ธ๋ ๋ฐ์ํ์ง
์์ ๊ฒ์ด๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
void main() { __try {
__asm { pushf mov [esp], 0x100 // Set TF to 1 popf } } __except (EXCEPTION_EXECUTE_HANDLER) { printf("Not Debugged"); } }
C) NtGlobal Flag
ํด๋น Flag ๋ PEB ๊ตฌ์กฐ์ฒด 0x68 ๋ฒ์จฐ์ ์กด์ฌํ๋ ๋ฉค๋ฒ๋ก, ๋๋ฒ๊ฑฐ๊ฐ ์กด์ฌํ๋ฉด 0 ์ด ์๋
๊ฐ์ด ๋ค์ด๊ฐ๊ฒ ๋๊ณ ์กด์ฌํ์ง ์์ผ๋ฉด 0x0 ์ด ๋ค์ด๊ฐ๊ฒ ๋๋ค.
- PEB Structure
- typedef struct _PEB {
- ...
- ULONG NumberOfProcessors;
- ULONG NtGlobalFlag;
- UNION _LARGE_INTEGER CriticalSectionTimeout;
- ...
- } PEB, *PPEB;
ํ์ธํด ๋ณด๋ฉด 0x70 ์ด๋ ๊ฐ์ด ๋ค์ด๊ฐ๊ฒ ๋๋๋ฐ ์ด๋
FLG_HEAP_ENABLE_TAIL_CHECK 0x10
FLG_HEAP_ENABLE_FREE_CHECK 0x20
FLG_HEAP_ENABLE_VALIDATE_PARAMETERS 0x40
์ด 3 ๊ฐ ๊ฐ์ด ํฉ์ณ ์ ์ 0x70 ์ด ๋๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __asm { mov eax, fs:[0x30] mov eax, [eax + 0x68] cmp eax, 0x0 jne debug push 1 call exit debug: }
printf("Debugged"); }
D) Heap Flag
PEB ๊ตฌ์กฐ์ฒด์ 0x18 ์ ์กด์ฌํ๋ ProcessHeap ๊ตฌ์กฐ์ฒด์ Flags ์ ForceFlags ๋ flag ๋ฅผ
์ด์ฉํด์ ๋๋ฒ๊น ํ์ง๊ฐ ๊ฐ๋ฅํ๋ค. Flags ๋ 0xc ์ ์์นํ๊ณ ForceFlags ๋ 0x10 ์
์์นํ๋ค.
- PEB Structure
- typedef struct _PEB {
- ...
- ULONG MaximumNumberOfHeaps ;
- PPVOID *ProcessHeap;
- PVOID GdiSharedHandleTable;
- ...
- } PEB, *PPEB;
Flags ๋ ๋๋ฒ๊น ์ค์ด๋ฉด 0x50000062 ๋ก ๊ฐ์ด ์ค์ ๋๊ณ ์๋ ๊ฒฝ์ฐ์ 0x2 ๋ก ์ค์ ๋๋ค.
ForceFlags ๊ฐ์ ๊ฒฝ์ฐ์ ๋๋ฒ๊น ์ค์ด๋ฉด 0x40000060 ์๋ ๊ฒฝ์ฐ์ 0x0 ์ผ๋ก ์ค์ ๋๋ค.
- ProcessHeap Structure
- typedef struct _ProcessHeap {
- Entry _HEAP_ENTRY
- UINT Signature;
- UINT Flags;
- UINT ForceFlags;
- UINT VirtualMemoryThreshold;
- ...
- } ProcessHeap;
๊ฐ๋ค์ ์๋์ ๊ฐ์ ์ ์๋ ๊ฐ์ผ๋ก ์ค์ ์ด ๋๋ค.
HEAP_GROWABLE 0x2
HEAP_TAIL_CHECKING_ENABLED 0x20
HEAP_FREE_CHECKING_ENABLED 0x40
HEAP_SKIP_VALIDATION_CHECKS 0x10000000
HEAP_VALIDATE_PARAMETERS_ENABLED 0x40000000
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
- Flags Example
void main() { __asm {
mov eax, fs:[0x30] mov eax, [eax + 0x18] mov eax, [eax + 0xc] cmp eax, 0x2 jne debug
push 1 call exit
debug: } printf("debugged");
}
- ForceFlags Example
void main() { __asm { mov eax, fs:[0x30] mov eax, [eax + 0x18] mov eax, [eax + 0x10] cmp eax, 0x0 jne debug push 1 call exit debug : } printf("debugged");
}
2.6. Based on VM Detection A) Red Pill
- SIDT
IDT(Interrupt Descriptor Table)๋ ์ธํฐ๋ฝํธ ์ฒ๋ฆฌ์ ๊ดํ ๋์คํฌ๋ฆฝํฐ๋ค์ ๋ชจ์๋
๊ตฌ์กฐ์ฒด์ด๋ค. ํ๋ก์ธ์๋น 1 ๊ฐ์ IDT ๋ ์ง์คํฐ(IDTR)๊ฐ ์กด์ฌํ๊ณ Guest OS ์ Host OS ๊ฐ
๊ตฌ๋ ์ค์ด๋ฉด IDT ๋ ์ฌ๋ฐฐ์น ๋๋ค. IDTR ๋ก IDT ๋ฉ๋ชจ๋ฆฌ ์์น๋ฅผ ์ ์ ์๋๋ฐ ์ด๋ฅผ ํตํด์
VM ์ ํ์งํด ๋ผ ์ ์๋ค. SIDT(Store Interrupt Descriptor Table)๋ช ๋ น์ผ๋ก IDTR ์
๊ฐ์ ธ ์ฌ ์ ์๋ค. VMware ๋ VirtualPC ๋ฑ์ VM ์์๋ ์ฃผ๋ก 0xd0000000 ์ด์์ ์ฃผ์๊ฐ
๋์ค๊ธฐ ๋๋ฌธ์ ํด๋น ๊ฐ๋ณด๋ค ํฌ๋ฉด ๊ฐ์ ๋จธ์ ์ผ๋ก ํ์ง๋ฅผ ํ ์ ์๋ค. ํ์ง๋ง ์ด ๊ธฐ๋ฒ์
๋ฉํฐ ํ๋ก์ธ์๊ฐ์ด IDT ๊ฐ ์ฌ๋ฌ ๊ฐ ์กด์ฌํ ๊ฐ๋ฅ์ฑ์ด ์์ด ์ค์๋ ๊ฐ๋ฅ์ฑ์ด ๋๋ค. ๋ํ
์์ฆ VM ๋ค์ EPT ๊ธฐ๋ฅ ๊ฐ์ด ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ํ ๊ธฐ์ ์ ์ฌ์ฉํ๋ฉด ID ์ฐํ๊ฐ ๊ฐ๋ฅํ๋ค.
์ฐธ๊ณ ๋ก VMware ๋ 0xffxxxxxx ์ ์ฃผ์๊ณ , VirtualPC ๋ 0xe8xxxxxx. ๋ก์ปฌ์์ ์๋์ฐ๋
0x80xxxxxx, ๋ฆฌ๋ ์ค๋ 0xc0xxxxxx.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { unsigned char idt[6]; __asm { sidt idt } if ((int)idt[5] >= 0xd0) printf("VM"); }
B) No Pill
No Pill ๊ธฐ๋ฒ์ Red Pill ๊ธฐ๋ฒ๊ณผ ๋ค๋ฅด๊ฒ IDT ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์์ฒด์ ๊ฐ ์๋ ํ๋ก์ธ์์
ํ ๋นํ๋๊ฒ ์ฐจ์ด์ด๋ค. Host OS ์์๋ LDT ์์น๋ 0 ์ด๊ณ VM ์์๋ 0 ์ด ์๋๋ค.
- SGDT
ํด๋น ๊ธฐ๋ฒ์ SGDT(Store Global Descriptor Table)๋ช ๋ น์ผ๋ก GDTR(Global Descriptor
Table Register)์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ๋ค. ์์ LDT ๋ฅผ ์ด์ฉํ ํ์ง์ ๋น์ทํ๊ฒ ์ต์์ ๋ฐ์ดํธ๊ฐ
0xff ์ธ ๊ฒ์ ํ์ธํด VM ์ ํ๋ณํ๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { UCHAR gdt[6]; __asm { sgdt gdt } UINT gdta = *((PULONG)&gdt[2]); if ((gdta >> 24) == 0xff) printf("VM"); }
- SLDT
ํด๋น ๊ธฐ๋ฒ์ SLDT(Store Local Descriptor Table)๋ช ๋ น์ผ๋ก LDTR(Local Descriptor
Table Register)๋ก ๋ถํฐ Segment Selector ๋ฅผ ๊ตฌํด, ํธ์คํธ ๋จธ์ ์์ ์ฃผ์๊ฐ
0x0000 ์ด๋ ๋ง์ฝ ์ด ๊ฐ์ด ์๋๋ฉด VM ์ผ๋ก ํ์ง๊ฐ ๊ฐ๋ฅํ๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { UCHAR ldt[2]; __asm { sldt ldt } USHORT ldta = *((PUSHORT)&ldt); if (ldta != 0x0000) printf("VM"); }
C) I/O Port
I/O ํฌํธ๋ Guest OS ํ๊ณ Host OS ๊ฐ ํต์ ์ ํ ์ ์๋ ํต์ ์ฑ๋์ด๋ค. I/O ์
์ฌ์ฉ๋๋ ๋ช ๋ น์ด๋ EFLAGS ๋ ์ง์คํฐ๋ฅผ ์ด์ฉํด ์คํ๋๋๋ฐ ์ด๋ ์ปค๋ ๋ ๋ฒจ์์๋ง ๋์์
ํ๋ค. ์ ์ ๋ ๋ฒจ์์ ์คํํ๋ฉด ์์ธ๊ฐ ๋ฐ์ํ๋ค. I/O ๋ฅผ ์ํ ๋ช ๋ น์์๋ in ๊ณผ out ์ด
์๋๋ฐ, Guest OS ์์ in ๋ช ๋ น ์คํ ์ ์์ธ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
- verison
void main() { UINT a = 0, b = 0; __try { __asm { pushad mov eax, 0x564d5868 // vmware magic valu, VMXh
mov ecx, 0xa // vmware version mov dx, 0x5658 // vmware I/O port, VX in eax, dx mov a, ebx // check is it VM mov b, ecx // get version popad } } __except (EXCEPTION_EXECUTE_HANDLER) { return; } if (a == 'VMXh') { printf("VM, version : "); switch (b) { case 1: printf("Express"); break; case 2: printf("ESX"); break; case 3: printf("GSX"); break; case 4: printf("Workstation"); break; default: printf("Unknown"); break; } } }
- memory size
void main(void) { __try { __asm { pushad mov eax, 0x564d5868 // vmware magic value : VMXh mov ecx, 0x14 // memory size mov dx, 0x5658 // vmware I/O port : VX in eax, dx cmp eax, 0 jbe notvm push 1 call exit notvm : popad } printf("Not VM"); } __except (EXCEPTION_EXECUTE_HANDLER) { return; } }
D) STR
STR(Store Task Register)๋ช ๋ น์ผ๋ก Task Register ๊ฐ์ ๋ฐ์์ค๋๋ฐ, ์ฒ์์ด
0x0040 ์ผ๋ก ์์์ ํ๊ฒ ๋๋ฉด VM ์ธ ๊ฒ์ ์ ์ ์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { UCHAR mem[4] = { 0, }; __asm { str mem } if (mem[0] == 0x00 && mem[1] == 0x40) printf("VM"); }
E) SMSW
ํด๋น ๊ธฐ๋ฒ์ SMSW(Store Machine Status Word)๋ช ๋ น์ผ๋ก ๋จธ์ ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ ์ ์ฅํ๋
๋ช ๋ น์ด๋ค. CR0 ๋ ์ง์คํฐ์์ ๊ฐ์ ๊ฐ์ ธ์จ๋ค. ์ด์์ฒด์ ๋ง๋ค ๊ฐ์ด ๋ค๋ฅด๊ณ Host ์ Guest ์
๋ฐ๋ผ ๋ ๊ฐ์ด ๋ค๋ฅด๋ค. ์๋ฅผ ๋ค์ด Windows 10 ์์๋ 0x80050033 ๊ฐ์ ๊ฐ์ง๊ณ VM Windows
10 ์์๋ 0x80050031 ์ด๋ ๊ฐ์ ๊ฐ์ง๊ณ VM Windows 7 ์์๋ 0x80010031 ์ ๊ฐ์ง๋ค.
์ด๋ฐ ๊ฐ๋ค์ ๊ธฐ๋ฐ์ผ๋ก ํด์ ํ์ง๊ฐ ๊ฐ๋ฅํ๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __asm { xor eax, eax smsw eax; cmp eax, 0x80050031 // Windows 10 on VM je vm cmp eax, 0x80010031 // Windows 7 on VM je vm push 1 call exit vm: } printf("VM"); }
F) CPUID
CPUID ๋ช ๋ น์ด๋ CPU ์๋ณ์ ์ํ ๋ช ๋ น์ด์ด๋ค. ํ๋ผ๋ฉํฐ(EAX ๊ฐ)์ ํน์ ๊ฐ์ ๋ฃ์ด ์ ๋ณด๋ฅผ
์ป์ด ํฌ๊ฒ 2 ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก VM ํ์ง๊ฐ ๊ฐ๋ฅํ๋ฐ, EAX ์ 1 ์ ๋ฃ์์ ๋ ํ๊ณ
0x40000000 ์ผ ๋์ด๋ค. ๋จผ์ EAX ์ 1 ์ ๋ฃ์์ ๋๋, Guest OS ๊ฐ ์ผ์ ธ ์์ง ์์
ํ์์๋ผ๋ฉด EAX ๊ฐ์ด 1 ์ผ ๋ CPUID ์คํ ์ 3 ๋ฒ์งธ ECX ๊ฐ์ 0 ์ด์ฌ์ผํ๋ค. Guest OS ๊ฐ
์ผ์ ธ ์์ผ๋ฉด ECX ๋ VMware ์์ ์ง์ ํด์ค serial ๊ฐ์ด ๋ค์ด๊ฐ ์์ด 1 ์ผ ๊ฒ์ด๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __asm { mov eax, 1 xor ecx, ecx push ebx cpuid pop ebx sar ecx, 0x1f cmp cl, 1 je detect push 1 call exit detect: } printf("VM"); }
๋๋ฒ์จฐ๋ก EAX ๊ฐ์ด 0x40000000 ์ผ ๋, 12 ๋ฐ์ดํธ ๊ธธ์ด์ ๋ฌธ์์ด์ EBX, ECX, EDX ์
๋ฐํํ๋ค. ์ด ๋ฌธ์์ด์๋ ์ฅ์น ์ ๋ณด๊ฐ ๋ด๊ฒจ ์๋๋ฐ ๋ก์ปฌ ๋จธ์ ์ผ ๊ฒฝ์ฐ์ ์๋ฌด๋ฐ ๋ฌธ์์ด์ด
๋ณด์ด์ง ์์ง๋ง VM ์ผ ๊ฒฝ์ฐ์๋ ํด๋น VM ์ ๊ดํ ์ ๋ณด๊ฐ ๋ด๊ฒจ์๋ค. ์๋ฅผ ๋ค์ด,
- VMware : โVMwareVMwareโ
- VirtualBox : โVBoxVBoxVBoxโ
- Parallels : โprl hyperv โ
- KVM : โKVMKVMKVM\0\0\0โ
- Xen : โXenVMM XenVMMโ
- Microsoft Hyper-V, Windows Virtual PC : โMicrosoft Hvโ
ํ์ง๋ง ์ด ๊ธฐ๋ฒ ๋ํ CPU ๊ฐ Hyper Thread ๋ฅผ ์ง์ํ๊ฑฐ๋ Guest OS ๊ฐ ์ด๋ฅผ ์ฌ์ฉํ๋ฉด
์ค์๋ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
G) MAC Address
VM ์ฅ์น๋ค์ด ๊ฐ๋ ๊ณ ์ ํ MAC Address ์ ์ผ๋ถ๋ฅผ ์ฒดํฌํด ํ์งํ๋ ๋ฐฉ๋ฒ๋ ์๋ค. ์ฃผ๋ก ๋งฅ
์ฃผ์์ ๋งจ ์์ 3 ๊ฐ์ ํํธ์๋ ์ ์กฐ์ฌ์ ํน์ ๊ฐ์ ๋ฃ๊ฒ ๋๋๋ฐ ๋ฌผ๋ก VMware ๋
Virtual PC ๊ฐ์ VM ๋ค๋ ํน์ ๊ฐ๋ค์ ์ฌ๋ฌ ๊ฐ ๊ฐ์ง๊ณ ์๋ค.
00:05:69 (VMware)
00:0C:29 (VMware)
00:1C:14 (VMware)
00:50:56 (VMware)
08:00:27 (VirtualBox)
00:03:ff (Virtual PC)
00:0d:3a (Virtual PC)
00:50:f2 (Virtual PC)
7c:1e:52 (Virtual PC)
00:12:5a (Virtual PC)
00:15:5d (Virtual PC)
00:17:fa (Virtual PC)
28:18:78 (Virtual PC)
7c:ed:8d (Virtual PC)
00:1d:d8 (Virtual PC)
00:22:48 (Virtual PC)
00:25:ae (Virtual PC)
60:45:bd (Virtual PC)
dc:b4:c4 (Virtual PC)
00:1c:42 (Parallels)
๋งฅ ์ฃผ์๋ฅผ ๊ตฌํ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { ULONG len = 0; PIP_ADAPTER_INFO p; if (GetAdaptersInfo(p, &len) == ERROR_BUFFER_OVERFLOW) { p = (PIP_ADAPTER_INFO)new char[len]; GetAdaptersInfo(p, &len);
printf("MAC : %#x\n", p->Address); // VM Detect with MAC if (p->Address[0] == 0x08 && p->Address[1] == 0x00 &&
p->Address[2] == 0x27) printf("Virtual Box"); delete p; } }
H) ETC
์์ ์๊ฐ๋ ๊ธฐ๋ฒ ์ด์ธ์๋ ์ค๋ช ํ์ง ๋ชปํ ๊ธฐ๋ฒ๋ค์ด ์ฌ๋ฌ๊ฐ์ง ์๋ค. ๊ฐ๋ตํ๊ฒ ์ ๋ฆฌํด
๋ณด๊ฒ ๋ค.
- VM Process
VM ํ๊ฒฝ์์์ฃผ๋ก ๋ณผ ์ ์๋ ํ๋ก์ธ์ค๋ค์ด ์๋ค. ํด๋น ํ๋ก์ธ์ค ์กด์ฌ ์ ๋ฌด๋ก VM ํ๊ฒฝ์์
์ ์ ์๋ค.
VMtoolsd.exe (VMware)
VMwaretrat.exe (VMware)
VMwareUser.exe (VMware)
VMwareService.exe (VMware)
VMwareTray.exe (VMware)
Vmacthlp.exe (VMware)
vboxservice.exe (VirtualBox)
vboxtray.exe (VirtualBox)
- VM Files
๋ค์์ VM ์ ์๋ ์ฃผ์ ํ์ผ๋ค์ ๊ธฐ๋ฐ์ผ๋ก ํ์งํ๋ ๋ฐฉ๋ฒ์ด๋ค. ํด๋น ํ์ผ ์ ๋ฌด๋ก VM ์
ํ๋ณํ ์๋ ์๋ค. ์๋๋ ๋ํ์ ํ์ผ๋ค์ ์ ์ด๋ณด์๋ค.
C:\Windows\System32\Driver\Vmmouse.sys (VMware)
C:\Windows\System32\Driver\vm3dgl.dll (VMware)
C:\Windows\System32\Driver\vmdum.dll (VMware)
C:\Windows\System32\Driver\vm3dver.dll (VMware)
C:\Windows\System32\Driver\vmtray.dll (VMware)
C:\Windows\System32\Driver\VMToolsHook.dll (VMware)
C:\Windows\System32\Driver\vmmousever.dll (VMware)
C:\Windows\System32\Driver\vmhgfs.dll (VMware)
C:\Windows\System32\Driver\vmGuestLib.dll (VMware)
C:\Windows\System32\Driver\VmGuestLibJava.dll (VMware)
C:\Windows\System32\Driversvmhgfs.dll (VMware)
C:\Windows\System32\Driver\VBoxMouse.sys (VirtualBox)
C:\Windows\System32\Driver\VBoxGuest.sys (VirtualBox)
C:\Windows\System32\Driver\VBoxSF.sys (VirtualBox)
C:\Windows\System32\Driver\VBoxVideo.sys (VirtualBox)
C:\Windows\System32\vboxdisp.dll (VirtualBox)
C:\Windows\System32\vboxhook.dll (VirtualBox)
C:\Windows\System32\mrxnp.dll (VirtualBox)
C:\Windows\System32\vboxogl.dll (VirtualBox)
C:\Windows\System32\vboxoglarrayspu.dll (VirtualBox)
C:\Windows\System32\vboxoglerrorspu.dll (VirtualBox)
C:\Windows\System32\vboxoglfeedbackspu.dll (VirtualBox)
C:\Windows\System32\vboxoglpackspu.dll (VirtualBox)
C:\Windows\System32\vboxoglpassthroughspu.dll (VirtualBox)
C:\Windows\System32\vboxservice.exe (VirtualBox)
C:\Windows\System32\vboxtray.exe (VirtualBox)
C:\Windows\System32\VBoxControl.exe (VirtualBox)
dbghelp.dll (Sandboxie)
sbiedll.dll (Sandboxie)
- Running Services
์ด๋ฒ์๋ ํ์ฌ ์คํ์ค์ธ ์๋น์ค๋ค๋ก ํ์งํ๋ ๋ฐฉ๋ฒ์ด๋ค. ๋ฌผ๋ก ์ด๋ฌํ ํ๋ก์ธ์ค๋ค์ด ํ์ฌ
์คํ ์ค์ด๋ฉด VM ์ผ๋ก ํ๋ณํ ์ ์๋ค. ์๋๋ ๋ํ์ VM ๊ด๋ จ ์๋น์ค๋ค์ด๋ค.
VMTools (VMware)
Vmxnet (VMware)
Vmvss (VMware)
Vmscsi (VMware)
Vmhgfs (VMware)
Vmmouse (VMware)
VMMEMCTL (VMware)
Vmrawdsk (VMware)
Vmx_svga (VMware)
Vmware Tools (VMware)
Vmware Physical Disk Helper Service (VMware)
- Registry
VM ์์์๋ ๋ ์ง์คํธ๋ฆฌ๋ Host OS ์ ์ฐจ์ด๊ฐ ์๋ค. ๋ํ VM ๊ด๋ จ ์ ๋ณด๊ฐ ๋ ์ง์คํธ๋ฆฌ์
์ผ๋ถ ์ ์ฅ๋์ด ์์ผ๋ ๊ฐ์ ํ์ธํด VM ํ๋ณ์ด ๋ํ ๊ฐ๋ฅํ๋ค.
SYSTEM\CurrentControlSet\Services\disk\Enum โ 0 (VMware) [Hard Disk]
ํด๋น ํ๋์ VMware ๊ฐ ์์ผ๋ฉด VMware.
SYSTEM\CurrentControlSet\Enum\IDE\DiskVMware_Virtual_IDE_Hard_Drive___________00000001 (VMware) [Hard Disk Driver]
VMware ๋ DiskVMware_Virtual_IDE_Hard_Drive___________00000001 ๊ผด์ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ง.
SYSTEM\CurrentControlSet\Control\Class\{4D36E968~}\0000 - DriverDesc (VMware) [Video Driver]
VMware ๋ vmx_svga ๋ผ๋ ๋น๋์ค ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉ. ํด๋น ํ๋์ VMware ๋ฌธ์์ด์ด ์๋์ง ํ์ธ.
VMware SVGA 3D ์ด๋ฐ ํ์์ ๊ฐ์ด ๋ค์ด์์.
SYSTEM\CurrentControlSet\Control\VirtualDeviceDrivers (VMware)
ํด๋น ๋ ์ง์คํธ๋ฆฌ๋ Windows 7 ์๋ ์กด์ฌํ๊ณ Windows 10 ์๋ ์กด์ฌํ์ง ์๋๋ค.
SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\root#vmwvmcihostdev โ ClassGUID or Service (VMware)
ํด๋น ๋ ์ง์คํธ๋ฆฌ๋ Windows 7 ์ ์กด์ฌํ๋ ๊ฒ์ผ๋ก Windows 10 ๋ถํฐ๋
CriticalDeviceDatabase ์์ฒด๊ฐ ์๋ค. Service ์๋ vmci ๋ผ๋ ๊ฐ์ด ๋ค์ด์๋ค.
SYSTEM\CurrentControlSet\Enum\SCSI\Disk&Ven_VMware_&Prod_Vmware_Virtual_S โ [5&22be343f&0&000000] (VMware)
VMware ์ธ ๊ฒฝ์ฐ์ SCSI ์๋ ์ ๋ฐ ๊ฒฝ๋ก๊ฐ ์์ง๋ง ๋ก์ปฌ๋จธ์ ์์ SCSI ์์ฒด๋ ์กด์ฌํ์ง ์๋๋ค.
HARDWARE\DEVICEMAP\Scsi\Scsi Port 2\Scsi Bus 0\Target Id 0\Logical Unit Id 0 - Identifier (VMware)
VMware ๋ VMware, Vmware Virtual S1.0 ๊ฐ์ ์ด๋ฆ์ ๊ฐ์ง๋ค. ๋ ์๋์ฐ 7 ๊ฐ์ ๊ฒฝ์ฐ์ Scsi
Port 2 ์ง๋ง, ์๋์ฐ 10 ์ธ ๊ฒฝ์ฐ์ Scsi Port 0 ์ด๋ค.
HKLM\SOFTWARE\Vmware Inc.\\\Vmware Tools (VMware)
- Invalid API Parameters
๋๋ถ๋ถ์ API ํจ์๋ค์ ์ ํจํ์ง ์์ ์ธ์๋ฅผ ๋๊ฒจ ๋ฐ๊ฒ ๋๋ฉด ์๋ฌ ์ฝ๋๋ฅผ ๋ฐํํ ๊ฑฐ๋ค.
ํ์ง๋ง ์๋๋ฐ์ค ๊ฐ์ ์ํฐ ๋ฉ์จ์ด ์๋ฎฌ๋ ์ดํฐ์์๋ ์๋ฌ ์ฝ๋๋ฅผ ๋ฐํํ์ง ์๋ ์ ์ด
์๋ค.
- Modern CPU Instructions
์๋ฅผ ๋ค์ด ์ธํ ์ธ์คํธ๋ญ์ ์ ๋ค ์ค MMX, FPU, SSE ๊ฐ์ ๋ช ๋ น์ด ์ ๋ค์ VM ์์ ์ง์ํ์ง
์์ ์๋ ์๋ค. ๊ฒฐ๊ตญ ์ด๋ฌํ ์ฝ๋๋ฅผ ์คํ์ํฌ ์ ์๊ฑฐ๋ ์๋ชป๋ ์ธ์คํธ๋ญ์ ํด์์ผ๋ก
์ค๋ฅ๊ฐ ๋๊ฒ ๋ ๊ฒ์ด๋ค.
- Undocumented Instructions
๋ฌธ์ํ ๋์ง ์์ ๋ช ๋ น์ด๋ค์ VM ์์ ์ง์์ด ๋์ง ์์์ ์๋ ์๋ค. ์ฆ ๋ง์ฝ ์คํ์ด
๋๋ฉด ์๋ฌด ์๋์ ํ์ง ์๊ฑฐ๋ ์์ธ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ๋ ์ค์ ํ๋์ผ ๊ฒ์ด๋ค.
์๋๋ ๊ทธ๋ฌํ ์ธ์คํธ๋ญ์ ๋ค์ด๋ค.
db 0xf1; // icebp db 0xd6; // setalc // salc db 0xc0, 0xf0 // sal db 0xf7, 0xc8 // test db 0xf, 0x20 // mov eax, cr2
- Time Locks
๋๋ถ๋ถ ๋ฉ์จ์ด ์๋ํ ๊ฒ์ฌ ์์คํ (ex) malwares.com, virustotal.com)๋ค์ time
out ์ด๋ ์คํํ ์ ์๋ ์ธ์คํธ๋ญ์ ๋ค์ ์ ํ์ด ์๋ค. ์ด๋ฅผ ์ด์ฉํด์ ์๋ฅผ ๋ค์ด time
out ์ด max ๊ฐ์ด 30 ์ด๋ผ๋ฉด ํ๋ก๊ทธ๋จ์ 30 ์ด๊ฐ sleep ๋ฑ์ผ๋ก ๋ฉ์ถฐ ์๋ค 30 ์ด๊ฐ ์ง๋
ํ์ ์๋์ ํ๊ฒ ํ๋ค. ํ์ง๋ง ๋ช๋ช ์๋ฎฌ๋ ์ดํฐ์์ ์ด ๊ณผ์ ์ ์๋์ผ๋ก ๋์ด๊ฐ์ง๊ฒ
ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ฆ, ์ด๋ค ๋ฌด์๋ฏธํ ์์ ์ ์ค๋ํ๋ ๊ณผ์ ์ ์๊ฐ์ ์ธก์ ํด ๋์๋ค
์ด๊ฒ ์ง๋์น๊ฒ ์งง์ ์๊ฐ์ด ๊ฑธ๋ ธ์ผ๋ฉด ์ด ๊ณผ์ ์ ์ง๋์ณค๋ค๊ณ ํ๋จํ ์ ์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __asm { rdtsc xchg ebx, eax mov ecx, 0x121212 // set loop cnt up: loop up rdtsc sub eax, ebx cmp eax, 0x1000 // must over 0x1000 jbe emul push 1 call exit emul: } printf("Emulator"); }
- ETC
์์์ Red Pill, No Pill ๋ฑ ์์ ์๊ฐํ ๋ช ๋ น์ด ์ด์ธ์๋ MM7, FST ๋ฑ์ ๋ ์ง์คํฐ๋ฅผ
์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์๊ณ ์๊ฐ ๊ธฐ๋ฐ์ผ๋ก ํ์งํ๋ ๋ฐฉ๋ฒ ๋ฑ ์ฌ๋ฌ๊ฐ์ง ๊ธฐ๋ฒ๋ค์ด ์๋ค.
2.7. Based on Timing A) RDTSC
๋์ ๋ถ์์ ํ ๋ ์ฃผ๋ก ์ฌ๋ฌ ๊ณณ์ breakpoint ๋ฅผ ์ธํ ํด ๋๊ณ ๋ถ์์ ํ๊ฒ ๋๋ค. ๋ง์ฝ
์๊ฐ์ ์ธก์ ํ๋ ๋ช ๋ น์ธ rdtsc ์ rdtsc ์ฌ์ด์ ์๋ ์ฝ๋์ breakpoint ๋ฅผ ์ค์นํ๊ณ
๊ฐ์ ๋ณด๊ณ ๋์ด๊ฐ๋ค ํ์ ๋ ์๋ฌด๋ฆฌ ๋นจ๋ผ๋ ์๋ฌด๋ฐ ๋ฐฉํด ์์ด ์คํ๋ ๋์ 0.x ์ด์
์ฐจ์ด๋ ์์ ๊ฒ์ด๋ค. ์ด ๋ ์๊ฐ ์ฐจ์ด๊ฐ ๋๋ ๊ฑธ ์ด์ฉํ ๊ธฐ๋ฒ์ด ์๊ฐ ๊ธฐ๋ฐ ํ์ง
๊ธฐ๋ฒ์ด๋ค. RDTSC(ReaD Time Stamp Counter)๋ช ๋ น์ด ๋ง๊ณ ๋ API ํจ์๋ก๋ GetTickCount,
QueryPerformanceTime ๋ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ ์๋ ์๊ณ , ๋ ํนํ๊ฒ
CreateTransaction ํจ์๋ฅผ ์ฌ์ฉํด์๋ ๊ตฌํ์ ํด ๋ณผ ์ ์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void count() { for (int i = 0; i < 10000; ++i); } void main() { UINT start, end; __asm { rdtsc mov start, eax call count // do something! loop 0 ~ 9999 rdtsc mov end, eax mov eax, end sub eax, start cmp eax, 0x1000 // time jbe notdebug push 1 call exit notdebug: mov start, eax } printf("diff %lu", start); }
2.8. Based on Checksums A) Hash Checking
์ด๋ฐ ์ ์ ์ด์ฉํด Hash Checking ๊ธฐ๋ฒ์ ํจ์ ์ฝ๋๋ค์ Hash ๊ฐ์ ๋ฏธ๋ฆฌ ๊ตฌํด ๋ ๋ค์์
๊ทธ ๊ฐ๊ณผ ์คํ ์ค๊ฐ์ ํ์ธ ํ Hash ๊ฐ๊ณผ ๊ฐ์ ์ง ํ์ธ ํด ํจ์นญ์ด ๋ฌ๋์ง ํ์ง ํ ์
์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void func(void) { printf("Hello!");
} void main() { DWORD checksum = 0x5792b8ac; // pre-calculated __asm { pushad mov ecx, offset main mov esi, offset func sub ecx, esi // func size - loop cnt xor eax, eax // checksum xor ebx, ebx calc : // checksum calc algorithm movzx ebx, ds:[esi] add eax, ebx rol eax, 1 inc esi loop calc cmp eax, checksum // compare jne debug push 1 call exit debug : popad } printf("Debugged"); }
2.9. Etc A) Stack Segment
SS(Stack Segment)๋ฅผ push ํ๊ณ pop ํ๊ฒ ๋๋ฉด ๋๋ฒ๊ฑฐ๊ฐ ์ธ์คํธ๋ญ์ ์ ์๋ชป ํด์ํด ๋ฐ๋ก
๋ค์ ์ฝ๋๊ฐ ์คํ์ ๋์ง๋ง step over ๋๊ณ ๊ทธ ๋ค์ ์ฝ๋๋ก ์ฎ๊ฒจ์ง๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void stepover() { __asm { mov eax, 0xdeadbeef } } void main() { __asm { push ss pop ss call stepover // This would be stepped over xor eax, eax } }
B) TLS Callback
TLS(Thread Local Storage)๋ EP(Entry Point)๊ฐ ์์ ๋๊ธฐ ์ ์ ์คํ๋๋ ๋ฃจํด์ด๋ค.
๋น์ ํ๋ฉด ๋ฆฌ๋ ์ค์ ctors ๊ฐ์ ์กด์ฌ๋ค. ์ง์ PE ๊ตฌ์กฐ๋ฅผ ํ์ธํด ๋ณด๋ฉด TLS ๊ธฐ๋ฅ์ ๋ฃ์ผ๋ฉด
tls section ์ด ๋ฐ๋ก ์์ฑ๋๋ค. ์ด๋ ๊ฒ main ํจ์๊ฐ ์์๋๊ธฐ ์ ์ ํด๋น callback ์ด
์คํ๋๋ ์ ์ ์ด์ฉํด ํด๋น ํจ์ ์์ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ๋ค์ ์ฃผ๋ก ๋ฃ์ด๋๊ณ ์ฌ์ฉํ๋ค.
data_seg ๋ .CRT$XL? ํ์์ผ๋ก ?์ B~Z ๊น์ง ๋ฃ์ด ์ฌ์ฉ ๊ฐ๋ฅํ๊ณ A ๋ ์ฌ์ฉ์ด
๋ถ๊ฐํ๋ค๋ ๊ฒ.
๊ตฌํํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค. ์คํ๊ฒฐ๊ณผ main ์์๋ ๋ณผ ์ ์์๋ ์ฐ์ฐ์ธ ++stat;
์คํ์ผ๋ก 0 ์ด ์๋ 1 ์ด ์ถ๋ ฅ๋ ๊ฑฐ๋ค.
int stat = 0; #pragma comment(linker, "/INCLUDE:__tls_used") void NTAPI tls(PVOID instance, DWORD reason, PVOID reserved) { ++stat; } #pragma data_seg(".CRT$XLB") PIMAGE_TLS_CALLBACK TLS = tls; // PIMAGE_TLS_CALLBACK TLS[] = { tls, 0 }; #pragma data_seg() void main() { printf("State : %d\n", stat);
}
C) CC Scanning
์ฃผ๋ก ๋๋ฒ๊น ์์ breakpoint ๋ฅผ ์ค์ ํด์ ๋์ ๋ถ์์ ์งํํ๋ค. ์ด ๋ breakpoint ๋ฅผ
์ค์ ์ ํ๋ฉด 0xcc(int 3) ๋ ์ฝ๋๊ฐ ์ถ๊ฐ๊ฐ ๋๋ค. ์ด ๊ฐ์ ์ง์ ํด์ค ํจ์(์๋์์
func)๋ฅผ 1 ๋ฐ์ดํธ์ฉ ๋์๋ค๋๋ฉฐ ๊ฒ์ฌ๋ฅผ ํ๋ ๊ธฐ๋ฒ์ด๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void func() { __asm { mov eax, 0xdeadbeef } } void main() { __asm { popad mov ecx, offset main mov esi, offset func sub ecx, esi // size of func() xor ebx, ebx scan : movzx ebx, ds : [esi] // one by one cmp ebx, 0xcc // compare with 0xcc(bp) je bpx inc esi cmp ecx, 0 je end loop scan end : jmp nobpx bpx : rdtsc call eax // go somewhere nobpx : call func // no breakpoints are detected popad } }
3. Anti-Disassembly ์ํฐ ๋์ค์ด์ ๋ธ๋ฆฌ ํํธ์์๋ ์ฝ๋๋ฅผ ๋๋ ํ ํ๋ ๋ฐฉ๋ฒ๊ณผ ๋๋ฒ๊ฑฐ ๊ฐ์ ๋ถ์ํด์ด ์ ๋๋ก
๋ถ์ํ์ง ๋ชปํ๊ฒ ํ๋ ์ฌ๋ฌ ๊ธฐ์ ์ ๋ํด ์์๋ณผ ๊ฒ์ด๋ค.
3.1. Code Obfuscating - Code Virtualizing
์ด๋ฒ ๋ฌธ์์์๋ ์ฝ๋ ๊ฐ์ํ์ ๋ํด์ ์ค๋ช ํ๊ณ ๊ตฌํ ๊ณผ์ ์ ์ค๋ช ํ๊ธฐ์ ๋ง์ ์์ธํ
์ค๋ช ์ ๋ค๋ฃจ์ง ์์ ๊ฒ์ด๋ค.
์ฝ๋ ๊ฐ์ํ๋ ์ฃผ๋ก ์ฐ๋ฆฌ๋ ์ธํ ์ธ์คํธ๋ญ์ ์ ์ ์ฃผ์ด์ง ๋๋ก ์ ์๋ opcode ์
๋ช ๋ น์ด๋ค์ ์ฌ์ฉํ๋ค. ํ์ง๋ง ์ด ๊ธฐ๋ฒ์ ์ง์ ์์ ์ด opcode ๋ register ๋ฅผ ๊ฐ์ํ ์์ผ
์๋ก์ด ์ธ์คํธ๋ญ์ ์ฒด๊ณ๋ฅผ ๋ง๋๋ ๊ฒ์ด๋ค. ์๋ฅผ ๋ค์ด opcode 0x1 ๋ฅผ mov ๋ก ์ ํด๋๊ณ
์ง์ ์ด์ ํด๋นํ๋ ์ฝ๋๋ฅผ ์ง๋ ๊ฑฐ๋ค.
์๋ง ํด๋น ๊ธฐ์ ์ ๋ํด์ ๋ค์ ๋ฌธ์์์ ์ ๋ฆฌํด ๋ค๋ฃจ๊ฒ ๋ ์์ ์ด๋ค.
- VFTables
VFTable(Virtual Function Table)์ด๋ ํด๋์ค์ ์ ์ธ ์ ๊ฐ์ ํจ์ ํ์ ์ผ๋ก ์ ์ธํ๊ฒ
๋๋ฉด vftable ์ด๋ ๊ณณ์ ๊ฐ์ ํจ์๋ค์ ์ฃผ์๊ฐ ์ ์ฅ๋๋ ๊ณณ์ด๋ค. ๊ฐ์ ํจ์๋ฅผ ์ ์ธํด
vftable ์ฃผ์๊ฐ ์๋ __vfptr ๋ฅผ ์ฐธ์กฐ ํ๋ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ์ง๊ฒ ๋๋ฉด ์ผ์ข ์ ์ฝ๋
๋๋ ํ๊ฐ ๊ฐ๋ฅํ๋ค. ๊ตฌ์ฒด์ ์ธ vftable ์ ๊ดํ ์ค๋ช ์ class ์ ๋ํ ์ค๋ช ๊ณผ ๊ฐ์ ํจ์์
๊ดํ ์ค๋ช ์ ์ฐพ์๋ณด๊ธธ ๋ฐ๋๋ค.
์๋๋ PoC ์ฝ๋์ด๋ค.
class _vft1 { public: virtual int add(int a, int b) { return a + b; } virtual int sub(int a, int b) { return a - b; } }; void main() {
_vft1 v; PVOID *vf = (PVOID *)(&v); PVOID *vft = (PVOID *)*(&vf[0]); // point __vfptr auto add = reinterpret_cast<int(__thiscall *)(PVOID, int, int)>(vft[0]); auto sub = reinterpret_cast<int(__thiscall *)(PVOID, int, int)>(vft[1]); printf("%d\n", add(&v, 2, 2)); printf("%d\n", sub(&v, 3, 1)); }
- Dummy Codes
๋๋ฏธ ์ฝ๋๋ ๊ฒฐ๋ก ์ ์ผ๋ก ์๋ฌด๋ฐ ์ญํ ์ ํ์ง ์๋ ์ฝ๋ ๋ญ์น๋ก, ์ฝ๋ ์ฌ์ด์ฌ์ด์ ์ฝ์ ํด
์ฝ๋ ๋๋ ํ๋ฅผ ์ํค๊ฑฐ๋ ๋ถ์ํด์ด ์ธ์คํธ๋ญ์ ๋ค์ ์๋ชป ํด์ํ๊ฒ ํ๋ ์ฉ๋๋ก ์ฌ์ฉ๋๋ค.
์๋๋ ๊ฐ๋จํ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ๊ณผ ๋๋ฏธ ์ฝ๋๋ฅผ ์์ด ๋ง๋ค์ด ๋ณธ ์์ ์ฝ๋์ด๋ค. ์ฝ๋์์
๊ฐ์กฐํ ๋ถ๋ถ์ด ์ค์ ๋ก ํ๋ ์ญํ ์ด๊ณ ๋๋จธ์ง ์ฝ๋๋ ์ ๋ถ hexray ๋ฐฉํด ์ฝ๋, ๋๋ฏธ
์ฝ๋๋ค์ด๋ค. ์ค์ ๋ก ์คํ ํด ๋ณด๋ฉด ์ ์์ ์ผ๋ก ์๋ํ๊ณ ์ฌ๋ฌ ๋ถ์ ํด์์๋ ๋ถ์์
์คํจํ ๊ฒ์ด๋ค.
void main() { __asm { pushad xor ebx, ebx shr ebx, 4 add esi, ebx mov eax, fs:[0x18] // TEB mov ecx, 0xdeadbeef cmp ecx, 0xdead jne jumping add esp, 0x100 call esp // never gonna happen jumping: sub ecx, ebx push offset gogo + 10 add ecx, esi lea edx, [esi+ecx] mov eax, ds:[eax + 0x30] // TEB->PEB retn shr edx, 5 mov esi, edx gogo: add esp, 0xfff call esp call ebx // never gonna happen movzx eax, ds:[eax + 2] // jump to here, TEB->PEB->IsDebugged lea ebx, [eax + ecx] xor ecx, ecx
test eax, eax // check IsDebugged push esi lea esi, [esp + 0xc] pop edi push eax jnz debug push 1 jmp goout popad debug: rdtsc call eax // go somewhere goout: popad } printf("Not Debugged"); }
3.2. Packing A) Benchmark
์ฝ๋๋ฅผ ๋ณดํธํ๋ ๋ฐฉ๋ฒ์ผ๋ก Packing ์ด๋ ๋ฐฉ๋ฒ์ด ํ๊ฐ์ง ๋ ์๋ค. Packing ์ด๋
์คํํ์ผ์ ์์ถ ๋ฐ ์ํธํ ํด์ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋งํ๋ค. ๋ฌผ๋ก ์์ถํ๊ณ ์ํธํ๋ฅผ ํด
์ ์ฅํ ๋ ๋ค๋ฅธ ์น์ ์ ๋ง๋ค๊ณ ๊ทธ ๊ณณ์ ๋ณตํธํํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฅํด ๋์ด ์คํ ์
์ํธํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณตํธํ ํ ์คํํด ์คํ์๋ ๋ฌธ์ ๊ฐ ์๋ค.
- UPX
์ผ๋จ ํ๋ฆฌ์จ์ด๊ณ ๊ฐ๋ฒผ์ฐ๋ฉด์ ๋ค์ํ ํฌ๋งท์ ์ง์ํ๊ณ ํจ์จ์ด ์ข์ผ๋ฉฐ ๋ง์ด ์ฐ์ด๋ ํจ์ปค ์ค
ํ๋์ด๋ค. ํจํน ์ UPX0 ํ๊ณ UPX1 ์น์ ์ด ์์ฑ๋๊ณ UPX0 ์๋ Section ๋ฐ ๊ธฐํ ์ ๋ณด
์ด๊ธฐํ ๊ด๋ จ ์ฝ๋๊ฐ ์กด์ฌํ๊ณ UPX1 ์๋ ๋ณตํธํ ๋ฃจํด์ด ์กด์ฌํ๋ค.
- ASPack/ASProtect
์์ฉ ํ๋ก๊ทธ๋จ์ด๊ณ , x86, x64 ์๋์ฐ ์คํํ์ผ ํ์ ๋ ๋ค ์ง์์ ํ๋ค. ์ฝ๋ ์์ถ๋ฅ
๋ฑ์์๋ ๋ณ๋ก ์ข์ง ๋ชปํ์ง๋ง ์ํธํ๋ ์ ๋์ด์๋ค. Stolen Bytes ๊ธฐ๋ฒ์ด ์ต์ด๋ก ๊ตฌํ๋
ํจ์ปค๋ค.
- Themida
๊ฐ์ฅ ๊ฐ๋ ฅํ ํจ์ปค ์ค ํ๋๋ก ์ํฐ ๋๋ฒ๊น , ์ํฐ ๋คํ, ์ํฐ VM ๋ฑ ์ฌ๋ฌ๊ฐ์ง ๊ธฐ๋ฅ์
์ง์ํ๋ฉฐ ์ง์ ์ปค์คํ ํ ์๋ ์๋ค. Section ๋ค์ ์ด๋ฆ์ ๋๋ค์ผ๋ก ์์ฑ๋๊ณ ์ฌ๋ฌ ์์ฉ
ํ๋ก๊ทธ๋จ์์๋ ์ฌ์ฉ ์ค์ด๋ค. ํ์ฌ ์นด์นด์คํก ๊ฐ์ ์ฌ๋ฌ ํ๋ก๊ทธ๋จ๋ค๋ Themida ํจ์ปค๋ฅผ
์ฌ์ฉํ๊ณ ์๋ค.
3.3. Anti-Dumping
A) Erase PE Header
ํด๋น ๊ธฐ๋ฒ์ ๋ฉ๋ชจ๋ฆฌ ์์ ์กด์ฌํ๋ PE Header ๋ฅผ ์ง์ dumping ์ ํ๋ ๊ณผ์ ์ ๋ฐฉํดํ ์
์๋ค.
๊ตฌํํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { DWORD oProt = 0; PCHAR base = (PCHAR)GetModuleHandle(NULL); // base address VirtualProtect(base, 4096, // x86 page size PAGE_READWRITE, &oProt); memset(base, 0, 4096); }
B) PE Header Modification
๋ฉ๋ชจ๋ฆฌ ์์ ์ฌ๋ผ์ ์๋ PE ์ ๋ณด๋ค์ ์ง์ฐ๊ฑฐ๋ ์์ ํด dumping ์ ๋ฐฉํดํ๋ ๋ฐฉ๋ฒ๋
์์ง๋ง, ์ง์ ๋ฐ์ด๋๋ฆฌ์ PE ๊ตฌ์กฐ๋ฅผ ์์ ํด์ ์ฌ๋ฆฌ๋๋ฒ๊ทธ ๊ฐ์ด strict ํ PE ๊ฒ์ฌ ๋ฃจํด์
๊ฐ์ง๊ณ ์๋ ์ฌ๋ฌ ํด๋ค์ ๋ฌด๋ ฅํ ์ํฌ ์ ์๋ค.
๋ค์์ PE Header(IMAGE_OPTIONAL_HEADER)๊ตฌ์กฐ๋ค.
- Magic: 0x010B (HDR32_MAGIC) - MajorLinkerVersion: 0x0e - MinorLinkerVersion: 0x00 -> 14.00 - SizeOfCode: 0x00001400 - SizeOfInitializedData: 0x00001200 - SizeOfUninitializedData: 0x00000000 - AddressOfEntryPoint: 0x00001470 - BaseOfCode: 0x00001000 - BaseOfData: 0x00003000 - ImageBase: 0x00400000
- SectionAlignment: 0x00001000 - FileAlignment: 0x00000200 - MajorOperatingSystemVersion: 0x0006 - MinorOperatingSystemVersion: 0x0000 -> 6.00 - MajorImageVersion: 0x0000 - MinorImageVersion: 0x0000 -> 0.00 - MajorSubsystemVersion: 0x0006 - MinorSubsystemVersion: 0x0000 -> 6.00 - Win32VersionValue: 0x00000000 - SizeOfImage: 0x00007000 - SizeOfHeaders: 0x00000400 - CheckSum: 0x00000000 - Subsystem: 0x0003 (WINDOWS_CUI) - DllCharacteristics: 0x8000 - SizeOfStackReserve: 0x00100000 - SizeOfStackCommit: 0x00001000 - SizeOfHeapReserve: 0x00100000 - SizeOfHeapCommit: 0x00001000 - LoaderFlags: 0x00000000 - NumberOfRvaAndSizes: 0x00000010
- ImageBase
๊ธฐ๋ณธ์ ์ผ๋ก Win32 ํ๋ก๊ทธ๋จ์์ ImageBase ๊ฐ์ 0x400000 ์ผ๋ก ์ธํ ์ด ๋๋ค. ํ์ง๋ง ์ด
๊ฐ์ ์กฐ์ํด์ ์ผ๋ถ ๋ถ์ํด์์ ๋ก๋ฉ์ด ์๋๊ฒ ํ๊ฑฐ๋ ๋ถ์์ ๋ฐฉํดํ ์ ์๋ค.
- EntryPoint RVA
PE Header ์ AddressOfEntryPoint ์ธ EntryPoint RVA ๊ฐ์ 0 ์ผ๋ก ์ธํ ์ ํ๊ฒ ๋๋ฉด
ํ์ผ์ ๋งจ ์ฒ์์ธ โMZโ ๋ถํฐ ์คํ๋ ๊ฑฐ๋ค. ์ฆ, MZ ๋ถํฐ ์ฝ๋๊ฐ ์คํ๋๋ opcode ๋ก dec
ebx, pop edx ๋ถํฐ ์์๋๋ ์ ์ด๋ค. ๋ฌผ๋ก EntryPoint ๊ฐ 0 ์ธ ํ๋ก๊ทธ๋จ์ ์ดํ์ ๋ค์
OEP ๋ก ๋ณต๊ทํ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ผ ํฌ๋์ฌ๊ฐ ๋์ง ์์ ๊ฒ์ด๋ค. ์ด๋ฐ ๊ธฐ๋ฒ์ ์ฃผ๋ก ํจ์ปค๋ค์์
๋ง์ด ๋ณผ ์ ์๋ ๊ธฐ๋ฒ์ด๋ค.
- SizeOfImage
์ผ๋ถ ๋ถ์ํด(๊ตฌ๋ฒ์ LordPE, ๋ฑ)์์ PE ํค๋์ SizeOfImage ๊ฐ ์๋ ํฌ๊ธฐ๊ฐ ์๋๋ฉด
ํฌ๋์ฌ๊ฐ ๋๊ธฐ๋ ํ์๋ค. ํ์ฌ SizeOfImage ๊ฐ๋ณด๋ค ์ฝ๊ฐ ํฐ ๊ฐ์ผ๋ก ์์ ํด ํด์์
๋ถ์๋๋๊ฑธ ๋ฐฉํด ํ ์ ์๋ค. ์ด ๊ฐ์ PEB->PEB_LDR_DATA->InOrderModuleList ์
SizeOfImage ๊ฐ์ ์์ ํด ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค.
- PEB_LDR_DATA Structure
- typedef struct _PEB_LDR_DATA {
- ULONG Length;
- UCHAR Initialized[4];
- ULONG SsHandle;
- mLIST InLoadOrderList;
- mLIST InMemOrderList;
- mLIST InInitOrderList;
- UCHAR EntryInProgress;
- } PEB_LDR_DATA;
PoC ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
void main() { __asm { mov eax, fs:[0x30] // PEB mov eax, [eax + 0xc] // PEB_LDR_DATA mov eax, [eax + 0xc] // InOrderModuleList add [eax + 0x20], 0x3000 // SizeOfImage } }
- LoderFlags & NumberOfRvaAndSizes
๊ตฌ๋ฒ์ ์ฌ๋ฆฌ๋๋ฒ๊ทธ ๊ฐ์ ๋ช๋ช ๋๋ฒ๊ฑฐ์์๋ ์๊ฒฉํ PE ๊ตฌ์กฐ ๊ฒ์ฌ ๋๋ฌธ์ ํด๋น ๊ฐ๋ค์
์์ ํด ํ์ผ์ ์ด๊ฒ ๋๋ฉด ํ๋ก๊ทธ๋จ์ด ๋ป๊ธฐ๋ ํ๋ค. NumberOfRvaAndSizes ์๋ ๋ค์
์ฌ์ฉ๋๋ ๋ฐ์ดํฐ ํ ์ด๋ธ์ ๊ฐฏ์๋ฅผ ์ ์ฅํ๋ ๊ณณ์ธ๋ฐ, ์ต๋ 0x10 ๊ฐ์ ํ ์ด๋ธ์ ๊ฐ์ง ์
์๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๊ฐ์ 0x10 ์ด์์ผ๋ก ์์ ์ ํด๋ ์คํ์์๋ ์๋ฌด ๋ฌธ์ ๊ฐ ์๋ค. ์ด๋ฅผ
์ด์ฉํด 0x10 ์ด์์ ์์์ ๊ฐ์ผ๋ก ๋ฐ๊ฟ ์๋ ์๋ค.
C) Sections Modification
- SizeOfRawData
Section Table ์์ SizeOfRawData ๊ฐ์ ์ ์ ๊ฐ์ธ VirtualAddress ์ VirtualSIze ์
์ฐจ๊ฐ ์๋ ๋น์ ์์ ์ผ๋ก ํฐ ๊ฐ์ ๋ฃ์ด์ ์ฌ๋ฌ ๋ถ์ ํด์์ ํฌ๋์ฌ๋ฅผ ๋ฐ์ ์ํฌ ์ ์๋ค.
์๋ฅผ ๋ค์ด ๊ตฌ ๋ฒ์ IDA ์์๋ section ํฌ๊ธฐ๋ฅผ ์๋ชป ์ธ์ํ๊ฒ ๋ผ ์์ฒญ๋๊ฒ ํฌ๊ฒ ๋ฉ๋ชจ๋ฆฌ๋ฅผ
ํ ๋นํ๋ ๊ฒฝ์ฐ๋ ์์๋ค.
- No Section Table
PE Header ์ SectionAlignment ๊ฐ์ด 4000(0xfa0)๋ณด๋ค ์์์ง๋ฉด, PE Header ๋
writeable, excutable ํ ์์ญ์ด ๋๊ณ , Section Table ์ด ํ์๊ฐ ์๋๊ณ ์ต์ ์ด ๋๊ฒ
๋๋ค. ์ฆ, ๋ชจ๋ Section ๋ค์ด ์๋ ๊ฑฐ๋ ๋ง์ฐฌ๊ฐ์ง๊ฐ ๋๋ค.
D) Stolen Bytes โ Asprotect
OEP ์ฃผ๋ณ์ ๋ช ๊ฐ์ ๋ฐ์ดํธ๋ค์(์ธ์คํธ๋ญ์ ) ๋ถ๋ฆฌ๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ๋ก ๋ณต์ฌํ ๋ค์์ ๊ทธ ๊ฒ์
์คํํ๋ ๊ธฐ๋ฒ์ Stolen Bytes ๋ผ๊ณ ํ๋ค. ํ์ง๋ง ๋จ์ํ๊ฒ ์๋ฌด๋ฐ์๋ ์ธ์คํธ๋ญ์ ๋ค์
๋ณต์ฌํด ์คํํ ์๋ ์๊ณ ๊ทธ ์ฝ๋๋ค์ ์ฌ์ด์ฆ๋ฅผ ๋ฏธ๋ฆฌ ์๊ณ ์์ด์ผ ์๋ชป๋ ์ธ์คํธ๋ญ์ ๋ค์ด
๋์ง ์๊ณ ์์ธ์์ด ์ ๋๋ก ์คํ์ด ๋ ๊ฑฐ๋ค. PoC ์ฝ๋๋ ์๋ Reference ์ ์ฐธ๊ณ ๋งํฌ๋ฅผ
ํ์ธํ๊ธฐ ๋ฐ๋๋ค.
E) Nanomites โ Armadillo
ํด๋น ๊ธฐ๋ฒ์ Armadillo ํจ์ปค์์ ์ฒ์์ผ๋ก ๊ตฌํ๋ ๊ธฐ๋ฅ์ผ๋ก ๋ชจ๋ ์ ํ๊ตฌ๋ฌธ(jmp, je, jz,
๋ฑ)์ ์์น๋ ์ ๋ณด๋ฅผ ๋ค๋ฅธ ๋ถ๋ถ์ ์ ์ฅํด ๋๊ณ int 3(0xcc)๋ก ๊ต์ฒดํ๋ ๊ธฐ๋ฒ์ด๋ค.
๋ณตํธํ ๊ณผ์ ์์๋ SEH ๋ฅผ ํ๋ ๋ง๋ค์ด ๋ 0xcc ๋ฅผ ๋ง๋ ๋ ๋ง๋ค, ์์ธ๊ฐ ๋ฐ์ํ ๋ ๋ง๋ค
ํ๋์ฉ ๋ณตํธํ๋ฅผ ํด ๋๊ฐ๋ ๊ณผ์ ์ ๊ฑฐ์น๋ค. PoC ์ฝ๋๋ ์๋ Reference ์ ์ฐธ๊ณ ๋งํฌ๋ฅผ
ํ์ธํ๊ธฐ ๋ฐ๋๋ค.
3.4. Etc
A) Fake Signatures
Fake Signature ๋ PEID ๊ฐ์ ๋ฐ์ด๋๋ฆฌ ๋ถ์ ํ๋ก๊ทธ๋จ์์ ์ค์ ์ ๋ณด์๋ ๋ค๋ฅธ ์ ๋ณด๋ก
์ธ์๋๊ฒ ์๋๋ฉด ์ธ์๋์ง ๋ชปํ๊ฒ ํ๋ ๊ธฐ์ ์ ๋งํ๋ค. ์๋ฅผ ๋ค์ด UPX ๋ก ํจํน๋์ง ์์
์ด๋ค ํ์ผ์์ UPX ์์ ์ฐ์ด๋ ์๊ทธ๋์ฒ ์ฝ๋๋ฅผ ์ฌ์ฉํด UPX packed ํ๋ก๊ทธ๋จ์ด ์๋์ง๋ง
UPX packed ํ๋ก๊ทธ๋จ์ผ๋ก ํ์ง๊ฐ ๋ ์ ์๋ค.
์๋๋ ๊ตฌํํ ์ฝ๋์ด๋ค.
void main() { }
extern "C" __declspec(naked) void fake(void) { __asm { // UPX signature __emit 0x60 __emit 0xbe __emit 0x0 __emit 0x80 __emit 0x40 __emit 0x0 __emit 0x8d __emit 0xbe __emit 0x0 __emit 0x90 __emit 0xff __emit 0xff __emit 0x57 __emit 0x83 __emit 0xcd __emit 0xff __emit 0xeb __emit 0x10 __emit 0x90 __emit 0x90 __emit 0x90 __emit 0x90 __emit 0x90 __emit 0x90 __emit 0x8a __emit 0x6 __emit 0x46 __emit 0x88 __emit 0x7 __emit 0x47 __emit 0x1 __emit 0xdb __emit 0x75 __emit 0x7 __emit 0x8b __emit 0x1e __emit 0x83 __emit 0xee __emit 0xfc __emit 0x11 __emit 0xdb __emit 0x72 __emit 0xed __emit 0xb8 __emit 0x1 __emit 0x0 __emit 0x0 __emit 0x0 __emit 0x1 __emit 0xdb __emit 0x75
__emit 0x7 __emit 0x8b __emit 0x1e __emit 0x83 __emit 0xee __emit 0xfc __emit 0x11 __emit 0xdb __emit 0x11 __emit 0xc0 __emit 0x1 __emit 0xdb __emit 0x73 __emit 0xef __emit 0x75 __emit 0x9 __emit 0x8b __emit 0x1e __emit 0x83 __emit 0xee __emit 0xfc __emit 0x11 __emit 0xdb __emit 0x73 __emit 0xe4 __emit 0x31 __emit 0xc9 __emit 0x83 __emit 0xe8 __emit 0x3 __emit 0x72 __emit 0xd __emit 0xc1 __emit 0xe0 __emit 0x8 push eax popad call main } }
ํด๋น ์ฝ๋๋ฅผ ์ปดํ์ผ ํ ๋, EP ๋ฅผ fake ํจ์๋ก ์ค์ ํ๊ธฐ ์ํด์ /ENTRY:fake ๋ผ๋ ์ต์ ์
๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
ํด๋น ํ๋ก๊ทธ๋จ์ PEID ๋ก ์ด์ด scan ์ ํด ๋ณด๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
UPX 0.89.6 - 1.02 / 1.05 - 2.90 -> Markus & Laszlo
4. Conclusion ์ง๊ธ๊น์ง ์ฌ๋ฌ ์ํฐ ๋๋ฒ๊น , ์ด์ ๋ธ๋ฆฌ, ๋คํ ๋ฑ ์ฌ๋ฌ ๊ธฐ๋ฒ๋ค์ ์์๋ณด์๋ค.
์์์ ์๊ฐํ ๊ธฐ๋ฒ๋ค์ ๋ํ ์ฝ๊ฐ ๋น๊ด์ ์ธ ์ด์ผ๊ธฐ๋ฅผ ํ์๋ฉด ๋๋ถ๋ถ์ด ์ด๋ฏธ ์ค๋์ ์
๋ฐ๊ฒฌ ๋ฌ๊ฑฐ๋ ๋ํ ์ด๋ฅผ ์๋์ผ๋ก ์ฐํํด ์ฃผ๋ ๋๋ฒ๊ฑฐ๋ค์ ํ๋ฌ๊ทธ์ธ(ex) idastealth,
ollyadvance)๋ค๋ ๋ง์ด ์๊ธด ์ง ์ค๋๋ค. ๊ทธ๋์ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ ๋ง์ผ๋ก๋ ํ์คํ
ํจ๊ณผ๋ฅผ ๋ณด๊ธฐ๋ ์ด๋ ต๋ค. ๊ทธ๋์ ํจ์ปค์์ ์ถ๊ฐํด ์ฃผ๋ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ์ ๋ฐ๋ก ์น๋ฉด ์ฃผ๋ก
์ ์ฑ์ฝ๋์์ ์ฌ์ฉ๋๋ ์ํฐ ๋๋ฒ๊น ๊ธฐ๋ฒ์ผ๋ก๋ API ํํน์ ๋ฐฉ์งํ๊ธฐ ์ํ Anti-Hook ์
์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ breakpoint ๋ฅผ scanning ํ๋ ์ฝ๋๋ค ์ ๋ ๋ฑ ์ธ๊ฑฐ ๊ฐ๋ค.
๋ํ ์ฝ๋ ๊ฐ์ํ์ Anti Dumping, Packing, Anti Sandbox, VM ๋ฑ์ ์ฝ๋๋ค์ด
์ฌ์ฉ๋๋ ์ถ์ธ์ด๋ค. ์ค์ ๋ก ๋ฉ์จ์ด๋ค์ ๋ถ์ํ๋ค ๋ณด๋ฉด ์์ ๊ฐ์ ๊ธฐ๋ฅ๋ค์ด ๊ตฌํ๋ ๊ฒ๋ค์
ํํ ๋ณผ ์ ์๋ค.
๋ํ ์ด๋ฒ ๋ฌธ์์์๋ ์๋์ฐ๋ฅผ ์ค์ฌ์ผ๋ก ๋ง์ด ๋ค๋ค๋๋ฐ ๋ฌผ๋ก ๋ค๋ฅธ ํ๋ซํผ์์๋ ๋ค์ํ
์ํฐ ๋ฆฌ๋ฒ์ฑ ๊ธฐ๋ฒ๋ค์ด ์กด์ฌํ๊ณ ์ฌ๋ฐ๋ ๊ธฐ๋ฒ๋ค๋ ๋ง๋ค.
5. Reference - PEB Structure :
- https://msdn.microsoft.com/en-us/library/windows/desktop/aa813706(v=vs.85).aspx
- NtQueryInformationProcess :
- https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx
- OutputDebugString :
- https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362(v=vs.85).aspx
- OutputDebugString โ new :
- https://ntquery.wordpress.com/2015/09/07/windows-10-new-anti-debug-
outputdebugstringw/#more-32
- BlockInput :
- http://ezbeat.tistory.com/357
- DeleteFiber :
- https://msdn.microsoft.com/en-us/library/windows/desktop/ms682556(v=vs.85).aspx
- Anti-Reversing Techniques :
- http://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide
- http://pferrie.host22.com/papers/antidebug.pdf
- http://www.slideshare.net/tylerxshields/antidebugging-a-developers-view
- Anti-VM :
- http://blog.cyberbitsolutions.com/anti-vm-and-anti-sandbox-explained/
- Stolen Bytes & Nanomites :
- http://resources.infosecinstitute.com/anti-memory-dumping-techniques/