Share
Embed
Transcript
109 slides
-
SYMBOLIC EXECUTION 1. Introduction ‣ IoT environment ‣ Vulnerability detection
‣ Logical vulnerability CONTENT 2. Remote debugging ‣ IoT architecture ‣ Firmware emulation 4. Dynamic symbolic execution ‣ angr plugin ‣ Vulnerability detection ‣ Hardcode credentials ‣ Command injection 3. Symbolic execution ‣ angr introduction ‣ basic angr operation -
SYMBOLIC EXECUTION ★ 主要研究領域 ‣ IoT firmware analysis (CVE-2021-1602) ‣
Malware analysis ★ 10sec CTF 戰隊成員 ★ 常⽤ ID: in0de Whoami -
SYMBOLIC EXECUTION ★ 匯入虛擬機 ‣ account: user ‣ password: user
Environment setting -
SYMBOLIC EXECUTION ★ Symbolic ‣ 1_remote_debug ‣ 2_symbolic_execution ‣ 3_Dynamic_symbolic
‣ Emulate ★ tools ‣ Ghidra ‣ angr_dev Environment setting -
SYMBOLIC EXECUTION Ghidra ★ 執⾏ ./tools/ghidraRun ★ File -> New
project ★ 將要分析的程式放入專案中 -
SYMBOLIC EXECUTION ★ 多樣性的場域 ‣ ex: manufacturing, smart home, smart
medical, and smart cars ★ 多種的設備 ‣ ex: router, switch, smart plug, and smart speak ★ 複雜的開發架構 ‣ ex: OpenWRT Background of IoT device -
SYMBOLIC EXECUTION ★ C1: 多樣的硬體架構 ‣ ARM, MIPS, and x86
★ C2: 依賴實體環境 ‣ Peripheral device, self-design library ★ C3: 程式複雜度相當⾼ ‣ Services, CGI programs, and tools Challenges on IoT vulnerability testing -
SYMBOLIC EXECUTION ★ ⼈⼯分析 Manual analysis ‣ Dynamic analysis ‣
Static analysis ★ ⾃動化分析 Automate analysis ‣ 模糊測試 Fuzzing ‣ 符號執⾏ Symbolic execution Analyze a binary -
SYMBOLIC EXECUTION ★ 無需額外學習其他技術 ★ 分析準確度較⾼ ★ 傷時間傷腦⼒ ★ 效率低下
Manual analysis -
SYMBOLIC EXECUTION ★ Fuzzing 專注在尋找記憶體毀損 ( memory corruption ) 的問題
★ 然⽽除了記憶體毀損問題,程式中也會存在邏輯漏洞 ★ 邏輯漏洞在模糊測試上無法有效率的挖掘 Why using symbolic execution -
SYMBOLIC EXECUTION ★ Logic flow weakness (邏輯流程上的弱點) ‣ 操縱程式執⾏流程引發各種攻擊者想要的⾏為 ★
Authentication bypass (權限逃逸) ‣ 攻擊權限認證流程上缺失,進⽽取得程式 (或系統) 的⾼權限 Logical vulnerability -
SYMBOLIC EXECUTION ★ Logic flow weakness ‣ 操縱程式執⾏流程引發各種攻擊者想要的⾏為 ‣ ex:
修改數值導致程式執⾏到異常動作 Logical vulnerability Request: do command ID: User ID is User ID is Admin Error: permission error Do command -
SYMBOLIC EXECUTION Logical vulnerability Request: do command ID: User;Admin ★
Logic flow weakness ‣ 操縱程式執⾏流程引發各種攻擊者想要的⾏為 ‣ ex: 修改數值導致程式執⾏到異常動作 ID is User ID is Admin Error: permission error Do command -
SYMBOLIC EXECUTION Logical vulnerability ★ Authentication bypass (權限逃逸) ‣ 攻擊權限認證流程上缺失,進⽽取得程式
(或系統) 的⾼權限 ‣ 經常發⽣於物聯網設備 -
SYMBOLIC EXECUTION Logical vulnerability int auth_check(char *user,char *pass){ char admin_name
= get_admin_name(); char admin_pass = get_admin_pass(); if(strcmp(user,"admin") == 0 && strcmp(pass,"admin")==0){ return PASS; } if ( strcmp(user,admin_name) == 0 && strcmp(pass,admin_pass)==0 ) return PASS; else return FALSE; } int main(void){ char user[256], passwd[256]; initialize(); get_input_username(user); get_input_passwd(passwd); if(auth_check(user,passwd) == PASS){ printf("Login successfully"); do_command(); } else{ printf("Login fail"); exit(); } -
SYMBOLIC EXECUTION Logical vulnerability int auth_check(char *user,char *pass){ char admin_name
= get_admin_name(); char admin_pass = get_admin_pass(); if(strcmp(user,"admin") == 0 && strcmp(pass,"admin")==0){ return PASS; } if ( strcmp(user,admin_name) == 0 && strcmp(pass,admin_pass)==0 ) return PASS; else return FALSE; } strcmp(user,”admin”) strcmp(pass,”admin”) Account Verify 0 1 Return PASS -
SYMBOLIC EXECUTION Logical vulnerability ★ 此例⼦就是權限逃逸的⼀種 ‣ Hardcode password 密碼硬編寫
‣ CVE-2018-6213 (Dlink DIR 620 router) https://www.bleepingcomputer.com/news/security/backdoor-account-found-in-d-link-dir-620-routers/ -
SYMBOLIC EXECUTION Physical device debugging Remote debugging in IoT Host
GDB GDB Server Firmware Binary Process < Port num > Register & Memory Physical hardware -
SYMBOLIC EXECUTION Emulated device debugging User-level emulating / System-level emulating
Remote debugging in IoT Host GDB GDB Server Emulated firmware Binary Process < Port num > Register & Memory Filesystem / Kernel QEMU -
SYMBOLIC EXECUTION GDB Server Emulated firmware Binary Process < Port
num > Filesystem / Kernel QEMU Remote debugging in IoT ★ Step ‣ 將韌體虛擬化在主機上 ‣ 進入韌體命令介⾯,輸入 gdbserver 指令 ‣ 在 Host 端開啟 GDB,並 attach 到虛擬化韌體 ‣ 開始進⾏ debugging -
SYMBOLIC EXECUTION Remote debugging in IoT ★ 韌體虛擬化 ‣ Boot
loader: 系統啟動程序 ‣ Kernel: 系統核⼼ ‣ Filesystem: 韌體檔案系統 CPU Flash RAM NVRAM Boot Loader Kernel Filesystem -
SYMBOLIC EXECUTION Remote debugging in IoT ★ 韌體虛擬化 ‣ QEMU:
可執⾏硬體虛擬化的開源代 管虛擬機器 ‣ User-level emulation ‣ System-level emulation Binary QEMU Binary Kernel/Filesystem System-level User-level -
SYMBOLIC EXECUTION Emulated firmware Binary Filesystem / Kernel QEMU Remote
debugging in IoT ★ 韌體虛擬化框架 ‣ Firmadyne (2016) - https://github.com/firmadyne/ firmadyne ‣ FirmAE (2020) - https://github.com/pr0v3rbs/ FirmAE -
SYMBOLIC EXECUTION Remote debugging in IoT ★ OpenWRT 韌體虛擬化 ‣
cd ~/Desktop/Symbolic/Emulate/ ‣ ./tap.sh ‣ ./run_arm.sh rw Console -
SYMBOLIC EXECUTION Remote debugging in IoT ★ 虛擬化成功後 ★ 可利⽤
ssh 連線進入 OpenWRT ‣ :ssh [email protected] -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
進到 /root/LAB1-1 - 執⾏ ./problem -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
分析程式 - Open Ghidra -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
分析程式 - Import program -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
分析程式 - Key 是 rand 產⽣,但 srand 固定 - 不同的 library rand 實作⽅式不同 - Flag = Key ^ fix_string - 程式在第三個迴圈將 flag 遮蓋掉 -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
解法 - 在原始設備上進⾏動態分析,確保 library ⼀致 - 斷點下在第三個迴圈開始處,並找到字串地址,即可輸出 flag -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
remote debugging ★ Host ‣ : gdb-multiarch <program> ‣ : target remote 10.10.2.2:1234 ★ OpenWRT ‣ :gdbserver —once 10.10.2.2:1234 <program> -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
remote debugging -
SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣
b *0x10710 ‣ x/s $r2 -
SYMBOLIC EXECUTION ★ ⽬標是走到 Target_point ★ 變數 X 的條件是什麼 Manual
analysis X = get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } -
SYMBOLIC EXECUTION ★ ⽬標是走到 Target_point ★ Input X 的條件是 ‣
X < 70 ‣ X >=60 Manual analysis X = get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } -
SYMBOLIC EXECUTION X < 70 X >=60 Manual analysis Solusion1:
X = 60 Solusion2: X = 61 … … SolusionN: X = 69 Concretize 具體化 -
SYMBOLIC EXECUTION Symbolic execution B1 B2 B3 B5 B6 B4
B7 B8 B1 B2 B3 B5 B6 B4 B7 B8 Concrete execution (具體執⾏) Symbolic execution (符號執⾏) User input User input -
SYMBOLIC EXECUTION Concrete execution ★ ⼀般程式運⾏⽅式 ★ User input 是具體的數值
★ 每種 input 只會造就出⼀種路徑 ‣ B1 -> B3 -> B5 -> B7 B1 B2 B3 B5 B6 B4 B7 B8 User input -
SYMBOLIC EXECUTION Symbolic execution B1 B2 B3 B5 B6 B4
B7 B8 Symbolic execution (符號執⾏) User input ★ 需要使⽤特殊的引擎運⾏ ★ User input 是⼀種符號 ★ input 會觸發所有可能執⾏的路徑 ‣ B1 -> B2 -> B4 ‣ B1 -> B3 -> B5 -> B7 ‣ B1 -> B3 -> B6 -> B8 -
SYMBOLIC EXECUTION Symbolic execution X = get_input(); if (X -
70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } -
SYMBOLIC EXECUTION ★ 符號執⾏引擎:將程式仿照真實程式流程執⾏,仿照暫存器、記憶體區段,讓程式 可以接受符號的 input Symbolic execution - states
X = get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } Symbolic execution Engine Regs Mem Condition CPU emulator Binary -
SYMBOLIC EXECUTION ★ State:符號執⾏引擎紀錄程式狀態的⽅式 Symbolic execution - states X =
get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } State A Registers RAX: 0x01 RBX: 0x00 … … RSP: 0xffff7f00 RBP: 0xffff2e12 Memorys Symbolic memory Concrete memory Condition None -
SYMBOLIC EXECUTION ★ State:符號執⾏引擎紀錄程式狀態的⽅式 Symbolic execution - states X =
get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } State A Registers RAX: 0x01 RBX: 0x00 … … RSP: 0xffff7f00 RBP: 0xffff2e12 Memorys Symbolic memory Concrete memory Condition X -70 < 0 -
SYMBOLIC EXECUTION ★ Path:符號執⾏引擎會依照路徑分裂出新的 state Symbolic execution - states X
= get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } State A State AA Condition X - 70 < 0 State AB Condition X - 70 >= 0 -
SYMBOLIC EXECUTION ★ Path:符號執⾏引擎會依照路徑分裂出新的 state Symbolic execution - states X
= get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } State A State AA Condition X - 70 < 0 State AB Condition X - 70 >= 0 -
SYMBOLIC EXECUTION ★ Path:符號執⾏引擎會依照路徑分裂出新的 state Symbolic execution - states X
= get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } State A State AA Condition X - 70 < 0 State AB Condition X - 70 >= 0 State AAB Condition X - 70 < 0 X < 60 State AAA Condition X - 70 < 0 X >= 60 State AAB Condition X - 70 < 0 -
SYMBOLIC EXECUTION ★ solvers:結束路徑探索後,負責將條件解回正確值 Symbolic execution - states X =
get_input(); if (X - 70 < 0){ if (X >= 60){ target_point(); } else{ printf("Input error\n"); } } else{ printf("Input error\n"); } State A State AA Condition X - 70 < 0 State AAA Condition X - 70 < 0 X >= 60 Solusion1: X = 60 Solusion2: X = 61 …. SolusionN: X = 69 -
SYMBOLIC EXECUTION ★ ⼀套不需原始碼的符號執⾏⼯具 ★ 適⽤於多種不同硬體架構的程式 ★ 使⽤ python 進⾏撰寫
‣ 易於擴充與修改 ‣ 效率上受到語⾔的限制 ★ https://angr.io Angr - introduction -
SYMBOLIC EXECUTION Angr - preprocessing Symbolic execution Engine Regs Mem
Condition CPU emulator Binary VEX IR VEX IR ★ 轉換執⾏檔成中介語⾔ (IR) ★ 符號執⾏引擎只需看得懂⼀種架構即可 ARM, MIPS, PPC … -
SYMBOLIC EXECUTION Angr t21 = GET:I64(rdx) PUT(r9) = t21 PUT(rip)
= 0x0000000000400585 mov r9, rdx ★ VEX IR -
SYMBOLIC EXECUTION Angr ★ 進入 angr 的 python 環境 ‣
:workon angr_dev -
SYMBOLIC EXECUTION Angr - Lab 2-1 ★ 解說 ‣ 使⽤者輸入
8個字 ‣ 接著每個字會在complex_function 中做⼀些複雜運算 ‣ 最後這8個字會與 程式中⼀段 hardcode string 做比較 ‣ 當輸入的數值正確就會輸出 “Nice! ...” -
SYMBOLIC EXECUTION Angr - Lab 2-1 ★ 解法 ‣ 符號化使⽤者輸入值
‣ 接著將程式運⾏在 angr 上 ‣ 當程式要輸出 “Nice! …” 時就標記 為到達我們的⽬標 -
SYMBOLIC EXECUTION Angr - lab 2-1 ★ student.py ‣ initial_state
= project.factory.entry_state() entry_state call_state full_init_state blank_state Constructs a state ready to execute a given function Constructs a "blank slate" blank state, with most of its data left uninitialized. Constructs a state ready to execute at the main binary's entry point. Constructs a state that is ready to execute through any initializers -
SYMBOLIC EXECUTION Angr - lab 2-1 ★ student.py ‣ simulation
= project.factory.simgr(initial_state) - 將 state 放入符號執⾏引擎中 ‣ simulation.explore(find=print_good_address) - 使⽤ explore 這個⼯具來做路徑探索 - explore 是 angr 的預設探索⼯具 (可以⾃⼰做) -
SYMBOLIC EXECUTION Angr - lab 2-1 ★ Solution 2 ‣
更改到達與避開的路徑判斷 def is_successful(state): stdout_output = state.posix.dumps(sys.stdout.fileno()) if b"Nice" in stdout_output: return True return False def should_abort(state): stdout_output = state.posix.dumps(sys.stdout.fileno()) if b"incorrect" in stdout_output: return True return False simulation.explore(find=is_successful,avoid=should_abort) -
SYMBOLIC EXECUTION Angr - lab 2-1 ★ 補充 ‣ tools/angr_dev/sim_manager.py
‣ explore -> run -> step -
SYMBOLIC EXECUTION Angr - Lab 2-2 ★ 建立⼀個 blank state
★ 起始位置為處理完使⽤者輸入後 start_address = 0x400a70 initial_state = project.factory.blank_state(addr=start_address) -
SYMBOLIC EXECUTION Angr - Lab 2-2 ★ 建立符號化數值 ★ 放入
state 的暫存器中 password0_size_in_bits = 8*4 password0 = claripy.BVS('password0', password0_size_in_bits) initial_state.regs.eax = password0 -
SYMBOLIC EXECUTION Angr - Lab 2-2 ★ 找到路徑後,具體化剛定義的符號數值 if simulation.found:
solution_state = simulation.found[0] solution0 = solution_state.solver.eval(password0) -
SYMBOLIC EXECUTION Angr - Lab 2-3 ★ 分析使⽤者輸入⽅式 ‣ scanf
會寫入 0x7ea440 ‣ 因此我們可以將 0x7ea440[32] 這段空間符號化 -
SYMBOLIC EXECUTION Angr - Lab 2-3 ★ 符號化記憶體區段 password0 =
claripy.BVS('password0', 8*8) password1 = claripy.BVS('password1', 8*8) password2 = claripy.BVS('password2', 8*8) password3 = claripy.BVS('password3', 8*8) password0_address = 0x7ea440 state.memory.store(password0_address, password0) state.memory.store(password0_address+0x8, password1) state.memory.store(password0_address+0x10, password2) state.memory.store(password0_address+0x18, password3) -
SYMBOLIC EXECUTION Angr - Lab 2-3 ★ 符號化記憶體區段 password0 =
claripy.BVS('password0', 8*8) initial_state.memory.store(password0_address, password0) -
SYMBOLIC EXECUTION Angr - Lab 2-3 ★ 問題 ‣ 使⽤
blank_state 進⾏符號執⾏會導致記憶體內部部份的值為進⾏初始化 ‣ 如何在不使⽤ blank_state 下完成注入符號變數 -
SYMBOLIC EXECUTION Angr - Lab 2-3 ★ Solution 2 ‣
Hooking SEE Hook address def my_hook(state): print(‘hello hook’) <do something> mov eax, [rbp+var_4] movsxd rdx, eax lea rax, user_input movsx eax, al mov edx, [rbp+var_4] mov esi, edx mov edi, eax call complex_function mov ecx, eax mov eax, [rbp+var_4] movsxd rdx, eax lea rax, user_input mov [rdx+rax], cl project.hook(hooking_address, hook_func,4) -
SYMBOLIC EXECUTION Angr - Lab 2-3 ★ Solution 2 Hooking
‣ 將程式轉為 entry_state 來執⾏ ‣ hooking start_address,並在 callback function 中符號化變數 password0 = claripy.BVS('password0', 8*8) def my_hook(state): password0_address = 0x7ea440 state.memory.store(password0_address, password0) project.hook(hooking_address, hook_func,4) -
SYMBOLIC EXECUTION Execution approach B1 B2 B3 B5 B6 B4
B7 B8 B1 B2 B3 B5 B6 B4 B7 B8 Concrete execution (具體執⾏) Symbolic execution (符號執⾏) User input User input -
SYMBOLIC EXECUTION Dynamic symbolic execution B1 B2 B3 B5 B6
B4 B7 B8 Dynamic symbolic execution (動態符號執⾏) User input ★ B1 ~ B3 使⽤具體執⾏ ★ B3 之後使⽤符號執⾏ ★ 可以減少不必要的路徑探索 ★ 可增加運⾏時成功率 -
SYMBOLIC EXECUTION Symbion: fusing concrete and symbolic execution ★ angr
plugin ★ 交互式符號執⾏框架 Interleaved execution technique ★ 使⽤ GDB 框架來達到動態分析效果 https://docs.angr.io/advanced-topics/symbion -
SYMBOLIC EXECUTION Symbion ★ ⽀援 ARM X86 X86-64 ★ 需要使⽤
Remote debugging 技術 concrete_tech = simgr.use_technique(angr.exploration_techniques.Symbion(find=[0x0400755])) exploration = simgr.run() -
SYMBOLIC EXECUTION Lab3-0 ★ 題⽬是 2-1 的 ★ 使⽤ symbion
的環境來解 Concrete Symbolic -
SYMBOLIC EXECUTION Lab3-1 Socket init wait for client connect Program
start Read socket input Send input check input Server Client Connect to server ★ Program work flow -
SYMBOLIC EXECUTION Lab3-1 Socket init wait for client connect Program
start Read socket input Send input check input Server Client Connect to server ★ Dynamic symbolic execution ‣ workflow Symbolic execution -
SYMBOLIC EXECUTION Lab3-1 Socket init wait for client connect Program
start Read socket input Send input check input Server Client Connect to server ★ Concrete execution concrete_tech = simgr.use_technique (angr.exploration_techniques.Symbion(find=[0x400a35])) exploration = simgr.run() new_concrete_state = exploration.stashes['found'][0] print(new_concrete_state) -
SYMBOLIC EXECUTION Lab3-1 Socket init wait for client connect Program
start Read socket input Send input check input Server Client Connect to server ★ Concrete execution ‣ 為了讓程式運⾏到 recv 需要假造⼀個 正常連線給 server :nc 127.0.0.1 8800 -
SYMBOLIC EXECUTION Lab3-1 Socket init wait for client connect Program
start Read socket input Send input check input Server Client Connect to server ★ Symbolic execution ‣ 為了讓程式運⾏到 recv 需要假造⼀個 正常連線給 server user_input = ??? password = claripy.BVS('password', 32*8) new_concrete_state.memory.store(user_input, password) simulation = p.factory.simgr(new_concrete_state) simulation.explore(find=????) -
SYMBOLIC EXECUTION Lab3-1 Socket init wait for client connect Program
start Read socket input Send input check input Server Client Connect to server ★ Result -
SYMBOLIC EXECUTION ★ Has specific source and sink point ★
complexity is lower than memory corruption vulnerability ★ Usually found in IoT device ★ ex: CVE-2020-29583 Authentication bypass vulnerability