คลัง
reverse

Static Analysis

Static Analysis คือการวิเคราะห์ binary โดยไม่รัน — ดู metadata, imports, disassembly, decompiler เพื่อเข้าใจ logic ปลอดภัยกว่า dynamic (ไม่รันโค้ดอันตราย) บทนี้ลงลึก triage workflow แบบเป็นระบบ, การอ่าน imports/symbols, การหา main ใน stripped binary, การรับมือ obfuscation/packing, และเมื่อใดควรเสริมด้วย dynamic

IntermediateAdvanced#static-analysis#reverse#triage#disassembly#imports#stripped#ctf

1. หลักการ — ข้อดี/ข้อเสีย

Static analysis อ่าน binary โดยไม่รัน — ปลอดภัย (ไม่ trigger malware/payload), เห็นภาพรวมทั้งหมด, ตามทุก branch ได้ ข้อเสีย: ต้องอ่าน assembly/decompiler เอง, เจอ obfuscation/packing/anti-analysis ได้, ไม่เห็นค่า runtime (เช่น string ที่ decode ตอน run) จึงมักใช้คู่กับ dynamic: static เข้าใจโครงสร้าง, dynamic ยืนยันพฤติกรรมจริง

2. Triage workflow (ก่อนเปิด decompiler)

เก็บข้อมูลเบื้องต้นเป็นลำดับLinux
# 1. ชนิดไฟล์ + architecture + stripped?
file binary
# ELF 64-bit LSB / PE32+ / stripped หรือ not stripped

# 2. protections (ถ้าเป็น pwn)
checksec binary

# 3. strings (ดูหัวข้อ strings)
strings -n 8 binary | grep -iE 'flag|key|pass'
strings -e l binary | grep -i flag    # Unicode ด้วย

# 4. imports — ฟังก์ชันที่เรียก (บอกใบ้พฤติกรรม)
rabin2 -i binary                      # imports
nm -D binary 2>/dev/null              # dynamic symbols
readelf -d binary                     # dynamic section / libraries

# 5. sections + entropy (packed?)
rabin2 -S binary
rabin2 -I binary                      # info รวม (lang, packer, ...)
ลำดับ: file → checksec → strings → imports → sections; ได้ภาพรวมก่อนเสียเวลาเปิด Ghidra

3. อ่าน imports — เดาพฤติกรรม

imports (ฟังก์ชัน library ที่โปรแกรมเรียก) บอกใบ้ว่าโปรแกรมทำอะไร — ก่อนอ่านโค้ดให้ดู imports เพื่อตั้งสมมติฐาน:

import ที่เห็นบอกใบ้ว่า
strcmp/memcmp/strncmpเทียบ input (flag check!) → xref ดู
fopen/fread/openอ่านไฟล์ (config/flag file)
socket/connect/sendnetwork (C2/download)
system/exec/popenรันคำสั่ง
crypt/AES/MD5/EVP_*cryptography (decode routine)
ptraceanti-debug (ดู Anti-Debug)
VirtualAlloc/mprotectself-modifying/unpacking
เจอ strcmp/memcmp ใน imports → ใน Ghidra/IDA หา xref ไปที่มัน มักเป็นจุด flag check ที่ argument ที่สองคือ flag ที่ hardcode

4. Stripped binary — หา main

binary ที่ stripped ไม่มี symbol → ไม่เห็นชื่อ main ต้องหาเอง:

  • จาก entry point: entry → __libc_start_main — argument แรก (RDI ก่อนเรียก) คือ address ของ main
  • ใน Ghidra: ไปที่ entry → ดู call __libc_start_main → ตาม RDI → rename เป็น main
  • หาจาก string xref: string ที่โปรแกรมพิมพ์ → X xref → ฟังก์ชันที่ใช้ มักใกล้ main
  • FLIRT/signatures: IDA FLIRT ช่วยระบุ library function ที่ stripped
  • เทียบ pattern: ฟังก์ชันใหญ่ที่ถูกเรียกจาก entry มักเป็น main

5. Obfuscation / packing / anti-analysis

  • packed (strings ว่าง, high entropy): unpack ก่อน — UPX: upx -d; อื่น: dump จาก memory ตอน runtime
  • string obfuscation: FLOSS หรือ reverse decode routine (ดู strings)
  • control flow obfuscation: opaque predicate, flattening → อาจต้อง dynamic ช่วย
  • anti-disassembly: junk byte หลอก disassembler → แก้ที่ Ghidra (clear/redefine)
  • anti-debug: ตรวจ ptrace ฯลฯ → static หาจุดตรวจ, dynamic patch (ดู Anti-Debug)
  • self-modifying: โค้ดแก้ตัวเองตอน run → static เห็นไม่ครบ ต้อง dynamic dump

6. Workflow รวม

  1. 1triage: file → checksec → strings → imports → sections
  2. 2ถ้า packed → unpack ก่อน
  3. 3เปิด Ghidra/IDA → หา main (stripped → จาก entry/__libc_start_main)
  4. 4ดู imports ที่น่าสนใจ (strcmp/crypto) → X xref → ไปจุด logic
  5. 5อ่าน decompiler, rename/retype ให้เข้าใจ
  6. 6obfuscation/runtime value → เสริมด้วย dynamic (ดู Dynamic Analysis)

7. Quick Reference

  • วิเคราะห์โดยไม่รัน — ปลอดภัย เห็นภาพรวม; ใช้คู่ dynamic
  • triage: file → checksec → strings → imports → sections
  • imports: rabin2 -i; strcmp/crypto/ptrace บอกใบ้พฤติกรรม
  • เจอ strcmp → xref = flag check
  • stripped → หา main จาก entry/__libc_start_main
  • packed → unpack (upx -d / dump); obfuscated → FLOSS/dynamic

🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ

สมมติได้ binary มาแบบไม่รู้อะไรเลย มีแค่ Kali ทำ triage ตามลำดับนี้ก่อนเปิด decompiler เสียเวลา

  1. 1file ./binary — ดู ELF/PE, architecture, stripped หรือไม่
  2. 2chmod +x ./binary แล้วลองรันดูเฉยๆ สังเกตพฤติกรรม (ถามอะไร, error แบบไหน)
  3. 3checksec ./binary (ถ้ามี pwntools ติดตั้ง) ดู canary/NX/PIE เผื่อโยงกับ pwn
  4. 4strings -n 8 ./binary | grep -iE 'flag|pass|key|secret'
  5. 5rabin2 -i ./binary (หรือ objdump -T / nm -D) ดู imports เดาพฤติกรรม (strcmp/crypto/ptrace/socket)
  6. 6rabin2 -I ./binary หรือ rabin2 -S ./binary ดู sections/entropy เช็ค packed
  7. 7ถ้า stripped ไม่มี main → ไปที่ entry point แล้วตาม argument แรกของ __libc_start_main
  8. 8สรุปสมมติฐานจากข้อมูลที่ได้ แล้วเปิด ghidra/radare2 ไปดู logic ตรงจุดที่น่าสนใจ
Triage ก่อนเปิด decompiler
file ./binary → ดู arch, ELF/PE, stripped?
strings -n 8 ./binary | grep -iE 'flag|pass|key'
✅ เจอ flag ตรงๆ→ จบเลย ส่งคำตอบ
❌ ไม่เจอ / string น้อยผิดปกติ→ เช็คว่า packed ก่อน
เช็ค packed: binwalk ./binary, rabin2 -I | grep -i packer
✅ เจอ UPX/packer→ upx -d ./binary -o unpacked แล้วย้อนไป strings ใหม่
❌ ไม่ packed แต่ยังไม่เจอ flag→ ดู imports ต่อ
rabin2 -i ./binary — ดู imports (strcmp/crypto/ptrace/socket)
imports บอกใบ้อะไร
✅ เจอ strcmp/memcmp→ น่าจะเป็นจุด flag check ไปดูใน decompiler
✅ เจอ ptrace→ มี anti-debug ต้อง bypass ก่อนค่อย debug
❌ เจอ crypto (AES/MD5) โดยไม่มี check ตรงๆ→ ต้องเข้าใจ algorithm แล้วเขียน solver
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
เช็ค type/archfile--
เช็ค protections (เผื่อเป็น pwn)checksecpipx install pwntools-
ดึงข้อความstrings-CyberChef
ดู imports/exportsrabin2, objdump, nm, readelfapt install radare2-
เช็ค packed/entropybinwalk, rabin2 -Iapt install binwalk-
unpack UPXupxapt install upx-ucl-
เปิด decompiler ต่อghidraapt install ghidradogbolt.org
เทียบ compiler/assembly--godbolt.org
🚑 ถ้าตันสนิท ลองท่าถัดไป: strings — ถ้ายังไม่ได้ลองดึงข้อความให้ละเอียดก่อน (encoding อื่น, FLOSS); ghidra — พร้อมเข้าใจ logic ลึกแล้วหลัง triage เสร็จ; anti-debug — เจอ ptrace ใน imports; dynamic-analysis — ต้องยืนยันค่า runtime หรือ unpack เองไม่ได้; binary-patching — เข้าใจ logic แล้วแค่ต้องผ่าน check

โน้ตของฉัน

ยังไม่มีโน้ตสำหรับหัวข้อนี้