关于android:Android安卓进阶之一文带你了解抓包和反抓包

50次阅读

共计 8051 个字符,预计需要花费 21 分钟才能阅读完成。

明天次要跟大家介绍一下 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 局部

验证后果
依照 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();

正文完
 0