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() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.e("YAO", "ZhihuHttp.java - onFailure() ----- e:" + e.toString());
                e.printStackTrace();
            }
            @Override
            public 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=CN
    sha256/zUIraRNo+4JoAYA7ROeWjARtIoN4rIEbCpfCRQT6N6A=: CN=GeoTrust RSA CA 2018,OU=www.digicert.com,O=DigiCert Inc,C=US
    sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
  Pinned 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 里面的「Wildcard pattern rules」部分

验证结果
按照 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=CN
    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)
  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();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容