Android 手机抓包

一、防抓包机制

正所谓”知己知彼,百战不殆“,只有仔细钻研敌人的防御手段,我们才可以有针对性的突破他们的防御措施,获取到我们所需要的通信数据。因此我们首先需要做的就是研究敌人的防范手段。

市面上的各种应用层抓包软件的实现原理基本都是中间人攻击(MITM),包括大家常用的Burpsuite、Fiddler、Charles等知名抓包工具(Wireshark 类型的软件使用的网卡数据复制,只要是经过指定网卡都会被抓取)。那么一般为了防止MITM,他们通常会采取下面几种防范措施

1.1 HTTPS单向验证

众所周知,HTTPS = HTTP + SSL/TLS,其中SSL/TLS协议作用于HTTPS建立前客户端与服务端建立信任的过程,HTTP协议作用于客户端与服务端的正式通信过程,但二者通信的数据是被TLS协议最终生成的密钥加密过的,具体流程如图所示。

image-20210910222927466

1.2 HTTPS双向认证

双向验证相比较单向验证,只是增加了服务端对客户端的认证,具体流程如图所示

image-20210910223050035

1.3 SSL pinning

SSL Pinning是一种专门防止中间人攻击的技术,主要机制是在客户端发起请求–>收到服务器发来的证书进行校验,如果收到的证书不被客户端信任,就直接断开连接不继续求情。可以发现中间人攻击的要点的伪造了一个假的服务端证书给了客户端,客户端误以为真。解决思路就是,客户端也预置一份服务端的证书,比较一下就知道真假了。
SSL-pinning有两种方式:

1.3.1 证书锁定(Certificate Pinning)

需要在客户端代码内置仅接受指定域名的证书,而不接受操作系统或浏览器内置的CA根证书对应的任何证书,通过这种授权方式,保障了APP与服务端通信的唯一性和安全性,因此客户端与服务端(例如API网关)之间的通信是可以保证绝对安全。但是CA签发证书都存在有效期问题,缺点是在
证书续期后需要将证书重新内置到APP中。

1.3.2 公钥锁定( Public Key Pinning)

提取证书中的公钥并内置到客户端中,通过与服务器对比公钥值来验证连接的正确性。制作证书密钥时,公钥在证书的续期前后都可以保持不变(即密钥对不变),所以可以避免证书有效期问题,一般推荐这种做法

1.3.3 双向验证与SSL pinning的区别

SSL pinning实际上是客户端锁定服务器端的证书, 在要与服务器进行交互的时候, 服务器端会将CA证书发送给客户端, 客户端会调用函数对服务器端的证书进行校验, 与本地的服务器端证书(存放在.\asset目录或\res\raw下)进行比对。

双向认证是添加了客户端向服务器发送CA证书, 服务器端对客户端的证书进行校验的部分。在app上,https双向认证的方案也可以防止中间人劫持,但这种双向认证开销较大,且安全性与SSL pinning一致,目前大多数app都采用SSL Pinning这种方案。

1.4 代理检测

首先我们需要了解HTTP代理是如何运作的,我们启动Fiddler 或 Burp就是启动了一个HTTP代理服务器,这类工具会通知操作系统,“现在我在系统上创建了一个HTTP代理,IP为XXXXXX端口为XX。如果您使用的是linux您可以手动通知操作系统(export http_proxy=ip:port export https_proxy=$http_proxy),如果您使用的是手机等移动设备您可以在当前wifi设置处告诉系统你要使用http代理。 现在我们已经告诉系统我们想要使用代理,这个时候运行在系统上的http客户端再去发送请求的时候,他就不会再去进行DNS解析,去连接目标服务器,而是直接连接系统告诉他代理所在的地址(代理的ip及端口,注意无论是http或https或其他支持代理的协议都会连接同一个端口)。然后代理服务器会与客户端建立连接,再然后代理服务器根据请求信息再去连接真正的服务器。

image-20210911143740345

然而不同的客户端虽然可能存在代理功能,但是并不一定在默认情况下会直接使用系统代理。在现实中这种况下这种情况还不少,也正是因为HTTP客户端没有使用我们设置的系统代理,他们自然也不会连接Fiddler 或 Burp创建的代理服务器,最终导致我们无法获取任何请求。

1.5 对抗HOOK

Hook 是钩子的意思,在 Android 操作系统中,系统维护着自己的一套事件分发机制。应用程序,包括应用触发事件和后台逻辑处理,也是根据事件流程一步步地向下执行。

而钩子的意思,就是在事件传送到终点前截获监控事件的传输,像个钩子钩上事件一样,并且能够在钩上事件时,处理一些自己特定的事件。较为形象的流程如下图所示。

image-20210911162401636

在 Android 系统中使用了沙箱机制,普通用户程序的进程空间都是独立的,程序的运行彼此间都不受干扰。根据 Hook 对象与 Hook 后处理的事件方式不同, Hook 还分为不同的种类,如消息 Hook 、API Hook 等。

在做Android App的安全防御中检测点众多,Xposed Installer检测是必不可少的一环,各个厂商通过不同的方式去检测xposed框架。对于Xposed框架的防御总体上分为两层:Java层和Native层。

Java层的检测点主要有:

  • 通过PackageManager查看安装列表
  • 自造异常读取栈
  • 检查关键Java方法被变为Native JNI方法
  • 反射读取XposedHelper类字段

Native层检测:

由上文可知,无论在Java层做何种检测,Xposed都可以通过Hook相关的API并返回指定的结果来绕过检测,只要有方法就可以被Hook。如果仅在Java层检测就显得很徒劳,为了有效提搞检测准确率,就须做到Java和Native层同时检测。每个App在系统中都有对应的加载库列表,这些加载库列表在/proc/下对应的pid/maps文件中描述,在Native层读取/proc/self/maps文件不失为检测Xposed Installer的有效办法之一。

二、中间人攻击

中间人攻击就是在客户端和服务端进行通信时,劫持并转发流量,同时对客户端伪装成服务端,对服务端伪装成客户端。根据上面HTTPS的会话过程可知,中间人攻击的关键是截获服务器返回的证书并伪造证书发送给客户端骗取信任,获取通信双方协商出来的会话密钥,进而达成盗取信息的目的。

具体流程如图所示:

image-20210910214210120

2.1 安装CA证书

MITM Server要成为真正的Server,必须能够给指定域名签发公钥证书,且公钥证书能够通过系统的安全校验。比如Client发送了一条https://www.baidu.com/的网络请求,MITM Server要伪装成百度的Server,必须持有www.baidu.com域名的公钥证书并发给Client,同时还要有与公钥相匹配的私钥。

MITM Server的处理方式是从第一个SSL/TLS握手包Client Hello中提取出域名www.baidu.com,利用应用内置的CA证书创建www.baidu.com域名的公钥证书和私钥。创建的公钥证书在SSL/TLS握手的过程中发给Client,Client收到公钥证书后会由系统会对此证书进行校验,判断是否是百度公司持有的证书,但很明显这个证书是抓包工具伪造的。为了能够让系统校验公钥证书时认为证书是真实有效的,我们需要将抓包应用内置的CA证书手动安装到系统中,作为真正的证书发行商(CA),即洗白。这就是为什么,HTTPS抓包一定要先安装CA证书。

2.2 Firefox证书安装

火狐浏览器Firefox自行搞了一套CA证书管理,无论是系统CA证书还是用户CA证书,Firefox通通都不认可。这种情况,我们需要将CA证书通过特殊方式导入到Firefox中,否则Firefox浏览网页就无法工作了。

下载相应抓包工具的证书并在火狐的隐私与安全模块中安装CA证书。

三、抓包手段

“只要思想不滑坡,办法总比困难多”,敌人的手段有很多但是我们也有相应的应对手段

3.1 Android 7.0的用户CA证书限制

Android从7.0开始系统不再信任用户CA证书(应用targetSdkVersion >= 24时生效,如果targetSdkVersion < 24即使系统是7.0+依然会信任)。也就是说即使安装了用户CA证书,在Android 7.0+的机器上,targetSdkVersion >= 24的应用的HTTPS包就抓不到了。

那么,我们如果绕过这种限制呢?已知有以下四种方式(低于7.0的系统请忽略)

3.1.1 AndroidManifest中配置networkSecurityConfig

如果我们想抓自己的App,只需要在AndroidManifest中配置networkSecurityConfig即可:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

这样即表示,App信任用户CA证书,让系统对用户CA证书的校验给予通过。

3.1.2 平行空间抓包

如果我们希望抓targetSdkVersion >= 24的应用的包,那又该怎么办呢?我们可以使用平行空间或者VirtualApp来曲线救国。平行空间和VirtualApp这种多开应用可以作为宿主系统来运行其它应用,如果平行空间和VirtualApp的targetSdkVersion < 24,那么问题也就解决了。
在此,我推荐使用平行空间,相比部分开源的VirtualApp,平行空间运行得更加稳定。但必须注意平行空间的版本4.0.8625以下才是targetSdkVersion < 24,别安装错了。

3.1.3 调低targetSdkVersion < 24

如果想抓一个App的包,可以找个历史版本,只需要其targetSdkVersion < 24即可。然而,随着GooglePlay开始限制targetSdkVersion,现在要求其必须>=26,2019年8月1日后必须>=28,国内应用市场也开始逐步响应这种限制。绝大多数App的targetSdkVersion都将大于24了,也就意味着抓HTTPS的包越来越难操作了。

3.1.4 安装到系统CA证书目录

首先从Burp中导出DER格式的证书。

image-20210907144249535

然后处理burp证书(kali有openssl服务)。

openssl x509 -inform DER -in cacert.der -out cacert.pem
openssl x509 -inform PEM -subject_hash_old -in cacert.pem|head -1

image-20210907144551475

然后将文件cacert.pem重命名为9a5ba575.0

最后将证书复制到/system/etc/security/cacerts 目录下。

3.2 公钥证书固定

证书固定(Certificate Pinning)是指Client端内置Server端真正的公钥证书。在HTTPS请求时,Server端发给客户端的公钥证书必须与Client端内置的公钥证书一致,请求才会成功。

在这种情况下,由于MITM Server创建的公钥证书和Client端内置的公钥证书不一致,MITM Server就无法伪装成真正的Server了。这时抓包就表现为App网络错误。已知的知名应用,比如饿了么,就采用了证书固定。另外,有些服务器采用的自签证书(证书不是由真正CA发行商签发的),这种情况App请求时必须使用证书固定。
证书固定的一般做法是,将公钥证书(.crt或者.cer等格式)内置到App中,然后创建TrustManager时将公钥证书加进去。很多应用还会将内置的公钥证书伪装起来或者加密,防止逆向提取。

3.2.1 JustTrustMe破解证书固定

Xposed和Magisk都有相应的模块,用来破解证书固定,实现正常抓包。

例如:JustTrustMeJustTrustMePlush

破解的原理大致是,Hook创建SSLContext等涉及TrustManager相关的方法,将固定的证书移除。

感兴趣的可以参考一下这篇文章https://bbs.pediy.com/thread-267355.htm

3.2.2 基于VirtualApp的Hook机制破解证书固定

Xposed和Magisk需要刷机等特殊处理,但是如果不想刷机折腾,我们还可以在VirtualApp中加入Hook代码,然后利用VirtualApp打开目标应用进行抓包。

参考链接:

3.2.3 导入真正的公钥证书和私钥

如果Client固定了公钥证书,那么MITM Server必须持有真正的公钥证书和匹配的私钥。如果开发者具有真正服务端的公钥证书和私钥,(比如百度的公钥证书和私钥百度的后端开发肯定有),如果真有的话,可以将其导入到代理软件之中,也可以完成正常抓包。

以HttpCanary为例,在设置 -> SSL证书设置 -> 管理SSL导入证书 中,切换到服务端,然后导入公钥证书+私钥,支持.p12和.bks格式文件。

3.3 双向认证

SSL/TLS协议提供了双向认证的功能,即除了Client需要校验Server的真实性,Server也需要校验Client的真实性。这种情况,一般比较少,但是还是有部分应用是开启了双向认证的。比如匿名社交应用Soul部分接口就使用了双向认证。使用了双向认证的HTTPS请求,同样无法直接抓包。

关于双向认证的原理,前文已经讲解过了,双向认证抓包的主要问题是client的证书问题,用于双向认证的公钥证书和私钥代表了Client端身份,所以其是隐秘的,一般都是用.p12或者.bks文件+密钥进行存放。由于是内置在Client中,存储的密钥一般也是写死在Client代码中,有些App为了防反编译会将密钥写到so库中,比如S匿名社交App,但是只要存在于Client端中都是有办法提取出来的。

3.3.1 双向认证抓包

这里以某匿名社交App为例,讲解下如何抓取使用了双向认证的App的HTTPS包。

如果服务器使用了Nginx且开启了双向认证,抓包时可能会出现400 Bad Request的错误,而有些服务器可能不会返回404,直接请求失败。

双向认证需要我们将证书提取出来,首先需要解压APK,提取出.p12或者.bks文件,二进制的文件一般都存放在raw或者assets目录。将client.p12文件导入手机,然后在在代理软件导入证书。

由于双向认证的公钥证书和私钥是受密钥保护的,所以需要输入密码:

一般通过逆向可以从APK中提取出密钥,感兴趣的可以参考这篇文章https://www.cnblogs.com/jiangjunyong/p/13272164.html

3.4 SSL重协商

有些服务器可能会开启SSL重协商,即SSL/TLS握手成功后发送请求时服务器会要求重新握手。这种情况一般比较少,但是也不排除,已知的应用比如 10000社区 就使用了SSL重协商。

由于Android系统对SSL重协商是有限支持,所以部分系统版本抓包会失败,表现为网络异常。在Android 8.1以下,SslSocket是完全支持SSL重协商的,但是SSLEngine却是不支持SSL重协商的,而HttpCanary解析SSL/TLS使用的是SSLEngine。在Android 8.1及以上,SSLEngine和SslSocket统一了实现,故是支持SSL重协商的。

所以,如果确认服务器使用了SSL重协商,请使用8.1及以上版本系统进行抓包。

3.5 代理检测

根据前文的内容,我们已经了解了代理检测的运行机制,那么就有下面几种解决的办法

3.5.1 控制DNS解析

可以通过DNS解析欺骗客户端,让它认为我们的代理服务端就是真正的服务端,这一点可以通过修改hosts文件来实现。他的优缺点十分明显

  • 它的优点是操作方便,通过修改设备的hosts可以十分方便

  • 缺点是需要为每个需要操作的域名提前添加host,同时在手机等手持设备上难以修改hosts(即对移动APP这类应用很难实现)

3.5.2 流量转发

在网络设备上直接做流量转发,将指定终端设备上发往80及443端口的数据直接转发到代理服务器的 目标端口上。

  • 优势:可以针对连接到网络设备上的终端设备进行分别配置,而手机等终端设备不需要进行任何设备
  • 劣势:需要单独的硬件设备

3.5.3 使用vpn软件(推荐)

客户端禁止你使用代理,但是基本不会禁止你使用VPN,因此可以使用vpn客户短绕过代理检测。这类软件的原理是和第二种方法类似,不过是通过软件实现的,它可以将应用层请求进行强制性的转发,具体做法有如下几种:

  • ios可以直接使用小飞机(Shadowrocket),ios的小飞机支持多种协议协议类型
  • Android可以利用postern/SocksDroid/Httpcanary/drony等等全局代理软件,具体操作可以参考这个链接https://www.freebuf.com/articles/mobile/267647.html

3.5.4 利用hook的方式

还有的检测手段就是检测代理状态,如果设置代理了就拒绝通信,也可以利用hook的方式将检测代理状态的代码Bypass掉。

3.6 非HTTP协议抓包

如果确认了以上几点,如果仍然抓包失败,那么极有可能使用的并非是HTTP协议。比如像微信聊天,视频直播等,使用的就不是HTTP协议,这种情况需要使用其它的抓包工具,比如Packet Capture这种直接解析TCP/UDP协议的,但是往往非HTTP协议的数据包即使抓到了也无法解析出来,因为大概率都是二进制而非文本格式的。

四、参考链接

SSL技术原理详解

Android HOOK技术防范漫谈

Hook技术分析

Hook样例

Android系统https抓包问题分析

最全APP抓包方法

SSL-Pinning的总结

系统证书写入

Android平台抓包以及解决方案

Android逆向之逆向工具

socks5代理软件抓包

flutter抓包

posted @ 2021-09-18 23:27  tomyyyyy  阅读(1089)  评论(0编辑  收藏  举报