Android安卓进阶之——一文带你了解抓包和反抓包
今天主要跟大家介绍一下Android的抓包和防止抓包
介绍两款抓包工具,Profiter和Charles。
工具环境:
Android Studio 4.2.2
手机Google Pixel 3XL Android 11
使用Profiler 工具抓包
将自己的手机连接到电脑上,然后打开Android Studio 的Profiler
Android Studio 白狐及以下版本的NetWork Inspector 在 Profler 中,大黄蜂版本的NetWork Inspector 在 App Inspection中。
然后app 访问网络会有这样提示:
我们选中波动 ,可以看到请求的信息:
然后我们点击接口信息之后,可以看到请求的详细信息:
这样我们就可以通过AndroidStudio的Profiler 轻松地抓取我们App 的网络信息了。
使用Charles 工具抓包
1.安装证书
首先下载Charles ,打开之后点击Help->SSL Proxying -> Install Charles Root Certificate 安装根证书
然后双击证书,进行信任
电脑端这就配置完了, 接下来配置 客户端
方式1:
手机端通过浏览器下载证书。
手机端 对连接wifi 进行代理设置,设置手动代理,将charles 提示的代理地址 设置好,然后charles 就会有一个提示:
然后我们同意就好了。
然后浏览器输入chls.pro/ssl 进行下载证书,下载完成进行安装即可;不过有时候这种方式无法安装,可以通过方式2进行安装。
方式2:
通过Help->SSL Proxying -> Save Charles Root Certificate 将证书保存在电脑上
然后上传到手机端,点击设置-安全-加密与凭证-安装证书-CA证书,选择我们刚刚的证书进行安装即可。
至此,安装证书的步骤我们就完成了。
2.抓包
此时,当我们进行网络访问 的时候,可以在charles上面看到我们访问的数据了
我们可以通过左下角的Filter 进行地址过滤,找到我们想看的网络数据。
防止抓包
前面讲到,默认的 Android Https 配置下,只要使用 Android7.0 以下的手机、或者找个 Root 设备安装把用户证书(比如charles证书)想办法搞进系统证书那部分,就可以抓包了。这对于黑产来说也忒忒忒简单了。那么怎么防止呢?
答案是配置你信任的网站证书或者配置信任的认证链。
1.Android 官方配置信息证书
(声明:这种方法只能防篡改设备的根证书,防不了使用 Android7.0 以下的手机。)
比如你可以像这样把你信任的网站的证书给搞下来
步骤①:点击域名旁边锁的图标,弹出框里面点「证书」
mac系统,对着证书那个图标拖动到某个文件夹里。这样你就能得到一个HTTPS的里面的SSL里面的非对称加密算法的公钥。
步骤②:放进 res/raw 文件夹里,在network_security_config.xml 里写上相关配置
<?xml version="1.0" encoding="utf-8"?>
<network-security-config><!-- 这个是全局的基础的配置 --><base-config><trust-anchors><!-- 如果整个base-config都不写,就等于是<certificates src="system" /> --><!-- 这里写全局基础配置,只信任下面某几个证书 --><certificates src="@raw/zhihu" /><certificates src="@raw/baidu" /></trust-anchors></base-config><!-- 如果只对某些涉及数据安全的私密域名进行保护,可以针对某个域名,只信任某几个证书 --><domain-config><domain includeSubdomains="true">zhihu.com</domain><trust-anchors><certificates src="@raw/zhihu" /><certificates src="@raw/tencent" /></trust-anchors></domain-config><debug-overrides><trust-anchors><certificates src="user" /></trust-anchors></debug-overrides></network-security-config>
以上就是 Android 官方推荐的做法。
——————————————— 分割线 ———————————————
2. OkHttp 配置信任认证链
(声明:这种方法是全方面防御,在 Android7.0 以下设备也能起作用)
步骤①:写一个 CertificatePinner 的配置
其中的 add方法两个参数。第一个参数是网址的域名host,第二个是sha256的证书。证书我们目前不清楚,先输入这么一段字符串。使用这么一段错误的配置运行后将会报错,然后在日志里得到正确的配置信息。
注意第一个参数不要包含协议,也不要省略部分域名,错误示例 「https://news-at.zhihu.com」、「zhihu.com」。
第二个参数是个假证书识别串,但是有效的,我测试时候乱输入了一串「sha256/wrong」没有触发到搜想要的结果。
public class ZhihuHttp {public static final String ZHIHU_BASE_URL = "https://news-at.zhihu.com/api/";private static final ZhihuHttp zhihuHttp = new ZhihuHttp();private OkHttpClient okHttpClient;private ZhihuHttp() {OkHttpClient.Builder builder = new OkHttpClient.Builder();builder.connectTimeout(10, TimeUnit.SECONDS);// 只信任网站对应的证书CertificatePinner certificatePinner = new CertificatePinner.Builder().add("news-at.zhihu.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=").build();builder.certificatePinner(certificatePinner);okHttpClient = builder.build();}public static ZhihuHttp getZhihuHttp() {return zhihuHttp;}public void getDailiesWithCallback() {Request request = new Request.Builder().url(ZHIHU_BASE_URL + "4/news/latest").build();okHttpClient.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {Log.e("YAO", "ZhihuHttp.java - onFailure() ----- e:" + e.toString());e.printStackTrace();}@Overridepublic void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {Log.e("YAO", "ZhihuHttp.java - onResponse() ----- :" + response.toString());}});}
}
步骤②:执行代码后报错。搜索关键字,我们能得到这么一串报错
Subscriber onError() : javax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!Peer certificate chain:sha256/f5fNYvDJUKFsO51UowKkyKAlWXZXpaGK6Bah4yX9zmI=: CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CNsha256/zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=: CN=GeoTrust RSA CA 2018,OU=www.digicert.com,O=DigiCert Inc,C=USsha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=USPinned certificates for news-at.zhihu.com:sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
这报错的意思是。现在访问这个链接的认证链是 Peer certificate chain 下面的3个sha256。
「sha256/f5fNYvDJUKFsO51UowKkyKAlWXZXpaGK6Bah4yX9zmI=」
「sha256/zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=」
「sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=」
链的含义是,第一个sha256对应的证书由第二个sha256对应的证书认证,第二个sha256对应的证书又第三个sha256对应的证书认证。
在代码里配置的用于「news-at.zhihu.com」域名的认证 sha256 期望是
「sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=」
因为两者对应不上,所以请求失败。然而通过这个方法,我们得到正确的sha256,下面就拿这几个正确的sha256来配置。
步骤③:配置正确 sha256
CertificatePinner certificatePinner = new CertificatePinner.Builder()//正常请求下的证书验证链路.add("news-at.zhihu.com", "sha256/f5fNYvDJUKFsO51UowKkyKAlWXZXpaGK6Bah4yX9zmI=")//CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CN.add("news-at.zhihu.com", "sha256/zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=")//CN=GeoTrust RSA CA 2018,OU=www.digicert.com,O=DigiCert Inc,C=US.add("news-at.zhihu.com", "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=")//CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US.build();
配置后,这个域名的请求就不能被抓包了。因为开启抓包后,根证书是 charles 的公钥,跟期望的 sha256 匹配不上。
一个很重要的点是,其实我们可以不用把3个 sha256 都加上。匹配逻辑是任意一个 sha256 匹配上请求就可以通过了。所以其实可以这么写。
CertificatePinner certificatePinner = new CertificatePinner.Builder()//正常请求下的证书验证链路.add("news-at.zhihu.com", "sha256/f5fNYvDJUKFsO51UowKkyKAlWXZXpaGK6Bah4yX9zmI=")//CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CN.build();
域名hostname 支持通配符,可以参考OkHttp CertificatePinner部分
验证结果
按照 OkHttp 官方指导配置完后,使用 charles 抓包看看还能不能在 Android 7.0 以下系统抓到包。
验证结果,不能抓包,会出现一个报错:
Subscriber onError() : javax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!Peer certificate chain:sha256/dVUJFtUhQtJki5t0/j+hMYzTgtVkETqjsogUuyquPPo=: CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CNsha256/54ZQa+M6vq6DhdR7DLkc1X6fWmVEZ6wLZaaYwoR4Uvw=: C=NZ,ST=Auckland,L=Auckland,O=XK72 Ltd,OU=https://charlesproxy.com/ssl,CN=Charles Proxy CA (2 十月 2017\, YaodeMacBook-Pro.local)Pinned certificates for news-at.zhihu.com:sha256/f5fNYvDJUKFsO51UowKkyKAlWXZXpaGK6Bah4yX9zmI=sha256/zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=
可以看到现在访问这个链接的认证链是 Peer certificate chain 下面的两个sha256。
「sha256/dVUJFtUhQtJki5t0/j+hMYzTgtVkETqjsogUuyquPPo=」
「sha256/54ZQa+M6vq6DhdR7DLkc1X6fWmVEZ6wLZaaYwoR4Uvw=」
报错的信息里,第二个 sha256 冒号后面,显示这串字符来自我的 charles 公钥。
对比 未使用 和 使用 抓包的报错信息,发现第一个 sha256 都是来自于知乎的公钥,但两个的 sha256 是不一样的。
//未开启抓包
sha256/f5fNYvDJUKFsO51UowKkyKAlWXZXpaGK6Bah4yX9zmI=: CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CN
//开启抓包
sha256/dVUJFtUhQtJki5t0/j+hMYzTgtVkETqjsogUuyquPPo=: CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CN
一开始我一直以为这一串东西是SSL公钥进行一次hash算法得到的字符串。后面观察后发现不是。
这是两个公钥在不同 「中间证书认证」-「中间证书认证」……「根证书认证」这种认证体系下的一个hash串。
所以如果开启抓包,那么他对应的根证书是 charles 的公钥,得出的第一个来自知乎证书的 sha256 就会有所不同。
warning: 配置信任某个具体证书一定要与服务器开发或运维沟通好,因为如果服务器进行了证书替换而App没有更新到最新证书,App的请求将会失效。如果开启的是全部域名的证书配置,意味着你连应用内升级或者热更新都用不了,绝对是重大事故。
还有什么骚操作
上面讲到我们配置到工程代码里的是 网站的公钥(任何人都可以随意下载)
根据HTTPS的原理,公钥和私钥的原理,其实完全可以在代码里配置上开发者的 charles 公钥(只针对某台具体的笔记本,charles 为它生成的一对公钥私钥)。因为没人能根据公钥能破解出对应的私钥。
所以如果在在 app 里配上我们某部电脑 charles 公钥,以后就可以用那个电脑抓正式环境正式域名的请求了。比如工程加上公司的公用开发机的 charles 公钥,或者核心App测试大佬的 charles 公钥。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config><!-- 这个是全局的基础的配置 --><base-config cleartextTrafficPermitted="true"><trust-anchors><!-- 如果整个base-config都不写,就等于是<certificates src="system" /> --><!-- 这里写全局基础配置,只信任下面某几个证书 --><certificates src="@raw/zhihu" /><certificates src="@raw/yao_charles" /></trust-anchors></base-config><debug-overrides><trust-anchors><certificates src="user" /></trust-anchors></debug-overrides></network-security-config>
使用OkHttp的配置的方法,这么写:
// 只信任网站对应的证书
CertificatePinner certificatePinner = new CertificatePinner.Builder()//正常请求下的证书验证链路.add("news-at.zhihu.com", "sha256/f5fNYvDJUKFsO51UowKkyKAlWXZXpaGK6Bah4yX9zmI=")//CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CN.add("news-at.zhihu.com", "sha256/zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=")//CN=GeoTrust RSA CA 2018,OU=www.digicert.com,O=DigiCert Inc,C=US.add("news-at.zhihu.com", "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=")//CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US//charles 抓包下的配置.add("news-at.zhihu.com", "sha256/dVUJFtUhQtJki5t0/j+hMYzTgtVkETqjsogUuyquPPo=")//CN=*.zhihu.com,OU=IT,O=智者四海(北京)技术有限公司,L=北京市,C=CN.add("news-at.zhihu.com", "sha256/54ZQa+M6vq6DhdR7DLkc1X6fWmVEZ6wLZaaYwoR4Uvw=")//C=NZ,ST=Auckland,L=Auckland,O=XK72 Ltd,OU=https://charlesproxy.com/ssl,CN=Charles Proxy CA (2 十月 2017\, YaodeMacBook-Pro.local).build();
Android安卓进阶之——一文带你了解抓包和反抓包相关推荐
- Android安卓进阶技巧之全局自定义字体的实现
前言 由于网上大部分教程在新版本系统中已经失效,特此记录. 一.修改TextView字体 假设现在有一个字体文件msyh.ttf:对于某个TextView来说,如果想修改它的字体,可以简单的使用如下代 ...
- Android安卓进阶之——相比 Groovy 脚本, KTS 性能到底怎么样?
前言 大家肯定也都或多或少的写过一些Groovy代码,但由于不支持代码提示及编译时检查,使用Groovy开发的体验并不太好,Android Gradle插件4.0之后支持在Gradle构建配置中使用K ...
- android phone驱动_一文带你掌握 Android 系统架构
引言 本文作为Android系统架构的开篇,起到提纲挈领的作用,从系统整体架构角度概要讲解Android系统的核心技术点,带领大家初探Android系统全貌以及内部运作机制.虽然Android系统非常 ...
- DDD进阶_一文带你搞定什么是前台、中台、后台
DDD从入门到精通,系列文章传送地址,请点击本链接. 目录 一.中台和平台的关系 二.什么是中台? 三.数字化转型中台应该共享什么? 四.如何实现前中后台的协同? 1. 前台 2. 中台 3. 后台 ...
- 一文带你了解基于视觉的机器人抓取自学习(Robot Learning)
"一眼就能学会动作",或许对人而言,这样的要求有点过高,然而,在机器人的身上,这个想法正在逐步实现中.马斯克(Elon Musk)创立的人工智能公司Open AI研究通过One-S ...
- 关于Android 抓包 与 反抓包
恭喜自己,文章投稿洋神公众号刊登成功.
- 安卓进阶之android系统架构
安卓进阶之android架构 安卓进阶躲不开阅读源码和深入了解安卓的底层,这是一篇入门级别的文章,可以对安卓架构有个大体的认识. AOSP与Android系统架构 首先要理解andriod和AOSP的 ...
- android 主要哪些版本,你用过的最早的安卓版本是哪个?带你见识最早的安卓系统!...
原标题:你用过的最早的安卓版本是哪个?带你见识最早的安卓系统! 随着Android版本更新的迭代,许多人现在使用Android 7.1版甚至8.0版.但你还记得你接触过多少最早的安卓版本吗?对于许多经 ...
- Android中高级进阶知识(最新动脑学院安卓进阶视频 )
Android中高级进阶知识点整理 转载 https://blog.csdn.net/lou_liang/article/details/8285653 那么接下来的文章就是高级进阶,其中或者引用或者 ...
最新文章
- golang的临时对象池sync.Pool
- 1142 CREATE VIEW command denied to user 'blog'@'XXX.XXX.XXX.XXX' for table 'Articles'
- python在哪里写代码比较适合-AI辅助写代码,Python之父都爱不释手的工具
- PCB电路设计10大基本原则
- bootstrap3 徽章_【可预留】不倒翁工作室,数码宝贝 勇气徽章
- react构建_您应该了解的有关React的一切:开始构建所需的基础知识
- 机器学习算法中文视频教程
- 基于c语言实现bp算法,基于BP网络的自学习算法和C语言实现
- c#连接mysql数据库,增删查改命令执行
- 放苹果(整数划分变形题 水)poj1664
- VC知识库五周年精华珍藏版(2CD)
- mmsegmentation自定义数据集
- 假定一种编码的编码范围是a~y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a,aa,aaa,aaaa,aaab,aaac,…,…,b,ba,baa,baaa,b
- 【知识学习】最大公因数gcd
- Pandas Dataframe 新增加一行
- 0x77A26B83 (ntdll.dll) 处有未经处理的异常: 0xC0000374: 堆已损坏。
- 在国内外市场均遭遇挫折的OPPO和vivo该反思了
- 一键安装与配置gitlab(脚本)
- bzoj2548[Cstc2002]灭鼠行动
- 机器人战争显示服务器连接,战争机器人总是显示无法连接网络
热门文章
- notepad++正则表达式表示汉字
- 2023 在线扒站系统PHP源码
- 深度学习——day42 基于时空Transformer的社交网络信息传播预测模型
- 如何选择合适的连锁管理软件?
- |Vijos|动态规划|P1264 神秘的咒语
- Navicat Premium12 安装报错、解决办法
- 用Excel对字符串进行拆分,拼接,翻译
- 大一计算机word作业朱自清,背影__朱自清-word(精).doc
- java康纳塔碳纤维硬吗,碳纤维车身是最硬的吗 最奢侈的汽车材料就是它
- C/C++ 实现切片免杀的思路