天天看點

COIN Attacks【源碼分析】COIN Attacks符号執行SGX_SQLite

COIN Attacks符号執行SGX_SQLite

從COIN Attack符号執行SGX_SQLite的過程入手分析COIN Attacks。從

run.sh

開始。

第一步 編譯SGX_SQLite

SGX SIM Mode編譯SGX_SQLite。(位于

run.sh

)

第二步 提取EDL資訊

分析EDL檔案并記錄所有會将資料傳入Enclave的E/OCALL函數及對應參數,具體包括OCALL傳回值、

[out]

标記的OCALL參數、

[in]

标記的及其它所有的ECALL參數。這些參數稱為不安全參數。資訊放到

unsafe_input_stat.tmp

unsafe_ecall_stat.tmp

檔案。(位于

edlParse.py

第三步 提取不安全參數的類型資訊

結合第二步得出的資訊,使用ModulePass讀取(似乎會漏掉SDK的接口)每個不安全參數所包含内容的類型(如pointer所指Reference的類型,struct内的各個成員的類型)。基于LLVM Pass的RTTI能更簡單地擷取類型資訊。資訊放到

unsafe_input_complete.tmp

檔案。(位于

EnclaveSemantics.cpp

第四步 符号執行Enclave

加載Enclave.so

load_binary

中,使用

lief.parse

解析

enclave.so

,使用Triton的

setConcreteMemoryAreaValue

将Enclave加載起來。

加載不安全的輸入資訊

load_input_semantics

函數将

unsafe_input_complete.tmp

裡的不安全函數及其參數資訊分别加載到資料結構

interface_hook_fn

input_semantics

中。

加載ECALL資訊

load_ECALLs

unsafe_ecall_stat.tmp

裡的Ecall資訊加載到資料結構

primary_ECALLs

中。

permutations

建構Ecall函數的各種排列。

為模拟器配置Hooks

config_hook_table

中,利用

lief.ELF.Binary

豐富的資訊,動态設定Unsafe函數pltgot項位址(若其為pltgot符号)。動态更新

dlmalloc

dlfree

memcpy

函數的位址資訊。動态更新

__stack_chk_fail

tag的位址資訊。

初始化triton上下文

單線程模拟執行(包括亂序執行)

定位

urts

sgx_ocall

sgx_ocfree

函數位址。Triton具體化所有記憶體、寄存器。擷取所有ECALL的位址。設定棧資訊(RBP和RSP)。選擇需要亂序執行的Ecall,對其參數設定記憶體值。其中比較重要的是模拟執行Ecall。在

MAX_SEED_ATTEMPT

次數内不斷變化seed(即改變記憶體值),然後重新模拟執行Ecall。

"""
run_single_thread_emul(perm_ECALLs_list) prepares and handles single thread mode of emulation
"""
def run_single_thread_emul(perm_ECALLs_list):
	...
	config_memory_for_param(it_ECALL, param_ECALL, it_ECALL_addr, init_seed_flag, True)
	...
	res = emulate(it_ECALL_addr, sgx_ocall, sgx_ofree, False)
	...
           

模拟執行

初始化模拟器。擷取Ecall函數的opcode并使用Triton模拟執行。單次模拟執行中,最多從入口指令開始往後執行

MAX_INST_CNT

條指令。檢查目前指令是否符合政策。

檢查目前指令是不是某個hook函數(針對

dlmalloc

sgx_malloc_hook

、針對

dlfree

sgx_free_hook

、針對

memcpy

sgx_memcpy

)或tag(

__stack_chk_fail

),陷入到hook或者tag時也進行政策檢查,若違反政策就建構報告。

政策檢查是這項工作的關鍵所在。

"""
emulate(pc, sgx_ocall, sgx_free, is_threaded) emulates instructions
"""
def emulate(pc, sgx_ocall, sgx_free, is_threaded):
	...
	ret = Triton.processing(instruction)
	...
	policies.inspection(instruction)
	...
    hook_process_inst(instruction)
	...
	print_report()
	...
           

檢查政策(*)

  • 當opcode為

    mov

    movsx

    lea

    且某個operand為記憶體時(

    oob_uaf_policy

    函數中)
    • 若記憶體對象尾部跨出了堆配置設定時記錄的Enclave堆對象的尾部,則認為OOB發生。
    • 若記憶體對象頭部未指向堆配置設定時記錄的Enclave堆對象内,并且與堆配置設定曆史記錄吻合,則認為UAF發生。
  • 當opcode為

    cmp

    ,指令被符号化,後20條指令記憶體在操作數是第32位為1的立即數(認為攻擊者控制?)的

    mov

    指令,再往後10條指令内有

    jmp

    指令,則認為Ineffectual Condition發生。(

    test_cmp_sides

    函數中)
  • Enclave内調用

    memcpy

    函數時,會被

    sgx_memcpy

    hook函數攔截,其中會先後檢查棧洩漏、Null Pointer Deference、堆溢出。
    • 棧洩漏檢測

      memcpy

      中是否是棧對象複制到堆對象。(

      test_stack_leak

      函數中)
    • Null Pointer Deference

      memcpy

      目标位址是否為Null(

      is_nd_or_heap_overflow

      函數中)
    • 堆溢出檢查目标堆對象有效大小(堆配置設定時會記錄堆對象資訊)是否小于

      memcpy

      參數指定的大小。(

      is_nd_or_heap_overflow

      函數中)