移动安卓App+BurpSuite的渗透测试

从Android 7.0及以上版本开始,安卓系统更改了信任用户安装证书的默认行为,默认不信任用户证书,用户安装的证书都是用户证书,因此不管是filddle还是burp,都是把他们的根证书安装到了用户证书
还有移动app默认只信任系统预装的CA证书(开发人员可通过定义配置文件的方式,定义哪些证书可以信任),不会信任用户安装的CA证书,因此导致我们手动生成的burpsuite证书导入手机后,已经不能拦截App的请求,同时,通过Burp代理访问https网站,系统会提示"该证书并非来自可信的授权中心"。

移动App的渗透,一般推荐安卓7.0及以下为测试环境,但如今越老越多的APP已经不支持安卓5等旧版本了

所以,就以夜神模拟器为例,记录下自定义安卓系统级CA证书以方便抓取HTTPS的包,如使用安卓真机,可能在细节上略有差异

整体流程:

1.证书导出

将burp证书导出,把后缀改为.der

2.计算证书HASH

计算证书HASH,我这里使用Linux下的命令

​ 安卓系统CA证书名字都是hash .0 ,文件名是 hash ,后缀名是 0 ,即pem证书文件名组成为:hash值+.0,故先计算出证书 hash 最后重命名证书

ubuntu@VM-16-11-ubuntu:~/Public$ openssl x509 -inform DER -in burpca.der -out burpca.pem
ubuntu@VM-16-11-ubuntu:~/Public$ ls
burpca.der  burpca.pem
ubuntu@VM-16-11-ubuntu:~/Public$ openssl x509 -inform PEM -subject_hash_old -in burpca.pem
9a5ba575
-----BEGIN CERTIFICATE-----
MIIDyTCCArGgAwIBAgIEU6k7MzANBgkqhkiG9w0BAQsFADCBijEUMBIGA1UEBhML
UG9ydFN3aWdnZXIxFDASBgNVBAgTC1BvcnRTd2lnZ2VyMRQwEgYDVQQHEwtQb3J0
U3dpZ2dlcjEUMBIGA1UEChMLUG9ydFN3aWdnZXIxFzAVBgNVBAsTDlBvcnRTd2ln
Z2VyIENBMRcwFQYDVQQDEw5Qb3J0U3dpZ2dlciBDQTAeFw0xNDA2MjQwODQ3NDda
Fw00MTA2MjQwODQ3NDdaMIGKMRQwEgYDVQQGEwtQb3J0U3dpZ2dlcjEUMBIGA1UE
CBMLUG9ydFN3aWdnZXIxFDASBgNVBAcTC1BvcnRTd2lnZ2VyMRQwEgYDVQQKEwtQ
b3J0U3dpZ2dlcjEXMBUGA1UECxMOUG9ydFN3aWdnZXIgQ0ExFzAVBgNVBAMTDlBv
cnRTd2lnZ2VyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjSEb
Hg/kfMjoj7sh9vQsPpvI1/Bfypwdp8Xm8fTBZEXPwfI7nUZ4Gn8c0P/QFQwZ1xMn
g7Jct+D2C0x6zosMT1Kv0/UsRN7NRQm1R1pv9EMbR//JCGwQU2ORxV9dU1HU9x7m
L/f5hkQcMz680YoUKnfW/kDODnbIIQkUmBTFKSvti4SlPyKkIvaNSskf1ReAxVHi
txbNpl8QiL+xBrvq3Vg4nwh70NpXD40FSplYaxD3ffbVgxYCMzp0ZT+Ud3AaiOAA
9IB/9ZyhS36IlfBZXRcYNoLUBmfYEEE44eX3cFvmOYcewHHAJbqPa2Y79slWeKIp
K5XaWkuHvsPtogyfkwIDAQABozUwMzASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1Ud
DgQWBBS7nfTpuNhzlKzbtuJ8/QTDRkZ7JTANBgkqhkiG9w0BAQsFAAOCAQEAQj4T
PpNBluUkUIRBCr/ATxJGogGDukvolexLGiMU6CKBVbdLwsp0rIxZJojtfvYxSrK/
iz3S9XWKcZFJyY142GALhyClLYhWKw4zLjQVik5tw0r236JKox3oOWhze5QLHnO/
aAjePpYo360N5enuXwCWfDSeb5YLVGx2HH+HNNvfzTf6YVRzYKvQeGHfjUlb5+xU
0DM1nPlDckH5xR0NL0IIbyfzEHA43ZDiEwT9/OjWnXCarOe/IWzh1nu1jem4J9/0
yySuKkg/+xLr3d+n/6kUqplOz4AvyAaYt7ZOTMpTQQo+ykTB82YWdQYr8OXg+6b+
j1Hi/AZ/MAdZhILQ3g==
-----END CERTIFICATE-----

计算证书hash一定要用subject_hash_old,而不是subject_hash
因为subject_hash使用SHA-1算法,subject_hash_old使用OpenSSL 1.0.0之前老算法MD5计算
经过测试在Android 7 64bit上只能使用subject_hash_old系统才能正确识别出证书。

TIPS:
文件名是一个Hash值,而后缀是一个数字。后缀名的数字是为了防止文件名冲突的,比如如果两个证书算出的Hash值是一样的话,那么一个证书的后缀名数字可以设置成0,而另一个证书的后缀名数字可以设置成1

3.移动到系统根证书目录

将刚才生成的pem改名为xxxx.0

ubuntu@VM-16-11-ubuntu:~/Public$ mv burpca.pem 9a5ba575.0
ubuntu@VM-16-11-ubuntu:~/Public$ ls
9a5ba575.0  burpca.der

3.1安装系统CA证书

  • 系统证书路径:/system/etc/security/cacerts/

  • 用户证书路径:/data/misc/user/0/cacerts-added/

    通过模拟器自带的文件共享将自定义证书9a5ba575.0从移动到模拟器下的对应目录 /system/etc/security/cacerts/ 9a5ba575 .0

    注意:虽然到这里自定义证书已导入,但暂时无法被读取,因为系统证书都是644权限,所以还需将自定义证书权限也改为644,防止普通用户无权读取写入。 /system目录默认是只读,这里只需配合本地adb命令以读写权限重新挂载 /system ,一般该命令存放在模拟器安装目录/bin目录下

PS D:\Program Files\Nox\bin> .\adb.exe shell
beyond1q:/ # ls
acct        default.prop       init.qcom.rc          mnt                seapp_contexts    ueventd.qcom.rc
bugreports  dev                init.rc               oem                selinux_version   ueventd.rc
cache       etc                init.superuser.rc     proc               sepolicy          vendor
charger     file_contexts.bin  init.usb.configfs.rc  property_contexts  service_contexts
config      fstab.qcom         init.usb.rc           root               storage
d           init               init.zygote32.rc      sbin               sys
data        init.environ.rc    lib                   sdcard             system
beyond1q:/ # su
beyond1q:/ # whoami
root
beyond1q:/ # cd system/etc/security/cacerts/
beyond1q:/system/etc/security/cacerts # mount -o remount,rw /system 
//这里需要以读写权限重新挂载/system,否则权限为只读无法修改
beyond1q:/system/etc/security/cacerts # chmod 644 ./9a5ba575.0
beyond1q:/system/etc/security/cacerts # ll | grep 9a5ba575.0  
-rw-r--r-- 1 root root 1375 2021-11-7 22:38 9a5ba575.0

4.查看导入的自定义证书

以上步骤全部完成后,在手机的设置->安全->加密与凭据->信任的凭据 能看到新加入burp的证书已被安装到系统证书

5.重启-结束

最后手动重启设备,这时就可以愉快的抓到安卓7下APP的HTTPS数据包了

这里还有一点就是,模拟器打开手机浏览器,可能会提示“该网站的安全证书有问题”,解决办法:弹出安全警告的提示框中点击继续按钮,直到点击没有窗口为止,然后在浏览器右上角的设置里,找到隐私和安全下拉框下的“显示安全警告”选项,取消打勾后返回,这一步之后浏览任何https网站都不会跳出证书安全警告了。

总结

写在最后:以上方法只是最常规的解决办法,现下各种移动APP也出现越来越多对抗抓包的检测方法
如APP预埋固定证书:

证书固定(Certificate Pinning)是指Client端内置Server端真正的公钥证书。表现就是抓包时,无法连接网络并且也接收不到任何数据(代理日志里 TLS 握手失败)。这是因为在HTTPS请求时,Server端发给客户端的公钥证书必须与Client端内置的公钥证书一致,请求才会成功。

APP内置了仅接受指定域名的证书,不接受操作系统或者浏览器内置的CA根证书对应的任何证书,当服务器返回的证书和代码中的证书不一致就不进行通信,这使得App只能和服务器进行通信,这样就保障了APP与服务端通信的唯一性和安全性,这个时候就需要绕过,比如利用Xposed + JustTrustMe + SSLUnpinning

双向认证:

APP客户端和服务端都互相验证对方证书,具体为客户端先验服务端证书,通过后就会把本地的证书发给服务器去验证,成功后才开始正常通信。
关于双向认证的原理。
首先,双向认证需Server支持,Client必须内置一套公钥证书 + 私钥。在SSL/TLS握手过程中,Server端会向Client端请求证书,Client端必须将内置的公钥证书发给Server,Server验证公钥证书的真实性。

注意:这里的内置的公钥证书有区别于前面预埋证书(固定),双向认证内置的公钥证书+私钥是额外的一套,不同于证书固定内置的公钥证书。如果一个Client既使用证书固定,又使用双向认证,那么Client端应该内置一套公钥证书 + 一套公钥证书和私钥。第一套与Server端的公钥证书相同,用于Client端系统校验与Server发来的证书是否相同,即证书固定;第二套SSL/TLS握手时公钥证书发给Server端,Server端进行签名校验,即双向认证。

使用了双向认证的HTTPS请求,同样无法直接抓包,这种情况需要找证书安装在抓包软件,一般证书会在安装包下,如Assets、Res等目录下

代理检测:

当设置手机代理后,APP无法获取网络数据,出现无法连接网络的情况出现。但手机网络是正常的,但就是抓不到包。这时候可能就是这个原因了。

还有模拟器和Root权限检测等等,所以你会发现,当千难万险绕过证书问题后,还会继续有其他问题导致无法抓包🤣🤣🤣,
就此又会涉及到更多的方法来绕过和流量转发,这一部分后面遇到会补。

posted @ 2021-11-17 11:00  广陌道人  阅读(1735)  评论(0编辑  收藏  举报