作者:麒麟框架
項目地址:https://qilingframework.github.io/www_zh/
微博:https://weibo.com/sgniwx?is_all=1
二進制分析工具的現狀
物聯網設備正面臨前所未有的威脅。惡意軟件攻擊的對象通常是安全性差或者配置不當的網絡設備。硬件廠商和安全行業都在努力研究各種攻擊行為,以制造更安全的產品。而“針對物聯網設備的攻擊”和“惡意軟件分析”則是這個過程中,我們所面臨的兩個最大的挑戰。
目前“物聯網設備”和“惡意軟件”同時運行于各種不同的操作系統與CPU架構中,逆向工程師需要了解全部CPU架構,這極大的降低了分析效率。同時,很多無法得到及時更新的分析工具,在面對層出不窮的新型攻擊方式時,則顯得捉襟見肘。
而現階段很多二進制分析工具(系統仿真、用戶模式仿真、二進制插樁工具和沙箱), 都只針對單一類型的操作系統或CPU架構,且這些工具間幾乎不可能共享信息或交叉引用數據。 這就是逆向工程的困難所在。
[1]Sonicwall的研究顯示,2018年,惡意軟件攻擊大幅上升,達到105.2億次,創下歷史新高,且網絡犯罪分子使用了新的威脅策略。
解決方案
麒麟框架旨在改變物聯網安全研究、惡意軟件分析和逆向工程的現狀。我們的目標是構建一個跨平臺、支持多體系結構的分析框架,而不僅僅是做一個逆向工具。麒麟框架擁有強大的功能,例如在二進制執行之前或執行期間進行代碼攔截和任意代碼注入。它還可以在執行期間補丁目標二進制文件。
麒麟框架是用Python編寫的開源工具。Python是逆向工程師常用的簡單的編程語言,這極大的降低了二次開發的門檻。
麒麟框架是什么
麒麟框架不僅僅是一個仿真平臺或逆向工程工具。它還將“二進制插樁”和“二進制仿真”結合一起。借助麒麟框架,你可以:
- 動態干預二進制程序執行流程
- 在二進制程序執行期間對其進行動態補丁
- 在二進制程序執行期間對其進行代碼注入
- 局部執行二進制程序,而不是運行整個文件
- 任意補丁“脫殼”已加殼程序內容
麒麟框架能夠模擬:
- Windows x86 32/64位
- Linux x86 32/64位,ARM,AARCH64,MIPS
- MacOS x86 32/64位
- FreeBSD x86 32/64位
麒麟框架能夠在Windows/MacOS/Linux/FreeBSD等操作系統上運行,且不受CPU架構的限制
麒麟框架是如何操作的
演示環境
Hardware : X86 64位 OS : Ubuntu 18.04 64位
Demo #1 獲取Wannacry的斷路器開關地址
麒麟框架運行Wannacry惡意軟件獲取斷路器開關地址
qiling DEMO 1: Catching wannacry's killer switch
代碼樣本
from qiling import *
def stopatkillerswtich(ql):
ql.uc.emu_stop()
if __name__ == "__main__":
ql = Qiling(["rootfs/x86_windows/bin/wannacry.bin"], "rootfs/x86_windows")
ql.hook_address(stopatkillerswtich, 0x40819a)
ql.run()
執行輸出
0x1333804: __set_app_type(0x2)
0x13337ce: __p__fmode() = 0x500007ec
0x13337c3: __p__commode() = 0x500007f0
0x132f1e1: _controlfp(0x10000, 0x30000) = 0x8001f
0x132d151: _initterm(0x40b00c, 0x40b010)
0x1333bc0: __getmainargs(0xffffdf9c, 0xffffdf8c, 0xffffdf98, 0x0, 0xffffdf90) = 0
0x132d151: _initterm(0x40b000, 0x40b008)
0x1001e10: GetStartupInfo(0xffffdfa0)
0x104d9f3: GetModuleHandleA(0x00) = 400000
0x125b18e: InternetOpenA(0x0, 0x1, 0x0, 0x0, 0x0)
0x126f0f1: InternetOpenUrlA(0x0, "http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com", "", 0x0, 0x84000000, 0x0)
Demo #2 在Ubuntu X64位上模擬ARM路由器固件
麒麟框架動態補丁及模擬ARM路由器固件,把其/usr/bin/httpd在X86_64位 Ubuntu上運行
qiling DEMO 2: Fully emulating httpd from ARM router firmware with Qiling on Ubuntu X64 machine
代碼樣本
from qiling import *
def my_sandbox(path, rootfs):
ql = Qiling(path, rootfs, stdin = sys.stdin, stdout = sys.stdout, stderr = sys.stderr)
# Patch 0x00005930 from br0 to ens33
ql.patch(0x00005930, b'ens33\x00', file_name = b'libChipApi.so')
ql.root = False
ql.run()
if __name__ == "__main__":
my_sandbox(["rootfs/tendaac15/bin/httpd"], "rootfs/tendaac15")
Demo #3 熱修補Windows crackme
麒麟框架熱修補丁Windows crackme程序使其顯示“Congratulation”窗口。
qiling DEMO 3: hotpatching a Windows crackme
代碼樣本
from qiling import *
def force_call_dialog_func(ql):
# get DialogFunc address
lpDialogFunc = ql.unpack32(ql.mem_read(ql.sp - 0x8, 4))
# setup stack memory for DialogFunc
ql.stack_push(0)
ql.stack_push(1001)
ql.stack_push(273)
ql.stack_push(0)
ql.stack_push(0x0401018)
# force EIP to DialogFunc
ql.pc = lpDialogFunc
def my_sandbox(path, rootfs):
ql = Qiling(path, rootfs)
# NOP out some code
ql.patch(0x004010B5, b'\x90\x90')
ql.patch(0x004010CD, b'\x90\x90')
ql.patch(0x0040110B, b'\x90\x90')
ql.patch(0x00401112, b'\x90\x90')
# hook at an address with a callback
ql.hook_address(0x00401016, force_call_dialog_func)
ql.run()
if __name__ == "__main__":
my_sandbox(["rootfs/x86_windows/bin/Easy_CrackMe.exe"], "rootfs/x86_windows")
執行輸出
0x10cae10: GetStartupInfo(0xffffdf40)
0x1121fa7: GetStdHandle(0xfffffff6) = 0xfffffff6
0x111fbc4: GetFileType(0xfffffff6) = 0x2
0x1121fa7: GetStdHandle(0xfffffff5) = 0xfffffff5
0x111fbc4: GetFileType(0xfffffff5) = 0x2
0x1121fa7: GetStdHandle(0xfffffff4) = 0xfffffff4
0x111fbc4: GetFileType(0xfffffff4) = 0x2
0x1121fd1: SetHandleCount(0x20) = 32
0x1121fbf: GetCommandLineA() = 0x501091b8
0x111fcd4: GetEnvironmentStringsW() = 0x501091e4
0x1117ffa: WideCharToMultiByte(0x0, 0x0, 0x501091e4, 0x1, 0x0, 0x0, 0x0, 0x0) = 2
0x1117ffa: WideCharToMultiByte(0x0, 0x0, 0x501091e4, 0x1, 0x50002098, 0x2, 0x0, 0x0) = 1
0x111fcbc: FreeEnvironmentStringsW(0x501091e4) = 1
0x1116a0b: GetACP() = 437
0x1121f8f: GetCPInfo(0x1b5, 0xffffdf44) = 1
0x1121f8f: GetCPInfo(0x1b5, 0xffffdf1c) = 1
0x111e43e: GetStringTypeW(0x1, 0x40541c, 0x1, 0xffffd9d8) = 0
0x10ffc95: GetStringTypeExA(0x0, 0x1, 0x405418, 0x1, 0xffffd9d8) = 0
0x111e39c: LCMapStringW(0x0, 0x100, 0x40541c, 0x1, 0x0, 0x0) = 0
0x1128a50: LCMapStringA(0x0, 0x100, 0x405418, 0x1, 0x0, 0x0) = 0
0x111e39c: LCMapStringW(0x0, 0x100, 0x40541c, 0x1, 0x0, 0x0) = 0
0x1128a50: LCMapStringA(0x0, 0x100, 0x405418, 0x1, 0x0, 0x0) = 0
0x111685a: GetModuleFileNameA(0x0, 0x40856c, 0x104) = 42
0x10cae10: GetStartupInfo(0xffffdfa0)
0x11169f3: GetModuleHandleA(0x00) = 400000
0x104cf42: DialogBoxParamA(0x400000, 0x65, 0x00, 0x401020, 0x00) = 0
Input DlgItemText :
<< enter any string or number here >>
0x1063d14: GetDlgItemTextA(0x00, 0x3e8, 0xffffdef4, 0x64) = 3
0x105ea11: MessageBoxA(0x00, "Congratulation !!", "EasyCrackMe", 0x40) = 2
0x1033ba3: EndDialog(0x00, 0x00) = 1
0x1124d12: ExitProcess(0x01)
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/1062/