Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symbolic Execution in IoT

In0de
September 22, 2022

Symbolic Execution in IoT

My training slide for company in 2021

In0de

September 22, 2022
Tweet

More Decks by In0de

Other Decks in Technology

Transcript

  1. 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
  2. SYMBOLIC EXECUTION ★ 主要研究領域 ‣ IoT firmware analysis (CVE-2021-1602) ‣

    Malware analysis ★ 10sec CTF 戰隊成員 ★ 常⽤ ID: in0de Whoami
  3. SYMBOLIC EXECUTION ★ Symbolic ‣ 1_remote_debug ‣ 2_symbolic_execution ‣ 3_Dynamic_symbolic

    ‣ Emulate ★ tools ‣ Ghidra ‣ angr_dev Environment setting
  4. SYMBOLIC EXECUTION Ghidra ★ 執⾏ ./tools/ghidraRun ★ File -> New

    project ★ 將要分析的程式放入專案中
  5. 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
  6. SYMBOLIC EXECUTION ★ C1: 多樣的硬體架構 ‣ ARM, MIPS, and x86

    ★ C2: 依賴實體環境 ‣ Peripheral device, self-design library ★ C3: 程式複雜度相當⾼ ‣ Services, CGI programs, and tools Challenges on IoT vulnerability testing
  7. SYMBOLIC EXECUTION ★ ⼈⼯分析 Manual analysis ‣ Dynamic analysis ‣

    Static analysis ★ ⾃動化分析 Automate analysis ‣ 模糊測試 Fuzzing ‣ 符號執⾏ Symbolic execution Analyze a binary
  8. SYMBOLIC EXECUTION ★ Fuzzing 專注在尋找記憶體毀損 ( memory corruption ) 的問題

    ★ 然⽽除了記憶體毀損問題,程式中也會存在邏輯漏洞 ★ 邏輯漏洞在模糊測試上無法有效率的挖掘 Why using symbolic execution
  9. SYMBOLIC EXECUTION ★ Logic flow weakness (邏輯流程上的弱點) ‣ 操縱程式執⾏流程引發各種攻擊者想要的⾏為 ★

    Authentication bypass (權限逃逸) ‣ 攻擊權限認證流程上缺失,進⽽取得程式 (或系統) 的⾼權限 Logical vulnerability
  10. SYMBOLIC EXECUTION ★ Logic flow weakness ‣ 操縱程式執⾏流程引發各種攻擊者想要的⾏為 ‣ ex:

    修改數值導致程式執⾏到異常動作 Logical vulnerability Request: do command ID: User ID is User ID is Admin Error: permission error Do command
  11. 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
  12. 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(); }
  13. 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
  14. 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/
  15. SYMBOLIC EXECUTION Physical device debugging Remote debugging in IoT Host

    GDB GDB Server Firmware Binary Process < Port num > Register & Memory Physical hardware
  16. 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
  17. SYMBOLIC EXECUTION GDB Server Emulated firmware Binary Process < Port

    num > Filesystem / Kernel QEMU Remote debugging in IoT ★ Step ‣ 將韌體虛擬化在主機上 ‣ 進入韌體命令介⾯,輸入 gdbserver 指令 ‣ 在 Host 端開啟 GDB,並 attach 到虛擬化韌體 ‣ 開始進⾏ debugging
  18. SYMBOLIC EXECUTION Remote debugging in IoT ★ 韌體虛擬化 ‣ Boot

    loader: 系統啟動程序 ‣ Kernel: 系統核⼼ ‣ Filesystem: 韌體檔案系統 CPU Flash RAM NVRAM Boot Loader Kernel Filesystem
  19. SYMBOLIC EXECUTION Remote debugging in IoT ★ 韌體虛擬化 ‣ QEMU:

    可執⾏硬體虛擬化的開源代 管虛擬機器 ‣ User-level emulation ‣ System-level emulation Binary QEMU Binary Kernel/Filesystem System-level User-level
  20. 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
  21. SYMBOLIC EXECUTION Remote debugging in IoT ★ OpenWRT 韌體虛擬化 ‣

    cd ~/Desktop/Symbolic/Emulate/ ‣ ./tap.sh ‣ ./run_arm.sh rw Console
  22. SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣

    進到 /root/LAB1-1 - 執⾏ ./problem
  23. SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣

    分析程式 - Key 是 rand 產⽣,但 srand 固定 - 不同的 library rand 實作⽅式不同 - Flag = Key ^ fix_string - 程式在第三個迴圈將 flag 遮蓋掉
  24. SYMBOLIC EXECUTION Remote debugging in IoT ★ LAB 1-1 ‣

    解法 - 在原始設備上進⾏動態分析,確保 library ⼀致 - 斷點下在第三個迴圈開始處,並找到字串地址,即可輸出 flag
  25. 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>
  26. 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"); }
  27. 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"); }
  28. SYMBOLIC EXECUTION X < 70 X >=60 Manual analysis Solusion1:

    X = 60 Solusion2: X = 61 … … SolusionN: X = 69 Concretize 具體化
  29. 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
  30. SYMBOLIC EXECUTION Concrete execution ★ ⼀般程式運⾏⽅式 ★ User input 是具體的數值

    ★ 每種 input 只會造就出⼀種路徑 ‣ B1 -> B3 -> B5 -> B7 B1 B2 B3 B5 B6 B4 B7 B8 User input
  31. 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
  32. 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"); }
  33. 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
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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
  39. 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
  40. SYMBOLIC EXECUTION ★ ⼀套不需原始碼的符號執⾏⼯具 ★ 適⽤於多種不同硬體架構的程式 ★ 使⽤ python 進⾏撰寫

    ‣ 易於擴充與修改 ‣ 效率上受到語⾔的限制 ★ https://angr.io Angr - introduction
  41. SYMBOLIC EXECUTION Angr - preprocessing Symbolic execution Engine Regs Mem

    Condition CPU emulator Binary VEX IR VEX IR ★ 轉換執⾏檔成中介語⾔ (IR) ★ 符號執⾏引擎只需看得懂⼀種架構即可 ARM, MIPS, PPC …
  42. SYMBOLIC EXECUTION Angr t21 = GET:I64(rdx) PUT(r9) = t21 PUT(rip)

    = 0x0000000000400585 mov r9, rdx ★ VEX IR
  43. SYMBOLIC EXECUTION Angr - Lab 2-1 ★ 解說 ‣ 使⽤者輸入

    8個字 ‣ 接著每個字會在complex_function 中做⼀些複雜運算 ‣ 最後這8個字會與 程式中⼀段 hardcode string 做比較 ‣ 當輸入的數值正確就會輸出 “Nice! ...”
  44. SYMBOLIC EXECUTION Angr - Lab 2-1 ★ 解法 ‣ 符號化使⽤者輸入值

    ‣ 接著將程式運⾏在 angr 上 ‣ 當程式要輸出 “Nice! …” 時就標記 為到達我們的⽬標
  45. 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
  46. SYMBOLIC EXECUTION Angr - lab 2-1 ★ student.py ‣ simulation

    = project.factory.simgr(initial_state) - 將 state 放入符號執⾏引擎中 ‣ simulation.explore(find=print_good_address) - 使⽤ explore 這個⼯具來做路徑探索 - explore 是 angr 的預設探索⼯具 (可以⾃⼰做)
  47. 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)
  48. SYMBOLIC EXECUTION Angr - Lab 2-2 ★ 建立⼀個 blank state

    ★ 起始位置為處理完使⽤者輸入後 start_address = 0x400a70 initial_state = project.factory.blank_state(addr=start_address)
  49. 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
  50. SYMBOLIC EXECUTION Angr - Lab 2-2 ★ 找到路徑後,具體化剛定義的符號數值 if simulation.found:

    solution_state = simulation.found[0] solution0 = solution_state.solver.eval(password0)
  51. SYMBOLIC EXECUTION Angr - Lab 2-3 ★ 分析使⽤者輸入⽅式 ‣ scanf

    會寫入 0x7ea440 ‣ 因此我們可以將 0x7ea440[32] 這段空間符號化
  52. 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)
  53. SYMBOLIC EXECUTION Angr - Lab 2-3 ★ 符號化記憶體區段 password0 =

    claripy.BVS('password0', 8*8) initial_state.memory.store(password0_address, password0)
  54. SYMBOLIC EXECUTION Angr - Lab 2-3 ★ 問題 ‣ 使⽤

    blank_state 進⾏符號執⾏會導致記憶體內部部份的值為進⾏初始化 ‣ 如何在不使⽤ blank_state 下完成注入符號變數
  55. 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)
  56. 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)
  57. 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
  58. SYMBOLIC EXECUTION Dynamic symbolic execution B1 B2 B3 B5 B6

    B4 B7 B8 Dynamic symbolic execution (動態符號執⾏) User input ★ B1 ~ B3 使⽤具體執⾏ ★ B3 之後使⽤符號執⾏ ★ 可以減少不必要的路徑探索 ★ 可增加運⾏時成功率
  59. SYMBOLIC EXECUTION Symbion: fusing concrete and symbolic execution ★ angr

    plugin ★ 交互式符號執⾏框架 Interleaved execution technique ★ 使⽤ GDB 框架來達到動態分析效果 https://docs.angr.io/advanced-topics/symbion
  60. SYMBOLIC EXECUTION Symbion ★ ⽀援 ARM X86 X86-64 ★ 需要使⽤

    Remote debugging 技術 concrete_tech = simgr.use_technique(angr.exploration_techniques.Symbion(find=[0x0400755])) exploration = simgr.run()
  61. 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
  62. 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
  63. 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)
  64. 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
  65. 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=????)
  66. 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
  67. 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