本文主要介绍安卓应用通信安全的测试方法和步骤。文中用到的 vuls 漏洞应用及代码可以在 https://github.com/AndroidAppSec/vuls/releases/tag/v2.1 中下载。
二、安全测试
主要是测试应用是否存在中间人(MITM)攻击的风险。对于 https 来说,取决于是否做了正确的证书校验,一般来说主要包含两个方面:签发的CA是否为系统所信任、请求的域名信息是否为证书中所包含的域名。
1、校验接口
在做证书校验的时候,有两个接口很重要。
一个是 javax.net.ssl.X509TrustManager ,用来校验证书是否被信任。通常会校验 CA 是否为系统内置权威机构,证书有效期等。这个接口有三个方法,分别用来校验客户端证书、校验服务端证书、获取可信证书数组。
通常系统信任的证书会被安装在以下的目录中:
另一个是javax.net.ssl.HostnameVerifier ,其只有一个方法,用来校验域名信息。通常会比对当前请求的域名是否在证书的常用名称(CN)和主题备用名称(Subject Alternative Name)中。
2、错误实现
对于开发者来说,在测试环境中,通常会使用自签名的证书。正常情况下是无法进行 https 通信的,于是很多开发者就会在代码中忽略证书错误。但是在上生产环境的时候,又忘记去掉相关的代码,就会出现 https 通信被中间人攻击的情况。
以下是一段典型的忽略证书错误的写法,在 TrustManager 中不做任何校验,在HostnameVerifier 中总是返回域名正确。
此时的 https 通信与 http 通信效果无异,都会受到中间人攻击。
3、测试
这里使用 burp suite 来进行测试。保证手机和 burp 在同一个 wifi 中,设置手机的代理为 burp,如下:
1)、测试自签名证书
设置 burp 代理如下,
可以使用以下命令查看当前证书的信息:
openssl s_client -proxy 192.168.8.233:8080 -connect baidu.com:443 | openssl x509 -noout -subject -issuer
depth=1 C = PortSwigger, ST = PortSwigger, L = PortSwigger, O = PortSwigger, OU = PortSwigger CA, CN = PortSwigger CA
verify error:num=19:self signed certificate in certificate chain
subject=C = PortSwigger, O = PortSwigger, OU = PortSwigger CA,CN = baidu.com
issuer=C = PortSwigger, ST = PortSwigger, L = PortSwigger, O = PortSwigger, OU = PortSwigger CA, CN = PortSwigger CA
此时如果 burp 能够抓取到请求数据包,则说明应用信任自签名证书,会受到中间人攻击。
上图为使用 vuls (自己编写的漏洞测试 APP )中的相应测试功能。
2)、测试域名校验
安装 burp 的根证书到手机中。
首先,导出 burp 根证书。
保存为 burp.crt,并 push 到手机中。
adb push ~/Desktop/burp.crt /sdcard/
然后在手机中的安装 burp 根证书,操作路径为设置-》安全-》从 SD 卡安装。
安装成功后,可以在信任证书中看到 burp 根证书。
配置 burp 证书如下:
此时,应该能正常抓取到 https 请求了。
为了测试域名校验,我们在代码中添加以下校验代码:
虽然我们请求的是 https://www.baidu.com,但只有当域名为 www.google.com 的时候,才通过验证。
可以使用以下命令查看当前证书的信息:
openssl s_client -proxy 192.168.8.233:8080 -connect www.baidu.com:443 | openssl x509 -noout -subject -issuer
depth=1 C = PortSwigger, ST = PortSwigger, L = PortSwigger, O = PortSwigger, OU = PortSwigger CA, CN = PortSwigger CA
verify error:num=19:self signed certificate in certificate chain
subject=C = PortSwigger, O = PortSwigger, OU = PortSwigger CA,CN = www.baidu.com
issuer=C = PortSwigger, ST = PortSwigger, L = PortSwigger, O = PortSwigger, OU = PortSwigger CA, CN = PortSwigger CA
从上面可见,CN 为 www.baidu.com,与www.google.com不符,这样我们直接请求的时候就会失败。
为了通过验证,我们设置 burp 证书如下,
使用以下命令查看当前证书的信息:
openssl s_client -proxy 192.168.8.233:8080 -connect www.baidu.com:443 | openssl x509 -noout -subject -issuer
depth=1 C = PortSwigger, ST = PortSwigger, L = PortSwigger, O = PortSwigger, OU = PortSwigger CA, CN = PortSwigger CA
verify error:num=19:self signed certificate in certificate chain
subject=C = PortSwigger, O = PortSwigger, OU = PortSwigger CA,CN = www.google.com
issuer=C = PortSwigger, ST = PortSwigger, L = PortSwigger, O = PortSwigger, OU = PortSwigger CA, CN = PortSwigger CA
CN 已变为 www.google.com,同时也能正确抓取数据包了。
参考:
https://developer.android.com/training/articles/security-ssl
https://sushi2k.gitbooks.io/the-owasp-mobile-security-testing-guide/content/0x05g-Testing-Network-Communication.html
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html
欢迎关注微信公众号 “安卓APP安全测试”