ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • μ•ˆν‹° 리버싱 :: 04 - μ•ˆν‹° 디버깅 기법듀 μ†Œκ°œ
    SECURITY/REVERSING 2020. 8. 5. 12:09

    μ•žμ„œ μ•ˆν‹° 디버깅에 λŒ€ν•œ κ°„λ‹¨ν•œ 예제λ₯Ό μ‚΄νŽ΄λ³΄μ•˜λ‹€.

    2020/08/04 - [SECURITY/REVERSING] - μ•ˆν‹° 리버싱 :: 03 - μ•ˆν‹° 디버깅 예제

     

     

    μ΄μ œλŠ” μ•ˆν‹° 디버깅에 λŒ€ν•œ 이둠적인 것듀을 κ°„λ‹¨ν•˜κ²Œ κ°œλ…μ μœΌλ‘œ 정리해볼 것이닀.

     

    λŒ€λ‹€μˆ˜ μ•ˆν‹° 디버깅 기법은 FS:[0x30] 에 μ ‘κ·Όν•΄ μœˆλ„μš° API λ₯Ό μ΄μš©ν•˜κ±°λ‚˜, 

    λ””λ²„κΉ…ν•˜λ©΄ κ·Έλƒ₯ μ‹€ν–‰ν–ˆμ„ λ•Œλ³΄λ‹€ μ‹€ν–‰ μ‹œκ°„μ΄ 길어짐을 μ΄μš©ν•˜μ—¬ μ‹œκ°„μ„ κ²€μ‚¬ν•˜λŠ” 기법을 자주 μ‚¬μš©ν•œλ‹€.

     

     

     

     

    ------------------- λͺ©μ°¨ -------------------

     

    1. Windows API 

    1.1 IsDebuggerPresent
    1.2 CheckRemoteDebuggerPresent

    1.3 NTQueryInformationProcess

    1.4 OutputDebugString

    1.5 FindWindow

     

    2. structure (ꡬ쑰체) λ₯Ό μˆ˜λ™μœΌλ‘œ 검사

    2.1 BeingDebugged ν”Œλž˜κ·Έ

     

    3. λ””λ²„κ±°λ‘œ μ‹€ν–‰ν•  λ•Œ ν”„λ‘œμ„ΈμŠ€μ— λ―ΈμΉ˜λŠ” λ³€ν™”λ₯Ό 감지

    3.1 INT

    3.2 Checksums

    3.3 μ‹œκ°„ 체크

     

    4. TLS Callback

     

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

     

     

     

     

    1. Windows API 

     

     

    1.1 IsDebuggerPresent

    https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-isdebuggerpresent

     

    μ•žμ„  μ˜ˆμ œμ—μ„œ μ‚΄νŽ΄λ³Έ, κ°€μž₯ κ°„λ‹¨ν•œ 디버거 탐지 μœˆλ„μš° API ν•¨μˆ˜μ΄λ‹€.

    이 ν•¨μˆ˜λŠ” PEB κ΅¬μ‘°μ—μ„œ IsDebugged ν•„λ“œλ₯Ό μ°Ύμ•„ 디버그가 λ™μž‘ 쀑인지 νŒλ‹¨ν•˜μ—¬ λ™μž‘ 쀑이 μ•„λ‹ˆλΌλ©΄ 0을, λ™μž‘ 쀑이라면 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

     

    ** PEB λŠ” FS λ ˆμ§€μŠ€ν„°λ₯Ό 톡해 μ ‘κ·Ό κ°€λŠ₯. TEB 의 0x30 이 PEB λ₯Ό 가리킴

      --> FS:[0x30] 이라 λ˜μ–΄μžˆμœΌλ©΄ PEB λ₯Ό κ°€λ¦¬ν‚€λŠ” 것

    ** TEB, PEB λž€?

    더보기

    * TEB (Therad Environment Block)

    : win32 의 자료 κ΅¬μ‘°λ‘œμ„œ, ν˜„μž¬ μ‹€ν–‰ 쀑인 μŠ€λ ˆλ“œμ— λŒ€ν•œ 정보λ₯Ό μ €μž₯ν•˜κ³  μžˆλ‹€.

    λ‹€μ–‘ν•œ μœˆλ„μš° DLL 에 λŒ€ν•œ μ»¨ν…μŠ€νŠΈ 정보λ₯Ό λ‹΄κ³  μžˆλ‹€.

    이 μš”μ†Œλ“€μ΄ μœ μ € λͺ¨λ“œμ—μ„œ κ΅¬λ™λ˜λ―€λ‘œ μœ μ € λͺ¨λ“œμ—μ„œ μ“°κΈ°κ°€ κ°€λŠ₯ν•œ ꡬ쑰체가 ν•„μš”ν–ˆλ‹€.

    κ·Έλž˜μ„œ 이 κ΅¬μ‘°μ²΄λŠ” 컀널 λͺ¨λ“œμ—μ„œλ§Œ μ“°κΈ°κ°€ κ°€λŠ₯ν•œ μ‹œμŠ€ν…œ μ£Όμ†Œ 곡간이 μ•„λ‹Œ ν”„λ‘œμ„ΈμŠ€ μ£Όμ†Œ 곡간에 μœ„μΉ˜ν•œλ‹€. 

     

    * PEB (Process Environment Block)

     

    : μœˆλ„μš° NT μ—μ„œμ˜ 데이터 ꡬ쑰체.

    운영체제 λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•˜λŠ” ꡬ쑰체둜, 이미지 λ‘œλ”, 힘 κ΄€λ¦¬μž, μœˆλ„μš° μ‹œμŠ€ν…œ DLL λ“± μœ μ € λͺ¨λ“œ μƒμ—μ„œ μ ‘κ·Όν•  ν•„μš”κ°€ μžˆλŠ” 정보λ₯Ό 가지고 μžˆλ‹€.

     

    (NT ZW ?? -> https://blog.naver.com/stgavriel/80044878343)

     

     

    + FS λ ˆμ§€μŠ€ν„°

    : 컀널 λͺ¨λ“œμ—μ„œλŠ” KPCR(Kernel's Processor Control Region) ꡬ쑰체λ₯Ό,

    μœ μ € λͺ¨λ“œμ—μ„œλŠ” TEB ꡬ쑰체λ₯Ό 가리킀고 μžˆλ‹€.

     

    λ”°λΌμ„œ

    FS:[0] 은 TEB 의 μ‹œμž‘ μœ„μΉ˜, 

    FS:[0x30] 은 PEB 의 μ‹œμž‘ μœ„μΉ˜λ₯Ό 의미

     

    μ‹€μ œλ‘œ ν•¨μˆ˜ 싀행에 듀어가보면 FS:[30] 으둜 PEB κ΅¬μ‘°μ²΄μ—μ„œ +2 λ₯Ό ν•˜μ—¬ BeingDebugged λ₯Ό ν™•μΈν•˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.

     

     

     

    1.2 CheckRemoteDebuggerPresent

    https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-checkremotedebuggerpresent

     

    PEB ꡬ쑰의 IsDebugged ν•„λ“œλ₯Ό ν™•μΈν•˜λ©° IsDebuggerPresent 와 거의 λ™μΌν•œ κΈ°λŠ₯을 ν•œλ‹€. 

    λ‹€λ§Œ μžμ‹ μ΄λ‚˜ 둜컬 μ»΄ν“¨ν„°μ˜ ν”„λ‘œμ„ΈμŠ€μ— λŒ€ν•΄μ„œλ§Œ 검사할 수 μžˆλ‹€.

     

    νŒŒλΌλ―Έν„°λ‘œ ν”„λ‘œμ„ΈμŠ€ 헨듀을 λ°›μ•„ ν”„λ‘œμ„ΈμŠ€κ°€ 디버거 ν™˜κ²½μ—μ„œ μ‹€ν–‰ 쀑인지λ₯Ό νŒλ‹¨ν•œλ‹€.

     

    Use the IsDebuggerPresent function to detect whether the calling process is running under the debugger.

     

     

    1.3 NTQueryInformationProcess

    https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess

     

    첫 번쨰 νŒŒλΌλ―Έν„°λ‘œ ν”„λ‘œμ„ΈμŠ€ 헨듀을, 두 번째 νŒŒλΌλ―Έν„°λ‘œ μ–»κ³ μž ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€ μ •λ³΄μ˜ νƒ€μž…μ„ μš”κ΅¬ν•œλ‹€.

    두 번째 νŒŒλΌλ―Έν„°μΈ ProcessInformationClass 에 ProcessDebugPort(0x7) 을 μ€€λ‹€λ©΄ ν•΄λ‹Ή ν”„λ‘œμ„ΈμŠ€κ°€ 디버깅 쀑인지에 λŒ€ν•œ μ—¬λΆ€λ₯Ό λ°˜ν™˜ν•œλ‹€.

     

    디버깅 쀑이라면 0, μ•„λ‹ˆλ©΄ 디버거 포트 번호λ₯Ό λ°˜ν™˜ν•œλ‹€.

     

    (NT ZW ?? -> https://blog.naver.com/stgavriel/80044878343)

     

     

    1.4 OutputDebugString

    https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-outputdebugstringw

     

    디버거에 좜λ ₯ν•  λ¬Έμžμ—΄μ„ μ „λ‹¬ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” ν•¨μˆ˜μ΄λ―€λ‘œ λ””λ²„κ±°μ˜ 쑴재λ₯Ό νƒμ§€ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆλ‹€.

     

    이 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν–ˆλŠ”λ° 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ λ””λ²„κ±°λ‘œ μ‹€ν–‰μ€‘μ΄λΌλŠ” μ˜λ―Έμ΄λ‹€.

     

     

    1.5 FindWindow

    https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa

     

    νŠΉμ • ν”„λ‘œκ·Έλž¨(디버그)κ°€ μ‹€ν–‰λ˜κ³  μžˆλŠ”μ§€ 검색할 수 μžˆλ‹€.

    첫번째 νŒŒλΌλ―Έν„°λ‘œ 검색할 ν”„λ‘œκ·Έλž¨(디버그) 이름을 μ£Όκ³ , 만일 ν•΄λ‹Ή ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰ 쀑이라면 κ·Έ 헨듀을, μ‹€ν–‰ν•˜κ³  μžˆμ§€ μ•Šλ‹€λ©΄ NULL 값을 λ°˜ν™˜ν•œλ‹€.

     

    ex. FindWindow("OllyDbg", NULL)

     

     

     

    2. Structure (ꡬ쑰체) λ₯Ό μˆ˜λ™μœΌλ‘œ 검사

     

    PEB κ΅¬μ‘°μ²΄μ—μ„œ 디버거가 μ‘΄μž¬ν•˜λŠ”μ§€μ— λŒ€ν•œ 정보λ₯Ό μ œκ³΅ν•œλ‹€.

     

    운영 μ²΄μ œλŠ” μ‹€ν–‰ 쀑인 각 ν”„λ‘œμ„ΈμŠ€μ— λŒ€ν•΄ μœˆλ„μš° PEB ꡬ쑰체λ₯Ό κ΄€λ¦¬ν•œλ‹€.

    ν™˜κ²½ λ³€μˆ˜ κ°’, λ‘œλ“œλœ λͺ¨λ“ˆ λͺ©λ‘, λ©”λͺ¨λ¦¬ μ£Όμ†Œ, 디버거 μƒνƒœ λ“±μ˜ ν”„λ‘œμ„ΈμŠ€ ν™˜κ²½ 데이터λ₯Ό ν¬ν•¨ν•œλ‹€.

     

    ν”„λ‘œμ„ΈμŠ€ μ‹€ν–‰ 쀑에 FS:[0x30] 으둜 PEB λ₯Ό μ ‘κ·Όν•  수 μžˆλ‹€.

    https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb

     

    2.1 BeingDebugged ν”Œλž˜κ·Έ

     

    이 ν”Œλž˜κ·ΈλŠ” PEB ꡬ쑰체의 μ˜€ν”„μ…‹ 2에 μžˆλ‹€. (0x2) (ν–₯ν›„ μœˆλ„μš° 버전에 따라 λ³€κ²½ κ°€λŠ₯)

    이 ν”Œλž˜κ·Έ 값이 0 이면 디버거가 λ™μž‘ν•˜κ³  μžˆμ§€ μ•Šλ‹€λŠ” 것이고, 1 이면 디버거가 λ™μž‘ν•˜κ³  μžˆλ‹€λŠ” λœ»μ΄λ‹€.

     

     

    그리고 λ‹€λ₯Έ ν”Œλž˜κ·Έλ“€μ΄ μ‘΄μž¬ν•˜μ§€λ§Œ, ν–₯ν›„ μœˆλ„μš° 버전에 μ˜ν•΄ ꡬ쑰가 λ‹¬λΌμ§ˆ 수 μžˆμœΌλ―€λ‘œ ν•΄λ‹Ή λ¬Έμ„œλ₯Ό μ°Έμ‘°ν•˜κΈΈ λ°”λž€λ‹€.

     

     

    3. λ””λ²„κ±°λ‘œ μ‹€ν–‰ν•  λ•Œ ν”„λ‘œμ„ΈμŠ€μ— λ―ΈμΉ˜λŠ” λ³€ν™”λ₯Ό 감지

     

    3.1 INT 3

     

    INT 3 λŠ” μ†Œν”„νŠΈμ›¨μ–΄ BP λ₯Ό μ„€μ •ν•˜λŠ” κΈ°λ³Έ λ©”μ»€λ‹ˆμ¦˜μ΄λ‹€.

     

    INT 3 의 OPCODE λŠ” 0xCC 둜, 이 OPCODE λ₯Ό κ²€μƒ‰ν•˜μ—¬ 본래의 μ½”λ“œκ°€ INT 3 둜 λ³€κ²½λ˜μ—ˆλŠ”μ§€ ν”„λ‘œμ„ΈμŠ€λ₯Ό μŠ€μΊ”ν•œλ‹€.

    0xCC κ°€ 발견되면 디버거가 μ‘΄μž¬ν•œλ‹€λŠ” λœ»μ΄λ‹€.

     

    ν˜Ήμ€ μ½”λ“œμ— INT 3 ꡬ문이 μžˆμ„ λ•Œ, λ””λ²„κ±°λ‘œ μ‹€ν–‰ν•˜λ©΄ 였λ₯˜κ°€ λ‚˜μ§€ μ•Šμ§€λ§Œ κ·Έλƒ₯ μ‹€ν–‰ν•˜λ©΄ ν•΄λ‹Ή ꡬ문은 였λ₯˜λ₯Ό λ±‰λŠ”λ‹€. 였λ₯˜λ₯Ό λ±‰λŠ”μ§€μ— λŒ€ν•œ μ—¬λΆ€λ‘œλ„ λ””λ²„κ·Έμ˜ 쑴재 μ—¬λΆ€λ₯Ό νŒŒμ•…ν•  수 μžˆλ‹€.

     

     

    이λ₯Ό μš°νšŒν•˜κΈ° μœ„ν•΄μ„œλŠ” μ†Œν”„νŠΈμ›¨μ–΄ BP λŒ€μ‹  ν•˜λ“œμ›¨μ–΄ BP λ₯Ό μ„€μ •ν•˜λ©΄ λœλ‹€.

     

     

     

     

    3.2 Checksums

     

    νŠΉμ • μ½”λ“œ μ˜μ—­μ˜ CheckSum 값을 κ΅¬ν•˜κ³ , 원본 CheckSum κ³Ό λΉ„κ΅ν•˜μ—¬ BP μ„€μ • ν˜Ήμ€ 각쒅 μ½”λ“œ 패치 μ—¬λΆ€λ₯Ό 검사할 수 μžˆλ‹€. 

     

    κ·Έ 쀑 Hash Checking 기법은 ν•¨μˆ˜ μ½”λ“œλ“€μ˜ Hash 값을 미리 ꡬ해 λ‘” λ‹€μŒ, κ·Έ κ°’κ³Ό μ‹€ν–‰ 쀑간에 ν˜Έκ°€μΈν•œ Hash 값이 같은지 ν™•μΈν•˜μ—¬ 패치 μ—¬λΆ€λ₯Ό νƒμ§€ν•˜λŠ” 것이닀.

     

     

     

    3.3 μ‹œκ°„ 체크

     

    λ””λ²„κ±°λ‘œ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹€ν–‰ν•˜λ©΄ κ·Έλƒ₯ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹€ν–‰ν–ˆμ„ λ•Œλ³΄λ‹€ 속도가 ν˜„μ €νžˆ λŠλ €μ§„λ‹€.

    이런 μ‹œκ°„ 차이λ₯Ό νƒμ§€ν•˜λŠ” λͺ‡ 가지 기술이 μ‘΄μž¬ν•œλ‹€.

     

     

    3.3.1 νƒ€μž„ μŠ€νƒ¬ν”„

     

    νŠΉμ • λ™μž‘ μˆ˜ν–‰ 전후에 νƒ€μž„ μŠ€νƒ¬ν”„λ₯Ό κΈ°λ‘ν•˜κ³  λΉ„κ΅ν•œλ‹€.

     

    ν˜Ήμ€ μ˜ˆμ™Έ λ°œμƒ μ „ν›„μ˜ νƒ€μž„ μŠ€νƒ¬ν”„λ₯Ό κ°€μ Έμ™€μ„œ λΉ„κ΅ν•œλ‹€. 디버거가 μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•˜λŠ” 경우 μƒλ‹Ήν•œ 지연이 λ°œμƒν•˜κΈ° λ•Œλ¬Έμ— ꡬ뢄할 수 μžˆλ‹€. (μ˜ˆμ™Έλ₯Ό λ¬΄μ‹œν•˜κ±°λ‚˜ μ§€λ‚˜μΉ˜κ²Œ ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” 디버거듀도 μžˆμ§€λ§Œ, κ·ΈλŸΌμ—λ„ 차이가 λ°œμƒν•œλ‹€.)

     

     

    3.3.2 rdtsc (OPCODE 0x0F31)

     

    κ°€μž₯ 일반적인 μ‹œκ°„ 검사 방법이닀.

     

    κ°€μž₯ μ΅œκ·Όμ— μ‹œμŠ€ν…œμ΄ λ¦¬λΆ€νŒ…ν•œ 이후 흐λ₯Έ μ‹œκ°„ 값을 μ €μž₯ν•œ 64λΉ„νŠΈλ₯Ό λ°˜ν™˜ν•œλ‹€.

    이 λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•œ ν›„ 두 κ°’μ˜ μ°¨κ°€ νŠΉμ •ν•œ 정도λ₯Ό λ„˜μœΌλ©΄ 디버거가 μ‹€ν–‰ μ€‘μž„μœΌλ‘œ νŒλ‹¨ν•  수 μžˆλ‹€.

     

     

    3.3.3 QueryPerformanceCounter & GetTickCount

    https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter

    https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount

     

     

    rdtsc 와 같이 μ‹œκ°„μ°¨λ₯Ό 뢄석할 수 μžˆλŠ” μœˆλ„μš° API ν•¨μˆ˜μ΄λ‹€.

     

     

    4. TLS Callback

     

    일반적으둜 λŒ€λ‹€μˆ˜ λ””λ²„κ±°λŠ” PE ν—€λ”μ—μ„œ μ •μ˜ν•œ ν”„λ‘œκ·Έλž¨ μ§€μž…μ μ—μ„œ μ‹œμž‘ν•œλ‹€.

    그런데 TLS(Thread Local Storage) Callback 은 μ§„μž…μ  전에 μ‹€ν–‰λ˜λŠ” μ½”λ“œλ‘œ, 디버거 λͺ°λž˜ μ‹€ν–‰ν•  수 μžˆλ‹€.

     

    즉, TLS Callback 에 μ•…μ„± μ½”λ“œ κΈ°λŠ₯을 μ‚½μž…ν•œλ‹€λ©΄ λ””λ²„κ±°λ‘œλŠ” κ°μ§€ν•˜μ§€ λͺ»ν•œλ‹€.

     

    일반적인 ν”„λ‘œκ·Έλž¨μ€ .tls μ„Ήμ…˜μ„ μ‚¬μš©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— .tls μ„Ήμ…˜μ΄ μžˆλŠ” 경우 κ°€μž₯ λ¨Όμ € μ•ˆν‹° 디버깅을 μ˜μ‹¬ν•΄μ•Ό ν•œλ‹€.

     

    좜처: https://kali-km.tistory.com/entry/Anti-Debugging?category=490391

    κ΄€λ ¨ λ‚΄μš©μ„ 더 μ•Œκ³  μ‹Άλ‹€λ©΄ - https://flack3r.tistory.com/entry/TLS-%EC%BD%9C%EB%B0%B1-%EC%95%88%ED%8B%B0%EB%94%94%EB%B2%84%EA%B9%85

     

     

    μ°Έκ³  μ‚¬μ΄νŠΈλ“€

    https://blog.naver.com/sol9501/70128619541

    https://kali-km.tistory.com/entry/Anti-Debugging?category=490391

    λŒ“κΈ€

Designed by Tistory.