Static Analysis
Static Analysis คือการวิเคราะห์ binary โดยไม่รัน — ดู metadata, imports, disassembly, decompiler เพื่อเข้าใจ logic ปลอดภัยกว่า dynamic (ไม่รันโค้ดอันตราย) บทนี้ลงลึก triage workflow แบบเป็นระบบ, การอ่าน imports/symbols, การหา main ใน stripped binary, การรับมือ obfuscation/packing, และเมื่อใดควรเสริมด้วย dynamic
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)
# 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, ...)3. อ่าน imports — เดาพฤติกรรม
imports (ฟังก์ชัน library ที่โปรแกรมเรียก) บอกใบ้ว่าโปรแกรมทำอะไร — ก่อนอ่านโค้ดให้ดู imports เพื่อตั้งสมมติฐาน:
| import ที่เห็น | บอกใบ้ว่า |
|---|---|
| strcmp/memcmp/strncmp | เทียบ input (flag check!) → xref ดู |
| fopen/fread/open | อ่านไฟล์ (config/flag file) |
| socket/connect/send | network (C2/download) |
| system/exec/popen | รันคำสั่ง |
| crypt/AES/MD5/EVP_* | cryptography (decode routine) |
| ptrace | anti-debug (ดู Anti-Debug) |
| VirtualAlloc/mprotect | self-modifying/unpacking |
strcmp/memcmp ใน imports → ใน Ghidra/IDA หา xref ไปที่มัน มักเป็นจุด flag check ที่ argument ที่สองคือ flag ที่ hardcode4. 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 รวม
- 1triage: file → checksec → strings → imports → sections
- 2ถ้า packed → unpack ก่อน
- 3เปิด Ghidra/IDA → หา main (stripped → จาก entry/__libc_start_main)
- 4ดู imports ที่น่าสนใจ (strcmp/crypto) → X xref → ไปจุด logic
- 5อ่าน decompiler, rename/retype ให้เข้าใจ
- 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 เสียเวลา
- 1file ./binary — ดู ELF/PE, architecture, stripped หรือไม่
- 2chmod +x ./binary แล้วลองรันดูเฉยๆ สังเกตพฤติกรรม (ถามอะไร, error แบบไหน)
- 3checksec ./binary (ถ้ามี pwntools ติดตั้ง) ดู canary/NX/PIE เผื่อโยงกับ pwn
- 4strings -n 8 ./binary | grep -iE 'flag|pass|key|secret'
- 5rabin2 -i ./binary (หรือ objdump -T / nm -D) ดู imports เดาพฤติกรรม (strcmp/crypto/ptrace/socket)
- 6rabin2 -I ./binary หรือ rabin2 -S ./binary ดู sections/entropy เช็ค packed
- 7ถ้า stripped ไม่มี main → ไปที่ entry point แล้วตาม argument แรกของ __libc_start_main
- 8สรุปสมมติฐานจากข้อมูลที่ได้ แล้วเปิด ghidra/radare2 ไปดู logic ตรงจุดที่น่าสนใจ
| ขั้นตอน/งาน | เครื่องมือใน Kali | ติดตั้งเพิ่ม (ถ้าไม่มี) | เครื่องมือออนไลน์ |
|---|---|---|---|
| เช็ค type/arch | file | - | - |
| เช็ค protections (เผื่อเป็น pwn) | checksec | pipx install pwntools | - |
| ดึงข้อความ | strings | - | CyberChef |
| ดู imports/exports | rabin2, objdump, nm, readelf | apt install radare2 | - |
| เช็ค packed/entropy | binwalk, rabin2 -I | apt install binwalk | - |
| unpack UPX | upx | apt install upx-ucl | - |
| เปิด decompiler ต่อ | ghidra | apt install ghidra | dogbolt.org |
| เทียบ compiler/assembly | - | - | godbolt.org |
หัวข้อที่เชื่อมโยง
โน้ตของฉัน
ยังไม่มีโน้ตสำหรับหัวข้อนี้