μν μ 보 : "Malware Bytes" λ°±μ νμ¬μμ 곡κ°ν μ μ±μ½λ λΆμ νλ ¨μ© μν
νμΈν μ 보
- Anti-debugging, Anti-VM λ± λΆμ λ°©ν΄ κΈ°λ₯
- λ°μ΄ν°μ μΈμ½λ©/λμ½λ©
- νλ‘μΈμ€ ν λ‘μ κΈ°λ²
1. λμ λΆμ - μν μ€ν κ²°κ³Ό νμΈ
μν μ€ν μ μμ κ°μ μ€ν κ²°κ³Όκ° λ³΄μ¬μ§λ€.
μμΈ λΆμμμλ x64dbgλΌλ λλ²κ±°λ₯Ό ν΅ν΄ λΆμμ μ§ννλ€.
2. λ¬Έμμ΄ κ²μ
μμμ λμ λΆμμ νμΈνλ λ¬Έμμ΄ "I am so sorry, you failed! :("μ μ°Ύμμ (λΆμμ νμν) μμ μμΉλ₯Ό νμΈνλ€.
[λ€μμ μ°ΎκΈ°] → [νμ¬ λͺ¨λ] → [λ¬Έμμ΄ μ°Έμ‘°]
"I am so sorry, you failed! :(" νμΈ
[λ€νν΄μ λ°λΌκ°κΈ°]λ‘ λΆμμ νμν μμΉλ‘ μ΄λ
μ νκ° μ·¨ν΄μ§κΈ° μ (jne)μ μ€λ¨μ (F2)μΌλ‘ μ€μ
3. μν° λλ²κΉ
jne(jump not equal) μ call ν¨μ (call 0x004085E9, call 0x004014F0)λ₯Ό νμΈνλ€.
0X004014F0 ν¨μμμ rdtsc λͺ λ Ήμ΄λ₯Ό μ¬μ©νμ¬ μ€νλλ μκ°μ μ μ₯νλ κ²μ΄ νμΈλμλ€.
call 0x004014F0 ν¨μ νμΈ.
λ κ°μ§ 체ν¬ν μ¬νμ΄ νμΈλλ€.
rdtsc λͺ λ Ήμ΄ μ¬μ©μ ν΅ν΄ μ€ν μκ° μ 보λ₯Ό eaxμ edxμ μ μ₯νμ¬ 8κ°μ ν¨μλ₯Ό μ§λκ° νμ call 0x401BC0μμ λΉκ΅νλ€.
function #1: call 0x4019D0 - λΆμ
β IsDebuggerPresent() μ¬μ©
IsDebuggerPresent()λ μ§κΈ λμ μ€μΈ μμ€ν μ΄ λλ²κ±° λͺ¨λλ‘ μ€νμ€μΈμ§ νλ¨νλ APIμ΄λ€.
μ΄ APIλ₯Ό ν΅ν΄ λλ²κΉ λͺ¨λ μ¬λΆλ₯Ό νλ¨νμ¬ λλ²κΉ μ€μ΄λ©΄ eaxμ 1μ μ μ₯νλ€. κ·Έ ν test λͺ λ Ήμ΄λ‘ eaxλ₯Ό κ²μ¬νμ¬ (λλ²κΉ → ZF = 0) CMOVNE λͺ λ Ήμ΄λ‘ ZFκ° 0μ΄λ©΄ ESIμ 1μ΄ μ μ₯λλ€.
β CheckRemoteDebuggerPresent μ¬μ©
CheckRemoteDebuggerPresent()λ λ°ν κ°μ΄ 0μ΄λ©΄ μ μ.
CheckRemoteDebuggerPresent() APIλ₯Ό ν΅ν΄ λλ²κΉ λͺ¨λ μ¬λΆλ₯Ό νλ¨νμ¬ λλ²κΉ μ€μ΄λ©΄ eaxμ [ebp-4]μ μμΉμ 1μ΄ μ μ₯λλ€. λΉκ΅λ₯Ό ν΅ν΄ νμ¬ λλ²κΉ μ€μ΄λ©΄ ESI κ°μ΄ 1λ‘ μ¦κ° λλ€. ESIκ° 2μ΄λ©΄ ZFκ° 1λ‘ μ€μ λλ€(βμ βλ₯Ό κ±°μ³ 2λ‘ λλ€). sete λͺ λ Ήμ΄λ‘ ZFκ° 1μ΄λ©΄ eaxλ₯Ό 1λ‘ μ€μ νκ³ , μλλ©΄ eaxκ° 0μ΄ λλ€
β νλκ·Έ κ° μ€μ
μμ λ λ¨κ³ β, βλ₯Ό κ±°μ³μ νμ¬ λλ²κΉ μ€μΈμ§ νλ¨νμ¬, λλ²κΉ μ€μ΄λΌλ©΄ β λΆλΆμ΄ μ€νλλ€.
μ΄ λΆλΆμ νλ ¨μ© μνμ΄λΌμ νΉμ μ£Όμμ νλκ·Έ κ°μ μ€μ νκ³ μλ€. [429F74]μ μν°λλ²κΉ κΈ°λ²μ μ°Ύμ νμλ₯Ό μ μ₯νμλ€.
function #1: call 0x4019D0 - μν° λλ²κΉ μ°ν
9κ°μ ν¨μλ€μ λΆμ μ€μ 곡ν΅λ νΉμ§ νλλ₯Ό λ°κ²¬νμλ€. λͺ¨λ ν¨μμμ je(ifλ¬Έ)μ κ±°μ³μ [429F74]λ₯Ό νΈμΆνμ¬ λ¬΄μΈκ°λ₯Ό μ μ₯νλ€.
μ΄ je(ifλ¬Έ)μμ μ νκ° μ·¨ν΄μ§μ§ μλλ‘ jeλ₯Ό μ΄μ λΈμ ν΅ν΄ ‘nop’μνλ‘ μΈμ½λ© ν΄μ£Όμλ€. λ€μ λλ¨Έμ§ 8κ°μ ν¨μλ€μμλ λμΌνκ² ‘nop’μΌλ‘ μΈμ½λ©νμ¬ μ νκ° μ·¨ν΄μ§μ§ μκ³ μ°¨λ‘λλ‘ λμλκ² νμλ€.
function #2: call 0x401A50 - λΆμ
β RaiseException() μ¬μ©
RaiseException() ν¨μ: λ§€κ°λ³μ 0x40010006λ₯Ό μ¬μ©νλ κ²½μ° λλ²κΉ μ¬λΆλ₯Ό νλ¨νμ¬ λλ²κΉ μ€ μΌ κ²½μ° μμΈκ° λ°μνμ¬ νμ¬ μμ€ν μ΄ λλ²κΉ λͺ¨λμΈμ§ νμ ν μ μλ€
β SHE νΈλ€λ¬ μ€μ
SEH νΈλ€λ¬λ₯Ό μ€μ νλ©΄ μμΈμ¬νμ΄ λ°μν λ SEHλ‘ νλ¦μ΄ λ°λλ€.
μ¬κΈ°μμλ SEH νΈλ€λ¬ μ£Όμ λ₯Ό 0X408EE0μΌλ‘ μ€μ νμλ€.
μ΄ μ½λκ° ν¬ν¨λ ν¨μ ꡬκ°μμ μ€λ₯κ° λ°μνλ©΄ 0x408EE0μ μ½λκ° μνλλ€.
βμμ RaiseException() ν¨μλ₯Ό νΈμΆνλ©΄ μμΈμ¬νμ΄ λ°μνμ¬ μ΄ μ£Όμλ‘ μ΄λνλ€.
μμΈ μ¬νμ ννΌνλ©΄ β λΆλΆ λ§μ§λ§ μ½λμΈ “jmp 0x401AAA”λ‘ μ΄λνκ³ νλκ·Έ κ°μ μ€μ νλ€. 0x429F74 κ°μ λ€μ 1 μ¦κ°λλ€
function #2: call 0x401A50 - μν° λλ²κΉ μ°ν
function #3: call 0x401B00 - λΆμ
β GetThreadContext() ν¨μ μ¬μ©
- getThreadContext() : νμ¬ μ€νμ€μΈ μ°λ λμ λν 컨ν μ€νΈλ₯Ό κ°μ Έμ μμ
- OpenThread()λ‘ λ°μμ¨ νΈλ€κ³Ό [edp-2D0] μ£Όμλ₯Ό λ§€κ°λ³μλ‘ μ λ¬
- ContextFlags [edp-2D0]λ 0x10010μ΄κ³ , 4byteμ© λ€μ μ£Όμκ° DR0~DR3 λ μ§μ€ν°μ
- DR0λΆν° DR3κΉμ§ νλλΌλ μ€λ¨μ μ΄ μ€μ λμ΄ μμΌλ©΄ ecxκ° 0μ΄ μλ κ°μ κ°μ§
β νλκ·Έ 루ν΄
- OR μ°μ° κ²°κ³Ό ecxκ° 0μ΄ μλλ©΄ ZFκ° 0μ΄ λ¨
- SETNE λͺ λ ΉμΌλ‘ ebxμ 1μ΄ μ μ₯ / ebxκ° 1(zf=0)μ΄λ©΄, eaxμ 1μ΄ μ μ₯
- κ²°κ΅ λλ²κΉ μ€μ΄λ©΄ μλ μ½λκ° μ€νλμ§ μμ / [0x429F74] κ°μ λ€μ 1μ¦κ°
function #3: call 0x401B00 - μν° λλ²κΉ μ°ν
function #4: call 0x401C20 - λΆμ
β PEB ꡬ쑰체μ λ©€λ²λ₯Ό ν΅ν μν° λλ²κΉ νμ§
- PEB ꡬ쑰체μ λ©€λ² λ³μλ‘ λλ²κ±°μ λμ μ 무λ₯Ό νμ§
- 0x02 : BeingDebugged (1byte) / 0x68 : NtGlobalFlag (4byte)
- PEB ꡬ쑰체λ fs:[30]μ μμ
- 0x68λ²μ§Έ κ°μ΄ 0μ΄ μλλ©΄ ecx = 1
- 0x02λ²μ§Έ κ°μ΄ 0μ΄ μλλ©΄ ecx κ°μ 1 μ¦κ°
β νλκ·Έ 루ν΄
- ecxκ° 2μ΄λ©΄ eaxκ° 1λ‘ μ€μ λ¨
- eaxκ° 1μ΄ μλλ©΄ νλκ·Έ 루ν΄μ΄ μνλμ§ μμ
- [0x429F74] κ°μ λ€μ 1μ¦κ°
function #4: call 0x401C20 - μν° λλ²κΉ μ°ν
4. μν° κ°μλ¨Έμ
QueryDosDevice() API νμ©
MS-DOS μ₯μΉ μ 보λ₯Ό κ°μ Έμ€κ±°λ VBoxMinRdrDN, VBoxGuestμ κ°μ κ°μλ¨Έμ μ₯μΉμ΄λ¦μ΄ ν¬ ν¨λμ΄ μλμ§ νμΈ
κ°μλ¨Έμ λ¬Έμμ΄μ΄ μμΌλ©΄ μ½κ² μν° κ°μλ¨Έμ κΈ°λ²μ΄ μ¬μ©λλμ§λ₯Ό μ μ μμ
→ μ€μν λ¬Έμμ΄μ ν΄μκ°μΌλ‘ νν
function #5: call 0x402730 - λΆμ
β λ¬Έμμ΄ ν΄μκ° μ²λ¦¬
- λ¬Έμμ΄ (VBoxMiniRdrDN) ν΄μ μ²λ¦¬
- λ¬Έμμ΄ (VBoxGuest) ν΄μ μ²λ¦¬
function #5: call 0x402730 - μν° λλ²κΉ μ°ν
2.3.2 function #6: call 0x402880 - λΆμ
β Virtual Boxμ κ΄λ ¨λ λ μ§μ€νΈλ¦¬ ν€ νμΈ
- RegOpenKeyA() APIλ₯Ό μ¬μ© -> λ μ§μ€νΈλ¦¬ ν€μ μ 보 νμΈ
β κ°μλ¨Έμ κ³Ό λλ²κΉ κ΄λ ¨ λͺ¨λ νμ§
- CreateToolhelp32Snapshot() API μ¬μ© – 32bit νλ‘μΈμ€μ μ€λ μ·μ κ°μ Έμ΄
: νμ¬ νλ‘μΈμ€μ μ 보λ₯Ό κ°μ Έμ΄
- Module32First() API μ¬μ© – νλ‘μΈμ€μ κ΄λ ¨λ 첫 λͺ¨λ μ 보λ₯Ό κ²μ
: λͺ¨λ μ 보μ ν΄μκ°μ λ³ννκ³ Module32First()ν¨μμ Module32Next()ν¨μλ‘ κ²μ
→ λ APIλ₯Ό μ¬μ©νμ¬ νμ¬ νλ‘μΈμ€μ μ€λ μ·μ κ°μ Έμμ νλ‘μΈμ€ μ 보μμ νΉμ μ΄λ¦μ νλ‘ μΈμ€λ₯Ό νμΈνμ¬ κ°μνκ²½ κ΄λ ¨λ νλ‘μΈμ€μ μ‘΄μ¬μΈμ§ νμΈνλ€.
function #6: call 0x402880 - μν° λλ²κΉ μ°ν
function #7: call 0x402B70 – λΆμ
Module32First
function #7: call 0x402B70 - μν° λλ²κΉ μ°ν
function #8: call 0x402DE0 – λΆμ
Process32First
function #8: call 0x402DE0 - μν° λλ²κΉ μ°ν
function #9: call 0x401BC0 - λΆμ
κ²½κ³Όμκ° λΉκ΅
function #9: call 0x401BC0 - μν° λλ²κΉ μ°ν
5. rdtsc λͺ λ Ήμ΄λ‘ κ²½κ³Ό μκ° λΉκ΅ (μν° λλ²κΉ )
6. νμΌ ν¨μΉ
9κ° ν¨μλ₯Ό λ€ μ°ννκ³ λλ©΄ νμΌ ν¨μΉλ₯Ό ν΅ν΄ μ νμΌ μμ±
첫 λ²μ§Έ μ°ν κ²°κ³Ό
λ λ²μ§Έ μ°νμ ννΈλ‘ μ¬μ©ν μ μλ λ¬Έμμ΄ “You are on the right track!” λ©μμ§ λ°μ€ νμΈ
7. ν¨μΉ νμΌλ‘ λλ²κΉ μ§ν
μμμ μ»μλ μμ΄ κ²μνμ¬ ν΄λΉ μμΉλ‘ μ΄λ
μμμ 1μ°¨ λλ²κΉ μ°νλ‘ μ»μλ λ λ²μ§Έ λ©μμ§λ°μ€μ “Better luck next time!”μ ννΈλ‘ ν΄λΉ λ¬Έμμ΄ μμΉλ‘ μ΄λνμ¬ κ·Έ μμΉμμ μ€λ¨μ (f2)μ κ±Έμ΄μ€λ€.
λλ²κΉ λ€μ μ§ν
첫 λ²μ§Έ λ¬Έμμ΄ “I am so sorry...”κ° λμ€κΈ° μ jneμ μν° λλ²κΉ μ΄ λμνλ call ν¨μμλ μ€λ¨ μ (f2)μ 건 νμ μ€νμμΌλ³΄μλ€
μνΈν μνμλ url κ°μ΄ μ°ννκ³ μ§λμ¨ νμ 볡νΈνλ κ²μ νμΈλμλ€.
ν΄λΉ urlμ 볡μ¬νμ¬ μΈν°λ· μ£Όμμ°½μ μ λ ₯νλ©΄ λ€μκ³Ό κ°μ΄ μνΈν(XOR)λ μ μ±μ½λκ° λ¨λ κ²μ λ³Ό μ μλ€.
볡νΈν λ°©λ²μ λ°λ‘ μκ² μ§λ§, μ¬κΈ°μλ 미리 μκ³ μλ νΉμ λ°μ΄ν°λ₯Ό μ¬μ©νμ¬ XOR 볡νΈνλ₯Ό μ ννλ€. λ©λͺ¨μ₯μ μΌμ malwarebytes λΌκ³ μ λ ₯ν ν 볡μ¬νκΈ°λ₯Ό ν΅ν΄ ν΄λ¦½λ³΄λμ μ μ₯ν΄μ€λ€.
λ³΅μ¬ ν λλ²κΉ μ λ€μ μ€νν΄λ³΄λ©΄ “You are one the right track!” λ¬Έμμ΄ μμΉκΉμ§ λλ²κΉ μ΄ μ€ νλμλ€.
κ·Έλ¦¬κ³ μλ μμμ λ΄€λ μ μ±μ½λλ€μ΄ λ€μ΄λ‘λ λ κ² λν νμΈν μ μλ€.
8. νλ‘μΈμ€ ν λ‘μ κΈ°λ²
κ·Έ μ μ [λ€μμ μ°ΎκΈ°] → [νμ¬ λͺ¨λ] → [λͺ¨λκ° νΈμΆ]μ ν΅ν΄ μ΄ νλ‘κ·Έλ¨μμ μ¬μ©λλ λͺ¨λλ€ μ νμΈν΄λ³΄μλ€. setThreadContext / ResumeThread λ±μ νμΈν μ μλ€.
- setThreadContext : νμ¬ μ€νμ€μΈ μ°λ λμ λν 컨ν μ€νΈλ₯Ό κ°μ Έμμ μμ
- ResumeThread : νμ¬ μ°λ λλ₯Ό μ€μ§/μ¬μμ
ν΄λΉ λͺ¨λ μμΉλ‘ μ΄λνμ¬ μ€λ¨μ μ κ±Έμ΄μ€λ€
μ€λ¨μ μ 건 ν κ³μ μ€ννλ€λ³΄λ©΄ SetThreadContextκΉμ§ μ€νμ μ΄ μ¨ κ²μ νμΈν μ μλ€.
μμμ λ΄€λ μ μ±μ½λμ μνΈκ° νλ Έλ€λ κ²μ΄λ€.
Suspend λͺ¨λλ‘ νλ‘μΈμ€ μ€ν
Suspend λͺ¨λλ‘ rundll32.exeλ₯Ό μ€ννλ€.
μ¬μ©μ νλ‘μΈμ€μ μ§μ μ μ°ΎκΈ°
μ€λ¨λ νλ‘μΈμ€λ₯Ό λλ²κΉ νλ €λ©΄ Suspend μνμ rundll32.exe νλ‘μΈμ€λ₯Ό λλ²κ±°λ‘ λΆμ°©νκ³ μ€ λ¨μ μ EPμ μ€μ νλ€.
EIP μμ νκ³ κ³μ μννκΈ°
λλ²κ±°μ λΆμ°©λ rundll32.exe μ€λ¨μ μ μ€μ νλ€
μ€λ¨μ μ€μ ν λ€μ sample.exe λλ²κ±°λ‘ λμμμ μ΄μ΄μ μ€νν΄λ³΄λ©΄ rundll32.exe λλ²κ±° λ΄μ© μ΄ λ¬λΌμ§ κ²μ νμΈν μ μλ€.
- SetThreadContext() APIλ₯Ό μ¬μ©νμ¬ PEμ EPκ° μ μ₯λ μ°λ λ 컨ν μ€νΈλ₯Ό λ³κ²½
- ResumeThread() APIλ₯Ό μ¬μ©νμ¬ μ€λ¨λμλ μλ‘μ΄ rundll32.exe νλ‘μΈμ€λ₯Ό μ€ν
9. μ±κ³΅ λ©μμ§ μΆλ ₯
μ±κ³΅ λ©μμ§ μΆλ ₯ 쑰건
- νμ¬ λλ²κΉ μ€μΈ “rundll32.exe”μ΄ system32 κ²½λ‘μΈμ§ νμΈ
- μ€ν μ€μΈ νλ‘μΈμ€μ μλμ° μ΄λ¦ μ€ νλ‘μΈμ€ μ΅μ€νλ‘(“procexpl.exe”)κ° μλμ§ νμΈ
- μ λ 쑰건μ λ§μ‘±νλ©΄ “rundll32.exe”λ νλ‘μΈμ€ μ΅μ€νλ‘λ¬μ μμ½λλ₯Ό μΈμ μ μμΌ μ€ν
μΈμ μ μ μ±κ³΅νλ©΄ λ€μκ³Ό κ°μ΄ μ±κ³΅λ©μμ§κ° νλ‘μΈμ€ μ΅μ€νλ‘λ¬λ₯Ό ν΅ν΄ μ€νλ κ²μ νμΈν μ μλ€.