android https 抓包
前几天有个需求,要破解一下某个app的部分通讯协议,需要了解一下某部分功能如何实现,甚至通过其协议抓取一些数据。而这个app只有android版本和ios版本。从初步看,这个app是同React Native写的。
虽然https是加密的,不过查看https本来感觉这并不是什么太复杂的事情,引入一个中间人就可以了。虽然在浏览器会弹出CA不可信任的警告,不过对于app来说,如果不作特殊处理(一般人也不会特殊处理),一般没什么影响。而这事在很久之前也是做过的了。没想到现在的android却提高了难度。记录一下步骤,以备后续可能需要查看。
普通 https 抓包
在mac下面最常用的是charles,其他平台有类似的软件。 步骤如下:
-
charles打开代理
如图示,如此经过操作后,经过此代理的http/https报文即可被捕获(中间人)。
代理设置:
SSL设置:
打开代理:
-
配置服务端客户端证书
经过上述配置,虽然可以实现了中间人捕获报文,可是https的内容是无法查看的,所以需要配置证书后才可以解密。步骤如图示:
-
电脑端:
添加证书:  设置信任证书: 
-
手机端:
设置代理:  添加信任的证书: 
-
以上便是网上能搜索到的方式,也是以前自己抓取https报文的步骤,如果一切那么顺利便不会有这篇记录。因为在从android7.0开始后,android手机即使你添加信任的证书后,系统依然是不信任你的证书的,只信任系统的证书。所以,任何请求都不会使用到这个用户证书,也因此,https的报文依然是无法解密的。
android7以上https抓包
针对android7.0以上系统,这个办法的解决方式也是挺粗暴的,既然只信任系统证书,那么就移动真是到系统目录不就可以了?而此方式必须要系统root方可以。这是不愿意做的,除非可以使用一个已经root的模拟器,不过这个好像比较难找。
除此之外,网上还有一种方式,那就是自己编码让其信任用户证书。具体的步骤也挺简单的,如下:
-
新建network_security_conf.xml文件
放在res/xml下面,此文件意思就告诉系统,让系统信任用户证书,内容大体如下:
1
<?xml version="1.0" encoding="utf-8"?>
-
AndroidManifest.xml修改
与此同时在AndroidManifest.xml文件的application字段后增加
android:usesCleartextTraffic="true" android:networkSecurityConfig="@xml/network_security_config"
内容。
然而,这个app并非自己所写的,本来就没有源码,所以必须反编译后修改,再重新签名。这个方式网上也有比较详细的方式,大体涉及三个工具:
-
apktool,编译和反编译apk,从apk中提取图片和布局资源
-
dex2jar,将可运行文件classes.dex反编译为jar源码文件
-
jd-gui,查看jar源码文件
网上已经有比较详细的方式,这里不再累赘。而现实修改的只涉及资源文件,所以,只用到apktool即可,而且只需要两个命令。
解包:apktool d -o dec xx.apk
重新打包:apktool b -o yy.apk dec/
重新打包后的apk需要经过重新签名之后,方可安装,步骤:
|
|
apktool重新打包时,有一个坑。在AndroidManifest.xml文件里,如果android:extractNativeLibs="false"
,则需要修改为android:extractNativeLibs="true"
,否则按装时会报错。
按照上述修改后,本以为就可以了,可事实上,压根就没有解决https无法查看的问题。这就如同说TCP挥手必须要四次才行的那些背八股文的人一样,根本就没有经过实践,把不完整的知识当是真理。当然,因为这是修改别的软件,不知道自己编写的软件这么修改后,有没有效果。
经过一番瞎折腾和摸索,才找到网上基本没有说过的修改方式(重点):
既然你是android 7.0以下才可以用,那么我就把你运行目标修改为这个目标,是不是可以?修改点:
|
|
然后,然后,结果居然行了!!!
小小结
- 原来apk反编译重新打包如此简单(修改源码例外,特别是混淆之后的)
- android 7后http是抓包变得繁杂
- 网上的答案很多的复制黏贴,不一定正确,自己实践过的才是可靠的,然而并不是所有人实践过,万一他们一直认为他们没实践过的是真理……