工具介绍
iblessing是一款针对iOS安全的漏洞利用&安全审计套件,该工具可以帮助广大研究人员实现针对目标设备的应用程序信息收集、静态分析以及动态分析。除此之外,我们还可以使用iblessing来进行逆向工程分析、源代码分析以及漏洞挖掘等安全任务。
功能介绍
iblessing基于Unicorn引擎和Capstone引擎实现其功能。
跨平台特性;支持macOS和Ubuntu平台上使用。 iOS应用程序静态信息提取,包括元数据、嵌入链接和URL等等。 Mach-O解析器和dyld符号绑定模拟器。 Objective-C类的实现与解析。 扫描器支持对arm64汇编代码进行动态分析,并从中寻找关键信息或攻击面。 扫描器使用了Unicorn来部分模拟Mach-O arm64代码执行并寻找相关功能。 生成器可以对扫描器的报告进行二次处理,并开启一个查询服务器,或生成IDA脚本。 报告格式包括JSON等。
注意事项
源代码扫描器需要至少12GB的虚拟内存空间来加载mach-o文件,但实际上并不会消耗那么多内存。因此,我们的工作设备至少需要有12GB物理内存才行。当然了,你也可以通过swap文件机制来分配超过12GB大小的虚拟内存空间。
工具下载&使用
广大研究人员可以下载预发布的iblessing源码。 针对源代码设置chmod x权限。
工具构建
CMake
平台:macOS、Linux
广大研究人员可以运行下列命令来编译iblessing:
代码语言:javascript复制git clone --recursive -j4 https://github.com/Soulghost/iblessing
cd iblessing
./compile-cmake.sh
XcodeBuild
平台:macOS
广大研究人员可以运行下列命令来编译iblessing:
代码语言:javascript复制git clone --recursive -j4 https://github.com/Soulghost/iblessing
cd iblessing
./compile.sh
工具文档
工具概览:
扫描器:
扫描器组件可以对源代码文件进行静态或动态分析,并输出分析报告。比如说,objc-msg-xref扫描器可以对大部分objc_msgSend交叉引用进行动态分析。
代码语言:javascript复制[*] Scanner List:
- app-info: extract app infos
- objc-class-xref: scan for class xrefs
- objc-msg-xref: generate objc_msgSend xrefs record
- predicate: scan for NSPredicate xrefs and sql injection surfaces
- symbol-wrapper: detect symbol wrappers
生成器:
生成器组件可以对扫描器生成的报告进行二次处理。比如说,它可以基于objc-msg-xref扫描器的交叉引用报告来生成IDA脚本。
代码语言:javascript复制[*] Generator List:
- ida-objc-msg-xref: generator ida scripts to add objc_msgSend xrefs from objc-msg-xref scanner's report
- objc-msg-xref-server: server to query objc-msg xrefs
- objc-msg-xref-statistic: statistics among objc-msg-send reports
工具使用
扫描应用程序信息
代码语言:javascript复制> iblessing -m scan -i app-info -f <path-to-app-bundle>
比如说,我们用微信来举个例子:
代码语言:javascript复制> iblessing -m scan -i app-info -f WeChat.app
[*] set output path to /opt/one-btn/tmp/apps/WeChat/Payload
[*] input file is WeChat.app
[*] start App Info Scanner
[ ] find default plist file Info.plist!
[*] find version info: Name: 微信(WeChat)
Version: 7.0.14(18E226)
ExecutableName: WeChat
[*] Bundle Identifier: com.tencent.xin
[*] the app allows HTTP requests **without** exception domains!
[ ] find app deeplinks
|-- wechat://
|-- weixin://
|-- fb290293790992170://
|-- weixinapp://
|-- prefs://
|-- wexinVideoAPI://
|-- QQ41C152CF://
|-- wx703://
|-- weixinULAPI://
[*] find app callout whitelist
|-- qqnews://
|-- weixinbeta://
|-- qqnewshd://
|-- qqmail://
|-- whatsapp://
|-- wxwork://
|-- wxworklocal://
|-- wxcphonebook://
|-- mttbrowser://
|-- mqqapi://
|-- mqzonev2://
|-- qqmusic://
|-- tenvideo2://
...
[ ] find 507403 string literals in binary
[*] process with string literals, this maybe take some time
[ ] find self deeplinks URLs:
|-- weixin://opennativeurl/devicerankview
|-- weixin://dl/offlinepay/?appid=%@
|-- weixin://opennativeurl/rankmyhomepage
...
[ ] find other deeplinks URLs:
|-- wxpay://f2f/f2fdetail
|-- file://%@?lang=%@&fontRatio=%.2f&scene=%u&version=%u&type=%llu&%@=%d&qqFaceFolderPath=%@&platform=iOS&netType=%@&query=%@&searchId=%@&isHomePage=%d&isWeAppMore=%d&subType=%u&extParams=%@&%@=%@&%@=%@
...
[*] write report to path /opt/one-btn/tmp/apps/WeChat/Payload/WeChat.app_info.iblessing.txt
> ls -alh
-rw-r--r--@ 1 soulghost wheel 29K Jul 23 14:01 WeChat.app_info.iblessing.txt
扫描XREF类
仅支持ARM64源码:
代码语言:javascript复制iblessing -m scan -i objc-class-xref -f <path-to-binary> -d 'classes=<classname_to_scan>,<classname_to_scan>,...'
> restore-symbol WeChat -o WeChat.restored
> iblessing -m scan -i objc-class-xref -f WeChat.restored -d 'classes=NSPredicate'
[*] set output path to /opt/one-btn/tmp/apps/WeChat/Payload
[*] input file is WeChat
[ ] detect mach-o header 64
[ ] detect litten-endian
[*] start Objc Class Xref Scanner
[*] try to find _OBJC_CLASS_$_NSPredicate
[*] Step 1. locate class refs
[ ] find _OBJC_CLASS_$_NSPredicate at 0x108eb81d8
[*] Step 2. find __TEXT,__text
[ ] find __TEXT,__text at 0x4000
[*] Step 3. scan in __text
[*] start disassembler at 0x100004000
[*] 0x1002e1a50/0x1069d9874 (2.71%) [ ] find _OBJC_CLASS_$_NSPredicate ref at 0x1002e1a54
...
[*] Step 4. symbolicate ref addresses
[ ] _OBJC_CLASS_$_NSPredicate -|
[ ] find _OBJC_CLASS_$_NSPredicate ref -[WCWatchNotificationMgr addYoCount:contact:type:] at 0x1002e1a54
[ ] find _OBJC_CLASS_$_NSPredicate ref -[NotificationActionsMgr handleSendMsgResp:] at 0x1003e0e28
[ ] find _OBJC_CLASS_$_NSPredicate ref -[FLEXClassesTableViewController searchBar:textDidChange:] at 0x1004a090c
[ ] find _OBJC_CLASS_$_NSPredicate ref [GameCenterUtil parameterValueForKey:fromQueryItems:] at 0x1005a823c
[ ] find _OBJC_CLASS_$_NSPredicate ref [GameCenterUtil getNavigationBarColorForUrl:defaultColor:] at 0x1005a8cd8
...
扫描所有的objc_msgSend XREFs
仅支持ARM64源码。
简单模式:
代码语言:javascript复制iblessing -m scan -i objc-msg-xref -f <path-to-binary>
反封装器模式:
代码语言:javascript复制iblessing -m scan -i objc-msg-xref -f WeChat -d 'antiWrapper=1'
反封装器模式将会检测objc_msgSend封装器并进行转化:
代码语言:javascript复制; __int64 __usercall objc_msgSend_X0_X22_X20@<X0>(void *obj@<X0>, const char *sel@<X22>, id anyObj@<X20>, ...)
objc_msgSend_X0_X22_X20:
MOV X1, X22
MOV X2, X20
B objc_msgSend
使用样例:
代码语言:javascript复制> iblessing -m scan -i objc-msg-xref -f WeChat -d 'antiWrapper=1'
[*] set output path to /opt/one-btn/tmp/apps/WeChat/Payload
[*] input file is WeChat
[ ] detect mach-o header 64
[ ] detect litten-endian
[*] !!! Notice: enter anti-wrapper mode, start anti-wrapper scanner
[*] start Symbol Wrapper Scanner
[*] try to find wrappers for_objc_msgSend
[*] Step1. find __TEXT,__text
[ ] find __TEXT,__text at 0x100004000
[ ] mapping text segment 0x100000000 ~ 0x107cb0000 to unicorn engine
[*] Step 2. scan in __text
[*] start disassembler at 0x100004000
[*] / 0x1069d986c/0x1069d9874 (100.00%)
[*] reach to end of __text, stop
[ ] anti-wrapper finished
[*] start ObjcMethodXrefScanner Exploit Scanner
[*] Step 1. realize all app classes
[*] realize classes 14631/14631 (100.00%)
[ ] get 667318 methods to analyze
[*] Step 2. dyld load non-lazy symbols
[*] Step 3. track all calls
[*] progress: 667318 / 667318 (100.00%)
[*] Step 4. serialize call chains to file
[*] saved to /opt/one-btn/tmp/apps/WeChat/Payload/WeChat_method-xrefs.iblessing.txt
> ls -alh WeChat_method-xrefs.iblessing.txt
-rw-r--r-- 1 soulghost wheel 63M Jul 23 14:46 WeChat_method-xrefs.iblessing.txt
> head WeChat_method-xrefs.iblessing.txt
iblessing methodchains,ver:0.2;
chainId,sel,prefix,className,methodName,prevMethods,nextMethods
182360,0x1008a0ab8, [A8KeyControl initialize], ,A8KeyControl,initialize,[],[4429#0x1008a1064@4376#0x1008a1050@13769#0x1008a10d0]
182343,0x1008a0ad0, [A8KeyControl_QueryStringTransferCookie initialize], ,A8KeyControl_QueryStringTransferCookie,initialize,[],[4429#0x1008a1064@4376#0x1008a1050@13769#0x1008a10d0]
145393,0x1008c2220, [A8KeyResultCookieWriter initWithDomain:weakWebView:andCompleteBlock:], ,A8KeyResultCookieWriter,initWithDomain:weakWebView:andCompleteBlock:,[145386#0x10036367c],[]
145396,0x1008c3df8, [A8KeyResultCookieWriter setA8KeyCookieExpireTime:], ,A8KeyResultCookieWriter,setA8KeyCookieExpireTime:,[145386#0x1003636e8],[]
145397,0x1008c27e8, [A8KeyResultCookieWriter writeCompleteMarkerCookieValue:forKey:], ,A8KeyResultCookieWriter,writeCompleteMarkerCookieValue:forKey:,[145386#0x10036380c],[]
253456,0x0, [AAOperationReq init], ,AAOperationReq,init,[253455#0x1039a9d30],[]
253457,0x0, [AAOperationReq setBaseRequest:], ,AAOperationReq,setBaseRequest:,[253455#0x1039a9d8c],[]
186847,0x0, [AAOperationRes length], ,AAOperationRes,length,[186845#0x10342aa54],[]
注意,这里生成的报告可以传递给生成器使用。
生成objc_msgSend Xrefs查询服务器
我们可以通过iblessing的objc-msg-xref-server生成器来查询所有的objc_msgSend xrefs:
代码语言:javascript复制iblessing -m generator -i objc-msg-xref-server -f <path-to-report-generated-by-objc-msg-xref-scanner>
指定监听的主机和端口
默认监听地址为127.0.0.1:2345,你可以使用-d选项来进行配置:
代码语言:javascript复制iblessing -m generator -i objc-msg-xref-server -f WeChat_method-xrefs.iblessing.txt -d 'host=0.0.0.0;port=12345'
使用样例:
代码语言:javascript复制> iblessing -m generator -i objc-msg-xref-server -f WeChat_method-xrefs.iblessing.txt
[*] set output path to /opt/one-btn/tmp/apps/WeChat/Payload
[*] input file is WeChat_method-xrefs.iblessing.txt
[*] start ObjcMsgXREFServerGenerator
[*] load method-chain db for version iblessing methodchains,ver:0.2;
[*] table keys chainId,sel,prefix,className,methodName,prevMethods,nextMethods
[-] bad line 104467,0x0, [TPLock P, ], ,TPLock,P, ,[104426#0x1043b9904],[]
[-] bad line 114905,0x0,?[0x108ce1578 (,],?,0x108ce1578,(,,[114900#0x1011e8c68],[]
[-] bad line 104464,0x0,?[? P, ],?,?,P, ,[104426#0x1043b98a8],[]
[-] bad line 139234,0x0,?[? X
[-] bad line ],?,?,X
[-] bad line ,[139205#0x1013c222c],[]
[ ] load storage from disk succeeded!
[*] listening on http://127.0.0.1:2345
接下来,可以打开浏览器并输入http://127.0.0.1:2345,然后查询任意objc_msgSend xrefs:
针对objc_msgSend xrefs生成IDA脚本
代码语言:javascript复制iblessing -m generator -i ida-objc-msg-xref -f <path-to-report-generated-by-objc-msg-xref-scanner>
使用样例:
代码语言:javascript复制> iblessing -m generator -i ida-objc-msg-xref -f WeChat_method-xrefs.iblessing.txt
[*] set output path to /opt/one-btn/tmp/apps/WeChat/Payload
[*] input file is WeChat_method-xrefs.iblessing.txt
[*] start IDAObjMsgXREFGenerator
[*] load method-chain db for version iblessing methodchains,ver:0.2;
[*] table keys chainId,sel,prefix,className,methodName,prevMethods,nextMethods
[-] bad line 104467,0x0, [TPLock P, ], ,TPLock,P, ,[104426#0x1043b9904],[]
[-] bad line 114905,0x0,?[0x108ce1578 (,],?,0x108ce1578,(,,[114900#0x1011e8c68],[]
[-] bad line 104464,0x0,?[? P, ],?,?,P, ,[104426#0x1043b98a8],[]
[-] bad line 139234,0x0,?[? X
[-] bad line ],?,?,X
[-] bad line ,[139205#0x1013c222c],[]
[ ] load storage from disk succeeded!
[*] Generating XREF Scripts ...
[*] saved to /opt/one-btn/tmp/apps/WeChat/Payload/WeChat_method-xrefs.iblessing.txt_ida_objc_msg_xrefs.iblessing.py
> ls -alh WeChat_method-xrefs.iblessing.txt_ida_objc_msg_xrefs.iblessing.py
-rw-r--r-- 1 soulghost wheel 23M Jul 23 16:16 WeChat_method-xrefs.iblessing.txt_ida_objc_msg_xrefs.iblessing.py
> head WeChat_method-xrefs.iblessing.txt_ida_objc_msg_xrefs.iblessing.py
def add_objc_xrefs():
ida_xref.add_cref(0x10036367c, 0x1008c2220, XREF_USER)
ida_xref.add_cref(0x1003636e8, 0x1008c3df8, XREF_USER)
ida_xref.add_cref(0x10036380c, 0x1008c27e8, XREF_USER)
ida_xref.add_cref(0x103add16c, 0x700006e187a8, XREF_USER)
ida_xref.add_cref(0x102cbee0c, 0x101143ee8, XREF_USER)
ida_xref.add_cref(0x10085c92c, 0x1005e9360, XREF_USER)
ida_xref.add_cref(0x10085c8bc, 0x1005e9274, XREF_USER)
ida_xref.add_cref(0x10085c8dc, 0x1005e92bc, XREF_USER)
ida_xref.add_cref(0x10085c8cc, 0x1005e9298, XREF_USER)
接下来,打开IDA,点击文件->脚本文件,并加载脚本:
针对Objc运行时函数重命名和Prototype修改生成IDA脚本
代码语言:javascript复制iblessing -m generator -i ida-symbol-wrapper-naming -f <path-to-report-from-symbol-wrapper>
使用样例:
代码语言:javascript复制> iblessing -m generator -i ida-symbol-wrapper-naming -f Aweme_wrapper-graph.iblessing.txt
[*] set output path to /Users/soulghost/Desktop/git/iblessing-public/iblessing/build/Debug
[*] input file is Aweme_wrapper-graph.iblessing.txt
[*] start IDAObjMsgXREFGenerator
[*] load symbol-wrappers db for version iblessing symbol-wrappers,ver:0.1;
[*] table keys wrapperId;address;name;prototype
[*] Generating Naming Scripts ...
[*] saved to /Users/soulghost/Desktop/git/iblessing-public/iblessing/build/Debug/Aweme_wrapper-graph.iblessing.txt_ida_symbol_wrapper_naming.iblessing.py
> head Aweme_wrapper-graph.iblessing.txt_ida_symbol_wrapper_naming.iblessing.py
def namingWrappers():
idc.set_name(0x100022190, '_objc_retainAutoreleasedReturnValue', ida_name.SN_FORCE)
idc.apply_type(0x100022190, idc.parse_decl('id __usercall f@<x0>(id@<x0>)', idc.PT_SILENT))
idc.set_name(0x100022198, '_objc_retainAutoreleasedReturnValue', ida_name.SN_FORCE)
idc.apply_type(0x100022198, idc.parse_decl('id __usercall f@<x0>(id@<x0>)', idc.PT_SILENT))
idc.set_name(0x1000221a0, '_objc_release', ida_name.SN_FORCE)
idc.apply_type(0x1000221a0, idc.parse_decl('id __usercall f@<x0>(id@<x22>)', idc.PT_SILENT))
idc.set_name(0x1000221a8, '_objc_msgSend', ida_name.SN_FORCE)
idc.apply_type(0x1000221a8, idc.parse_decl('id __usercall f@<x0>(id@<x0>, const char*@<x20>, ...)', idc.PT_SILENT))
idc.set_name(0x100022448, '_objc_release', ida_name.SN_FORCE)
打开IDA,点击文件->脚本文件,加载目标脚本:
项目地址
iblessing:https://github.com/Soulghost/iblessing