本人今年应届生,就职于甲方安全,研究生期间主要做开发,偶尔做做渗透,护护网;工作了呢,主要维护内部系统的安全,对于移动逆向这块,只简单用burpsuite,顺顺利利抓过app的包。突然有一天,老大说,有个app,fiddler抓包,服务器不响应客户端发的包,让看看咋回事?于是就有了接下来三天不吃不喝不眠不休的入坑爬坑的过程~·所有用到的工具,都在文章开头列出
1 工具
1.1 抓包工具
工具名称 | 使用平台 | 抓包类型 | 优点 | 缺点 |
---|---|---|---|---|
Wireshark | linux、windows | 网络7层协议 | linux平台支持好,功能强大,可抓网络7层的包 | 不能解析https的内容 |
Fidder | windows | http,https 和FTP协议 | 功能强大,支持修改报文,重放报文 | 仅支持windows |
Charles | window、Mac | http,socket | 可以按照域名进行分层级查看 | 需要收费 |
BurpSuite | 支持java的平台 | http,https | 黑客喜欢用的功能强大工具,可以重放包,篡改包等进行一些包的攻击。 | 界面不是很好看 |
HttpCanary | Android | http,https,WebSocket | 使用方便 | 只支持Android |
手机只能安装crt证书
1.2 反汇编工具
描述 | 所需要软件 | 步骤 | 优缺点 |
---|---|---|---|
较老一套 | dex2jar:将dex转化成jar JD-GUI : 反编译jar中的源码 apktool.jar | Android反编译apk逆向分析 | 使用复杂 |
上面工具的封装 | AndroidKiller_v1.3.1 | AndroidKiller教程 | 使用复杂 |
强大 | jadx | 直接拖apk到即可 | 使用方便 |
1.3 查壳工具:
ApkScan
1.4 脱壳工具:
反射大师,FDEX等
2 逆向过程
·文章废话比较多,为了使各位看客看的明白,先抛出整个爬坑过程:抓包–》反汇编–》脱壳–》拿到私钥
2.1 抓包
话说回来,老大说fiddler抓包失败,于是乎,从网上下载fillder,用我的oppo手机装上证书,开始了第一次fiddler抓包之旅,网上随手找一篇抓包攻略,发现连接失败,(这里有个坑:公司网络刚好不可以访问这个app,开始弄了好久,都是0字节,后面换了自己热点,就出现连接失败,说到这里真的想吐槽公司网络)
接着用我最熟悉的burpsuite抓包,发现抓不了https的包,证书也安装了呀,其他https请求都可以抓,刚开始以为是证书的问题,并且app,始终报错,证书校验错误,让我更加以为是证书的问题。。但是又没办法解决,,就想着再换个抓包工具,charls抓包后send成功,但是response都失败了。
这时候打开微信问问我以前实验室的大佬,听说现在搞app逆向,他推荐了一款手机抓包神器httpCanary,直接安装到手机,抓包是超级方便呀,但是令人奔溃的是app依旧报错,证书校验错误,到这里内心很奔溃,开始网上搜,抓包失败,发现了这篇文章部分APP使用burpsuite抓不到包原因,猜测可能app使用了双向认证或SSL-pinning(证书绑定) ,并谷歌这两个词汇,理解如下:
单向认证:一般的客户端所作的都是单向认证,即客户端只需要验证服务器端的证书,确保服务器来源的可靠性,服务器端无需验证客户端证书。
双向认证:客户端验证服务器端证书,服务器端也需要验证客户端证书。
如上图所示: 证书锁定(SSL/TLS Pinning)提供了两种绑定方式: Certificate Pinning 和 Public Key Pinning,过程如下:
1):首先对服务器端证书/证书中的公钥进行哈希,得到ssl指纹内置到app中。
2):通信连接时,服务器发来证书。
3):app对该证书进行哈希操作,将哈希值与app内置的ssl指纹进行对比,若对比成功,则建立连接,否则,断开连接。
弄懂双向认证和ssl-pinning原理后,结合中间人攻击原理(如下图),进行猜想如下:
1)如果该app使用的双向认证,即同时认证客户端证书,则在下图中间人与服务器端的交互中,中间人需要提供app的证书。客户端与中间人交互正常。
2)如果该app使用的是ssl-pinning,即客户端需要对服务器证书进行校验,则在下图客户端与中间人交互中,中间人的需要提供原有服务器端的证书。中间人与服务器端交互正常。
无论是app证书还是服务器端证书,女生第六感觉得app中可能会有,因此下一步想着逆向app,看下app里面有没有证书啥的,然后代理绑定原有证书就可以正常抓包了。(后面发现我是有多天真)
2.2 反汇编
开始网上搜索apk反汇编教程,搜到了一篇超详细利用四件套反汇编apk教程,Android反编译apk逆向分析 ,按照他的步骤,先解压apk,查看解压后的文件发现了几个证书,一个后缀为cer的证书(看到这个证书个人感觉app应该用了双向认证吧,当时我愚蠢的以为这个证书即是服务器证书,也是客户端证书,因此下一步目标明确为:代理安装客户端证书即可),一个后缀为bks的deb_keystore.bks(这个时候我还不知道bks是啥)。
下一步目标为中间人代理安装app客户端证书,我常用的工具为burpsuite,发现其可以导入客户端证书,在user options->ssl-Clinet ssl certificates下:
后面发现burp suite只可导入pem类型的证书,且需要输入密码,这时候我天真的以为密码可以读取反汇编后的源码中找,然后将可以将cer证书转为pem 证书,就可以成功导入客户端证书。但是反汇编后的dex源码可读性很差,并没有得到有用的东西,又看看cer证书转为pem证书格式,发现需要私钥,哎,这个时候打开微信,找找以前实验室的大佬,有没有好的反汇编工具推荐(这个时候一直以为反汇编工具不行),大佬推荐了jadx神器,直接拖拉apk即可,但是反汇编出的代码可读性仍然不太高,并没有有用的信息。但是收获了,不同格式证书的区别,总结在此。于是又开始不断地谷歌,能否绕过ssl pinning(此时我也不确定是不是用了证书绑定还是双向认证,但是总得做点啥吧),网上绕过ssl pinning需要 JustTrustMe,root手机啥的,我这刚买的oppo,也不能root呀,变搬砖了没钱买呀。尝试用模拟器呢,这个app简直了,首先尝试强大的夜神模拟器,app打开没反应,接着逍遥模拟器失败,mumu模拟器失败,天天模拟器失败,哎筋疲力尽的一天··········出去上了个厕所透透气 回来,app到底是不是用了ssl pining?或者双向认证???于是用httpCanary重新抓包详细看看了,这个时候突然有了重大发现,httpCanary抓包失败,有报错信息如下:
抓包失败因为Android 7.0以上,系统就不会信任安装用户的证书,也就是说,android不信任装的httpCanary根证书,当app进行交互时,没有可信任的根证书,因此交互失败。从下图的流程图可以看到,如果根证书可信,才会去判断该证书是否校验成功(ssl pinning/双向认证成功),因此,该app可能没有做双向认证或者ssl pinning,做没做找个android 7.0以下的手机试试就知道了。
第二天,从家里拿了个之前的老手机,android 6.0系统的,安装httpcanary抓包,安装目标app,进行登录,突然发现旧手机的触屏有问题,刚好按密码那块失灵了我的天啊··真的命途多舛,·后面灵机一动,可以放大屏幕,移动到触屏好的区域输入即可(我可真是个小机灵鬼)果然抓包成功!!!1喜大普奔啊啊啊啊·昨天一天我是在搞啥呀····
然后贼开心的去找老大,说可以抓到包了,老大说通信内容可以解密么?需要看通信数据。分析下报文发现:
客户端app发送给服务器端用的是sm2密文(客户端存sm2公钥加密,服务器端存私钥解密),服务器端发送给客户端app的是AES密文(客户端和服务器端都存有AES对称密钥),即使逆向app,也只能发现AES密钥,sm2密钥存在服务器端,哎找到一个是一个吧,然后又开始漫漫长路~·…..
2.3 脱壳
之前反汇编的源码都没啥结果,又谷歌发现app是不是加了壳,做了代码混淆啥的,于是网上下载了查壳工具ApkScan,果然发现该app加了阿里聚安全的壳。然后在旧手机上开始了一系列脱壳之旅:
(1)首先使用网上教程脱壳工具FDex2,进行脱壳,(旧手机手机安装 VirtualXposed,FDex2+total conmander(自带amaze文件管理器下载打开失败)),但是并没有在data/data目录文件夹中看到dex文件,脱壳失败。
(2)然后使用网上超牛的反射大师进行脱壳,利用反射大师超详细脱壳教程,使用反射大师3.0,3.5版本,脱壳后有5个dex文件,但是源码可读性还是较差,没有找到有用代码,感觉脱壳还是失败。
(3)尝试其他脱壳工具,。。都一一失败···一无所获·不知所向~···
就这样又一天过去了~····回家睡觉
第三天换了清醒的脑袋,开始查看别人的脱壳经历,逆向app经历,突然发现一篇有趣的文章:为了抓包某app,我折腾了10天,原来他是用SSL Pinning防抓包的,看到楼主的经历,我内心也好过多了,翻看评论时候,看到有个读者提问密钥是怎么获取的,楼主说从低版本获取,这可是个重要信息呀。我立刻从网上下载了低版本,利用反射大师一顿操作猛如虎,逆向出8个dex文件,有7M,9M的,心想这下有希望了,果然逐个打开dex搜索AES,惊喜发现AES密钥:果然利用在线AES解密成功。
再搜索sm2_encrypt,发现sm2公钥和疑似sm2私钥(我的天,猜测app工程师用于测试忘记删除了)
将dex转为jar,IDE导入该库文件,调用apk中的sm2加解密函数,成功解密出交互密文!!
3 总结
头秃的三天终于结束了!!只是一个记录小白逆向app的心酸过程,总结三点如下:
(1)逆向低版本app,这个真的是太重要了
(2) 安卓模拟器运行app失败后,最好用Android7.0以下进行测试。
( 3)要有一个强大的内心和一直转的脑子搞不动了可以换换方向,说不定柳暗花明又一村呢···
参考:
3 破解https的SSL Pinning 很详细
4 Androidkiller反汇编失败的解决方案 能不用就不用,太复杂啦
5 证书格式互转 很nice 虽然我没用到
6 脱壳工具FDex2 很详细 但是 Amaze 文件管理器下载打开失败,尝试用total conmander成功
7 利用反射大师超详细脱壳教程 很nice,