iOS|iOS 模块分解—「逆向流程分析(上)」
引言
本文测试工具 iPhone:7P、iOS9.3.2
- ios逆向工程指的是在软件层面上进行逆向分析的一个过程。如果想要达到对ios软件较强的逆向分析能力,最好能非常熟悉ios设备的硬件构成、ios系统的运行原理,还要具备丰富的ios开发经验,比如:拿到一个App之后能清晰的推断出这个App使用的技术,包括引用了那些FrameWork,那些经典的第三方代码,以及整个App工程大致的文件个数等。
- 逆向工程的主要两个作用:首先是攻破目标程序,拿到关键信息,可以归类于安全相关的逆向工程,其次是借鉴他人的程序功能来开发自己的软件,可以归类于开发相关的逆向工程
- 与安全相关的ios逆向工程
ios 逆向工程最突出的应用领域就是与安全相关的,比如:通过逆向一个金融App,来评定这个软件的安全等级,安全专家通过逆向ios病毒,来找到杀毒的方法,安全公司通过逆向ios系统电话、短信功能,来构建一个手机防火墙
ios中那些具有交易功能的App一般会先加密敏感数据,然后将加密过的数据存储在本地或通过互联网传输,而如果安全意识不够强,就完全有可能将重要信息直接用明文保存或传输,安全隐患极大。App虽然可以将低维的攻击防守得如铜墙铁壁一般,但是挡不住高维的逆向攻击,不过不可以据此得出App不安全的结论,因为ios逆向工程的使用均来自一个前提:ios越狱,在这种环境下,我们使用这些逆向工程技术来分析评估目标App中可被攻击点有多少,可攻击点越少的自然就越安全。
b. 逆向恶意软件
ios 是只能移动终端操作系统,它同计算机操作系统没有本质区别,恶意软件就是通过逆向工程定位系统和软件漏洞,利用漏洞渗透进目标主机,获取敏感数据
- 与开发相关的ios逆向工程
开发者可以逆向系统调用,在自己的程序里使用一些文档中没有提及的私有功能,还可以逆向一些经典的软件等
a.逆向系统调用
开发者编写的软件能够运行在操作系统中,提供各种各样的功能,是因为操作系统本身已经内嵌了这些功能,软件只是拿来重组使用。绝大多数的App的实现都源于公开的开发文档,而不能使用诸如锁屏,关机等文档中不涉及的功能,如果你的程序面向Cydia,那么不采用非公开功能将导致程序几乎没有竞争力,故可以通过逆向ios系统调用,还原系统实现相应功能的代码,并应用到自己的程序中。
b.借鉴别的软件
逆向工程最受欢迎的应用场合就是“借鉴”他人的软件功能。
不完美越狱,iPhone一旦关机后再开机时,屏幕就会一直停留在启动画面,也就是“白苹果”状态。或者能正常开机,但已经安装的破解软件都无法正常使用,需要将设备与PC连接后,使用软件进行引导才能使用。一般说来,在苹果发布新的iOS固件后,针对该固件的不完美越狱会先发布,随后完美越狱才可能发布,一般较新的系统版本,均为不完美越狱
越狱方法推荐
PP助手:http://jailbreak.25pp.com/
ps:不同机型,不同系统,有的可以越狱,有的不可以
http://jailbreak.25pp.com/iphone5syueyu/
如何判断是否越狱成功?
- 桌面是否有cydia
文章图片
文章图片
image.png 使用cydia安装软件
文章图片
Snip20180927_2.png 一、远程登录到手机: SSH介绍 SSH是Secure Shell的缩写,意为"安全外壳协议",是远程登录会话和其他网络服务提供安全性的协议,用于计算机之间的加密登录,使用SSH,可以把所有传输的数据进行加密,"中间人"攻击方式就不可能实现,防止DNS欺骗和IP欺骗,
OpenSSH
是SSH协议的免费开源的实现,是一个运用ssh、提供ssh登录的一个软件。- SSH过程
client首先向server发送登录请求
server收到请求以后发送一个公钥给client
client将密码用公钥加密以后发给server
server收到这段信息,用私钥解密,如果是正确的密码就登录成功
文章图片
SSH登录原理.png
- ssh安全隐患-中间人攻击(MITM攻击)
在client向server发送请求的时候,在client与server之间架起伪server然后拦截client的请求
用伪server向server发送一个登录请求,
server生成密钥A:公钥A,私钥A 反给伪server
伪server拿到公钥A以后,立马生成一对密钥B:公钥B、私钥B,将公钥B反给client
client拿到公钥B以后进行密码加密,发送server,然后伪server拦截
伪server拿到这段密文,用私钥B进行解密拿到密码,发送给黑客server,再将密码用公钥A进行加密发送给server
文章图片
SSH中间人攻击.png 1、WiFi使用SSH登录到手机:
- 准备
在同一个Wi-Fi下使用ssh
越狱机中先安装插件OpenSSH,密码在openSSH可以查看,初始密码为alpine,默认端口是22
OpenSSH使用方法如下:
文章图片
openssh.png
- 操作:
//192.168.68.178 为手机的IP
GarryKings-Mac:~ macair$ ssh root@192.168.68.178
root@192.168.68.178's password:
fall1994de-iPhone:~ root#
2、通过usbmuxd登录到手机:
- 准备
usbmuxd下载
下载完成后如下:
文章图片
usermuxd.png
- 操作:
//在下载的文件下
/Users/macair/usbmuxd
GarryKings-Mac:usbmuxd macair$ cd python-client/
//查看内容
GarryKings-Mac:python-client macair$ ls
tcprelay.py usbmux.pyusbmux.pyc
//执行Python里脚本,进行端口转发,把手机的22端口(SSH端口)转发为Mac本地的2222端口
GarryKings-Mac:python-client macair$ python tcprelay.py 22:2222
Forwarding local port 2222 to remote port 22
Incoming connection to 2222
Waiting for devices...
Connecting to device
Connection established, relaying data
打开另一个终端:
//登录手机端口、localhost是一个域名
GarryKings-Mac:~ macair$ ssh root@localhost -p 2222
root@localhost's password:
fall1994de-iPhone:~ root#
二、砸壳
- 前言
从 APPStore 商店下载安装的APP 默认都被苹果加了一层壳,加了壳后我们就无法使用dump导出头文件等其它操作,所以我们就必须要砸壳1、砸壳方式
- a、静态砸壳
静态砸壳使用Clutch, 主动调起iPhone的解密功能, 得到解密的APP文件
步骤:
1、下载Clutch,
2、copy Clutch文件到手机的 /usr/bin/ 目录下
scp -P 2222 Clutch root@127.0.0.1:/usr/bin/
3、查看可砸壳的应用Clutch -i
4、砸壳应用Clutch -d bundleId
5、查看砸壳后的路径,生产.ipa文件
6、验证是否砸壳成功: cryptid 为 0, 即没有任何加密,砸壳成功
- 操作
//ssh登录到手机
macair:~ GarryKings-Mac$ ssh root@192.168.68.178
root@192.168.68.178's password:
//进入手机的bin目录下
fall1994de-iPhone:~ root# cd /usr/bin/
//找到Clutch
fall1994de-iPhone:/usr/bin root# ls
Clutch*expr*mkfifo*ssh-keygen*
//查看Clutch说明
fall1994de-iPhone:/usr/bin root# Clutch
2018-08-07 17:04:16.671 Clutch[2104:61556] command: None command
Usage: Clutch [OPTIONS]
-b --binary-dumpOnly dump binary files from specified bundleID
-d --dumpDump specified bundleID into .ipa file
-i --print-installedPrints installed applications
--cleanClean /var/tmp/clutch directory
--versionDisplay version and exit
-? --helpDisplays this help and exit
-n --no-colorPrints with colors disabled
-v --verbosePrint verbose messages
//查看手机上可砸壳的应用
fall1994de-iPhone:/usr/bin root# Clutch -i
2018-08-07 17:04:39.962 Clutch[2105:61595] command: Prints installed applications
Installed apps:
1:百度网盘
2:今日头条
3:QQ
4:微信
5:钉钉
6:火山小视频 - 分享生活,让世界为你点赞
7:WhatsApp Messenger
8:苹果助手
9:快扫二维码
10:播放器OPlayer Lite - 视频播放器
//砸壳应用
fall1994de-iPhone:/usr/bin root# Clutch -d com.olimsoft.oplayer.lite
2018-08-07 17:04:53.531 Clutch[2106:61621] command: Dump specified bundleID into .ipa file
Zipping OPlayer Lite.app
Dumping (arm64)
Patched cryptid (64bit segment)
Writing new checksum
Dumping (arm64)
Patched cryptid (64bit segment)
Writing new checksum
Zipping OPlayer WatchKit Extension.appex
//砸壳后生产的ipa包
DONE: /private/var/mobile/Documents/Dumped/com.olimsoft.oplayer.lite-iOS7.0-(Clutch-(null))-3.ipa
Finished dumping com.olimsoft.oplayer.lite in 21.2 seconds
fall1994de-iPhone:/usr/bin root# exit
logout
Connection to 192.168.68.178 closed.
macair:~ GarryKings-Mac$ cd /Users/macair/Desktop/reverse
//验证是否砸壳成功,cryptid 0没有加密,砸壳成功
macair:reverse GarryKings-Mac$ otool -l OPlayer\ Lite | grep crypt
cryptoff 16384
cryptsize 21282816
cryptid 0
macair:reverse GarryKings-Mac$
通过iTool查看路径如下图:
DONE: /private/var/mobile/Documents/Dumped/com.olimsoft.oplayer.lite-iOS7.0-(Clutch-(null))-5.ipa
文章图片
ipapath.png
- b、动态砸壳
准备:
dumpdecrypted下载,并编译,得到步骤:dumpdecrypted.dylib
原理:将应用运行起来, 然后从内存中得到已经解密的Mach-O文件
1、注入dumpdecrypted 到需要砸壳的应用
- 操作
//ssh登录手机
macair:~ GarryKings-Mac$ ssh root@192.168.68.172
//默认密码alpine
root@192.168.68.172's password:
//查看手机进程
fall1994de-iPhone:~ root# ps -e
PID TTYTIME CMD
1 ??2:04.09 /sbin/launchd
1352 ??0:01.79 /usr/sbin/syslogd
1354 ??0:00.12 /usr/sbin/WirelessRadioManagerd
.
.
.
1933 ??0:00.05 /usr/sbin/filecoordinationd
1967 ??0:01.80 /var/containers/Bundle/Application/9AA9E393-EE7A-47A6-B0BB-75F60C56A688/WeChat.app/WeChat
1969 ??0:00.20 sshd: root@ttys000
1971 ttys0000:00.03 -sh
1974 ttys0000:00.01 ps -e
//附加进程
fall1994de-iPhone:~ root# cycript -p 1967
//查看路径
cy# [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]
#"file:///var/mobile/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents/"
cy#
//control+d退出,进入终端二、执行完成后进入到wechat的Documents目录下
fall1994de-iPhone:~ root# cd /var/mobile/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents
//利用环境变量 DYLD_INSERT_LIBRARY 来添加动态库dumpdecrypted.dylib
fall1994de-iPhone:/var/mobile/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/9AA9E393-EE7A-47A6-B0BB-75F60C56A688/WeChat.app/WeChat
Killed: 9
//su mobile解决Killed: 9的问题
fall1994de-iPhone:/var/mobile/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents root# su mobile
fall1994de-iPhone:~/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents mobile$ DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/9AA9E393-EE7A-47A6-B0BB-75F60C56A688/WeChat.app/WeChat
mach-o decryption dumperDISCLAIMER: This tool is only meant for security research purposes, not for application crackers.[+] detected 64bit ARM binary in memory.
[+] offset to cryptid found: @0x100018ca8(from 0x100018000) = ca8
[+] Found encrypted data at address 00004000 of length 59129856 bytes - type 1.
[+] Opening /private/var/containers/Bundle/Application/9AA9E393-EE7A-47A6-B0BB-75F60C56A688/WeChat.app/WeChat for reading.
[+] Reading header
[+] Detecting header type
[+] Executable is a plain MACH-O image
[+] Opening WeChat.decrypted for writing.
[+] Copying the not encrypted start of the file
[+] Dumping the decrypted data into the file
[+] Copying the not encrypted remainder of the file
[+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset ca8
[+] Closing original file
[+] Closing dump file
//查看砸壳后得到的WeChat.decrypted
fall1994de-iPhone:~/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents mobile$ ls
000000000000000000000000000000008988bed64ad49de43bb92358e80eb712LocalInfo.lstMemoryStatWeChat.decryptedc6b1224b7e98abe938eb5a77961de633heavy_user_id_mapping.dat
0536d2db0169c7330e147ab22b4c12d89083f532701f365dcb748827438e4ac8LoginInfo2.datOpenImResourceaa5c5b713a622d61083988a71b0b448ad6ff5cb02a15b19eb7f797dc866de9e7mmupdateinfo.archive
516c1e86e3a79d704c7c78dbf43cba82CrashReportMMResourceMgrSMReport.datapp_tuttdb.globalconfig
5b8df94ef782697848221b40d04d9835KsidMMappedKVSafeMode.datc5488da61168334a11af0d0e524109dbdumpdecrypted.dylib
fall1994de-iPhone:~/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents mobile$
文章图片
wechatdec.png 终端二:
/Users/macair/dumpdecrypted
//用scp命令将dumpdecrypted.dylib copy到要砸壳应用的Documents目录下
macair:dumpdecrypted GarryKings-Mac$ scp ./dumpdecrypted.dylib root@192.168.68.172:/var/mobile/Containers/Data/Application/BCEF4156-0E01-4D7A-89D7-4898DD3A1A88/Documents
root@192.168.68.172's password:
dumpdecrypted.dylib100%193KB1.2MB/s00:00
macair:dumpdecrypted GarryKings-Mac$
终端三:
/Users/macair/Desktop/reverse
//验证得到的WeChat.decrypted是否解密
macair:reverse GarryKings-Mac$ otool -l WeChat.decrypted | grep crypt
WeChat.decrypted:
cryptoff 16384
cryptsize 59129856
cryptid 0
macair:reverse GarryKings-Mac$
2、用class-dump开始砸壳: 步骤:
1、下载 class-dump,编译生成class-dump的可执行文件
如下图:
文章图片
class-dump.png
文章图片
class-dumpu-nix.png 2、终端执行命令 ./class-dump XXXX -H -o ./headers 得到.h文件
如下图:
文章图片
headers.png 操作:
/Users/macair/Desktop/reverse
//查看是否解密
macair:reverse GarryKings-Mac$ otool -l OPlayer\ Lite| grep crypt
cryptoff 16384
cryptsize 21282816
cryptid 0
//查看class-dump命令
macair:reverse GarryKings-Mac$ ./class-dump
class-dump 3.5 (64 bit) (Debug version compiled Aug3 2018 15:06:07)
Usage: class-dump [options] where options are:
-ashow instance variable offsets
-Ashow implementation addresses
.
.
.--sdk-rootspecify the full SDK root path (or use --sdk-ios/--sdk-mac for a shortcut)
//生产.h头文件
macair:reverse GarryKings-Mac$ ./class-dump OPlayer\ Lite -H -o ./headers
2018-08-08 11:13:28.898 class-dump[7327:103611] Warning: Parsing instance variable type failed, _canMakePayments
macair:reverse GarryKings-Mac$
三、用 cycript 定位到感兴趣的视图
步骤:
1、登录到手机,查看进程
2、找到OPlayer Lite的进程ID,查看APP的当前界面结构,定位到广告视图的view
3、去除广告视图,分析:广告是个小的UIView,一定有个地方进行了addSubView的操作添加到大的View上,那么定位到调用的地方,改变逻辑,让调用者绕过addSubView
操作:
//SSH登录到手机
macair:~ GarryKings-Mac$ ssh root@localhost -p 2222
//默认密码alpine
root@localhost's password:
//查看手机进程
fall1994de-iPhone:~ root# ps -e
PID TTYTIME CMD
1 ??0:47.59 /sbin/launchd
240 ??0:32.77 /usr/sbin/syslogd
242 ??0:00.95 /usr/sbin/WirelessRadioManagerd
.
.
.
2951 ??0:10.68 /var/containers/Bundle/Application/9995465C-AD4C-434D-92AF-2CDC46EA60E8/OPlayer Lite.app/OPlayer Lite
3002 ??0:00.18 sshd: root@ttys000
3004 ttys0000:00.03 -sh
3007 ttys0000:00.01 ps -e
//附加进程
fall1994de-iPhone:~ root# cycript -p 2951
//查看当前UI的视图层次机构
cy# [[UIApp keyWindow ]recursiveDescription ].toString()
`;
layer = >
| >
|| >
||| >
|||| >
|||| >
|||||(layer)
|||||| (layer)
||||||| (layer)
|||||| (layer)
||||||(layer)
||| >
||| >
|||| >
||||| >
|||| >
||||| <_UILabelContentLayer: 0x124796d50> (layer)
||| >
|||| >
||||| >
||||| ;
value: 231.000000>
|||||| >
||||||| >
|||||| >
|||||| >
||||| >
|||| >
|||| >
|||| >
||||| >
|||| >
||||| >
||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||||| >
|||||| >
||||| ;
value: 0.000000>
|||||| >
||||||| >
|||||| >
|||||| >
|||| >
||||| >
|||| >
||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
||| >
||| >
|||| <_UILabelContentLayer: 0x12470a710> (layer)
||| >
|||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
||| >
|||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
|||| >
||||| >
||| >
|||| >
||| >
|||| >`
cy# [#0x1258c5ba0 setHidden: YES]
cy# [#0x1258c5ba0 setHidden: NO]
cy# [[UIApp keyWindow ]recursiveDescription ].toString()
`;
layer = >
| >
|| >
||| >
|||| >
|||| >
|||||(layer)
|||||| (layer)
||||||| (layer)
|||||| (layer)
||||||(layer)
||| >
||| >
|||| ;
layer = >
||||| ;
layer = ;
contentOffset: {0, 0};
contentSize: {0, 0}>
|||||| >
|||||| >
||||| >
|||||| >
||||||| <_UIWebViewScrollView: 0x1249ce000;
frame = (0 0;
320 50);
clipsToBounds = YES;
autoresize = H;
gestureRecognizers = ;
layer = ;
contentOffset: {0, 0};
contentSize: {320, 51}>
|||||||| ;
layer = >
||||||||| (layer)
|||||||||| (layer)
||||||||| (layer)
|||||||||| (layer)
||||||||||| (layer)
|||||||||||| (layer)
||||||||||||| (layer)
|||||||||||| (layer)
||||||||||||| (layer)
|||||||||||| (layer)
|||||||||||| (layer)
||||||||||| (layer)
|||||||| >
|||||||| >
||| >
|||| 【iOS|iOS 模块分解—「逆向流程分析(上)」】>
||||| >
||||| ;
value: 139.000000>
|||||| >
||||||| >
|||||| >
|||||| >
||||| >
|||| >
|||| >
|||| >
||||| >
|||| >
||||| >
||| >
.
.
.
||| >
|||| >`
cy# [#0x12811ed00 setHidden: YES]
cy# [#0x12811ed00 setHidden:NO]
cy#
fall1994de-iPhone:~ root#
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- SpringBoot调用公共模块的自定义注解失效的解决
- Node.js中readline模块实现终端输入
- python自定义封装带颜色的logging模块
- 解决SpringBoot引用别的模块无法注入的问题
- iOS中的Block
- Python(pathlib模块)
- Apache多路复用模块(MPMs)介绍
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 2019-08-29|2019-08-29 iOS13适配那点事