抓包详解
介绍
抓包通常是指通过一些手段获取App与服务器之间传输的明文网络数据信息.
抓包分为以下两种情形:
- Hook抓包:通过对发包函数的Hook来达到抓包的作用.
- 中间人抓包:将原来一段完整的客户端-服务器的通信方式割裂成两段客户端-服务器的通信.
中间人的抓包在OSI七层网络模型的结构中通常又会被分成以下两种情形:
- 应用层:Http(s)协议抓包.
- 会话层:Socket通信抓包.
Http抓包配置
首先要将计算机和测试手机连接在同一个局域网中并且要确保手机和计算机能够相互访问.
WLAN代理
在手机设置代理时,可以选择"设置"应用中的WLAN设置,长按选择"修改网络"选项,并在弹出的对话框中选择手动代理,设置代理服务器地址为主机的地址以及端口,这里端口为8080.
上述这种配置代理的方式可被下述App代码检测,而导致最终抓不到数据包,因此推荐使用VPN代理方式.
|
|
相对于直接从应用层设置WLAN代理的方式,VPN代理则是通过虚拟出一个新的网卡,从网络层加上该层代理,不仅可以绕过上述App代码的检测,而且检测VPN代理的API相对较少,也比较容易绕过.
VPN代理
为了配置VPN代理,首先需要下载一个VPN软件,这里推荐Postern这个App.
- adb安装Postern,进入App主页面,然后单击App左上方将菜单调出.
- 进入"配置代理"页面后单击"代理1:proxy",配置服务器IP地址为主机IP、端口为8080,再选择代理类型为HTTPS/HTTP CONNECT,配置完毕后单击"保存"按钮并退出页面.
- 配置完代理后,重新单击App左上角,待弹出菜单后选择"配置规则",清空原来的所有规则并创建一个新的规则,分别设置"动作"选项为"通过代理连接" “代理/代理组"为刚才设置的代理(这里为192.168.1.5:8080),并设置"目标地址"为”*“或者直接清空以指定手机所有流量从代理经过.注意,“开启抓包"选项要关闭.
- 在上述代理和规则都设置完毕后,重新打开菜单项单击"关闭VPN"并开启VPN.这样测试机的配置就完成了.
BurpSuite
接下来使用BurpSuite来进行测试抓包.
- 打开BurpSuite,单击Proxy->Intercept,再单击Intercept is On按钮关闭拦截模式.
- 在关闭拦截模式后,单击Options按钮并把代理地址修改为本机IP地址和端口8080.设置好代理地址后,单击OK按钮完成抓包的全部配置.
- 手机和PC端抓包设置完毕后,在手机浏览器上访问任意Http网址,就可以在"HTTP history"页面中看到抓到的Http明文数据了.(这里手机访问的网址为:http://www.jwc.ldu.edu.cn/wlgxk.asp)
Charles
依次单击Proxy->Proxy Settings,在弹出的窗口中对端口进行配置.
如果不关掉,抓取HTTP数据包,就会出现上面的问题,明明是HTTP协议却被识别为HTTPS协议.
Https抓包配置
开启SSL Proxying
为了能够成功抓取HTTPS的数据,首先需要通过Ctrl+L快捷键开启Charles的SSL Proxying模式.
为了解决上述错误,我们需要设置下SSL Proxying.
将Charles证书加入到Android系统信任的证书列表中
在开启SSL Proxying模式后,用VPN代理模式使用手机浏览器访问任意HTTPS站点时,浏览器会显示提示信息"您的连接不是私密连接”,为了解决这个问题,我们需要将Charles证书加入到Android系统信任的证书列表中,具体步骤如下:
- Charles导出cer证书,保存在PC上.
- 修改证书名称.
|
|
- 复制证书到Android设备上.
|
|
- 复制到Android系统目录,并修改权限.
|
|
执行完上述命令,手机重启之后,Charles的证书就会放在系统证书中被系统信任.
如果运气不好,可能会出现下面的错误,原因是root的不彻底,权限不够,换一种方式root即可.
- 此时切换为VPN代理模式,用手机浏览器访问任意HTTPS站点,Charles就能够正常抓到数据了.
Socks5抓包配置
如果App不使用HTTP/HTTPS连接方式,那么主机的抓包软件就无法正常抓到数据包,为了绕过对协议的限制,我们选择将VPN代理中的"代理类型"设置为SOCKS5模式,为了区分于HTTPS/HTTP CONNECT代理类型要将服务器端口修改为8888,从而从应用层的下层对所有网络连接进行抓取.
与此同时要在Charles上进行配置.
由于使用的是SOCKS代理模式,因此哪怕App使用Socket进行网络连接,Charles也可以正常抓取.
OSI七层模型
OSI七层网络模型 | TCP/IP五层概念模型 | 对应网络协议 |
---|---|---|
应用层(Application) | HTTP、HTTPS、WS、FTP、DNS、SMTP、TFTP、SNMP、POP3、DHCP | |
表示层(Presentation) | 应用层 | TELNET、RLOGIN、SNMP、GOPHER |
会话层(Session) | SMTP、DNS | |
传输层(Transport) | 传输层 | TCP、UDP |
网络层(Network) | 网络层 | IP(TPV4、IPV6)、ICMP、IGMP、ARP |
数据链路层(Data Link) | 数据链路层 | FDDI、ETHERNET、APPANET、PDN、SLIP、PPP |
物理层(Physical) | 物理层 | IEEE 802.1A、IEEE 802.2到IEEE 802.11 |
Http协议
HTTP(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,基于TCP的连接方式.
URL:
URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息.格式如下:
|
|
-
http: 表示要通过HTTP协议来定位网络资源.
-
host: 表示合法的Internet主机域名或者IP地址.
-
port: 指定一个端口号,为空则使用缺省端口80.
-
abs_path: 指定请求资源的URI,如果URL中没有给出abs_path,那么当它作为请求URI时,必须以“/”的形式给出.
Http请求:
由以下四部分组成:请求行、请求头部、请求空行、请求数据.
下方的URL其实是abs_path.
请求方法:
方法 | 描述 |
---|---|
GET | 请求获取Request-URI所标识的资源 |
POST | 在Request-URI所标识的资源后附加新的数据 |
HEAD | 请求获取由Request-URI所标识的资源的响应消息报头 |
PUT | 请求服务器存储一个资源,并用Request-URI作为其标识 |
DELETE | 请求服务器删除Request-URI所标识的资源 |
TRACE | 请求服务器回送收到的请求信息,主要用于测试或诊断 |
CONNECT | 用于某些代理服务器,请求的连接转化为一个安全隧道 |
OPYIONS | 请求查询服务器的性能,或者查询与资源相关的选项和需求 |
PATCH | 是对PUT方法的补充,用来对已知资源进行局部更新 |
请求头:
请求头 | 描述 |
---|---|
Host | 接受请求的服务器地址,可以是IP:端口号,也可以是域名 |
User-Agent | 发送请求的应用程序名称 |
Connection | 指定与连接相关的属性,如Connection:Keep-Alive |
Accept-Charset | 通知服务端可以发送的编码格式 |
Accept-Encoding | 通知服务端可以发送的数据压缩格式 |
Accept-Language | 通知服务端可以发送的语言 |
Http响应:
由以下四部分组成:状态行、响应头部、响应空行、响应正文.
Https实现原理
Https的整体过程分为证书验证和数据传输阶段.
证书验证阶段:
- 浏览器发起Https请求.
- 服务端返回Https证书.
- 客户端验证证书是否合法,如果不合法则提示警告.
数据传输阶段:
- 当证书验证合法后,在本地生成随机数.
- 通过公钥加密随机数,并把加密后的随机数传输到服务端.
- 服务端通过私钥对随机数进行解密.
- 服务端通过客户端传输的随机数构造对称加密算法,对返回结果内容进行加密后传输.
中间人抓包
中间人攻击,实际上是指客户端在传输数据到服务端的中间过程中,被在链路上的一个设备进行抓取过滤甚至篡改,将完整的客户端-服务端通信在客户端和服务器无感的状态下分割成客户端-攻击者和攻击者-服务端两个通信阶段.
我们在Https上的应用层抓包原理也是基于中间人攻击的方式.Https上的应用层抓包原理主要"攻破"的是Https传输过程中验证身份的步骤,我们在配置抓包环境时是将Charles证书加入到系统本身信任的证书中,当应用进行通信时,如果没有进一步的安全保护措施,那么客户端接收到的服务器证书即使是Charles证书也会继续通信,整个过程如下:
对抗手段
为了应对这一通过手动给系统安装证书从而导致中间人攻击继续生效的风险,App也对该类攻击推出了对抗手段,主要有以下两种方式:
SSL Pinning
原理
也称为证书绑定,该种方式不仅校验服务器证书是否是系统中的可信凭证,在通信过程中甚至连系统内置的证书都不信任而只信任App指定的证书.一旦发现服务器证书为非指定证书即停止通信,最终导致即使将Charles证书安装到系统信任凭据中也无法生效.
绕过方式
客户端在校验服务器的情况时,考虑到对证书验证的代码是写在App内部,自然而然就可以通过Hook修改校验服务器的代码,从而使得判断的机制失效.
前人的研究工作如下:
- 可以利用Objection命令完成Bypass.
|
|
- Github开源项目-DroidSSLUnpinning.
https://github.com/WooyunDota/DroidSSLUnpinning/blob/master/ObjectionUnpinningPlus/hooks.js
由于SSL Pinning的功能是开发者自定义的,因此并不存在一个通用的解决方案,Objection和DroidSSLUnpinning也只是对常见的App所使用的网络框架中对证书进行校验的代码逻辑进行了Hook修改,一旦App中的代码被混淆或使用了未知的框架,这些App的客户端校验服务器的逻辑就需要安全人员自行分析.
服务器校验客户端
原理
这种方式发生在Https验证身份阶段,服务器在接受到客户端的公钥后,在发送session key之前先对客户端的公钥进行验证,如果不是信任的证书公钥,服务器就中止和客户端的通信.
绕过方式
服务器并不掌握在分析人员手中,因此在中间人的状态下与服务器进行通信的实际上已经变成抓包软件,比如Charles.通常来说,我们所能做的对抗手段就是将App中内置的证书导入Charles中,使得服务端认为自己仍旧是在与其信任的客户端进行通信,最终达到欺骗服务器的目的.
具体的操作需要完成两项工作:
-
分析Apk,找到证书文件和相应的证书密码.
-
在找到证书和密码后将其导入到抓包软件中,比如导入Charles.打开Charles,依次单击Proxy->SSL Proxy Settings->Client Certificates->Add 添加新证书,然后输入指定的域名IP以及端口并导入p12或者pem格式的证书,之后即可将Charles伪装成使用特定证书的客户端,最终达到正常抓包的目的.
Hook模拟抓包
这种方式的抓包虽然不如抓包软件抓到的数据包全面,但是如果能够顺利Hook到发包函数,就可以直接无视证书,甚至通过Hook直接得到参数并在Hook的函数中通过打印函数调用栈得到函数的调用链,为后续分析带来便利.
Objection
这里来展示下如何利用Objection快速定位App中的收发包函数.
示例Apk
步骤展示
- 切换到Objection的目录,删除旧的日志.
|
|
- 启动App,使用Objection附加到App进程.
|
|
- 运行下述命令,获取App已经加载的所有类.
|
|
- 输入exit命令,退出Objection,到Objection目录重命名日志文件(objection.log),防止后续操作影响本次生成的日志文件,这里重命名为objection1.log
- 使用网络框架相关的关键词来过滤相关类.
|
|
- 通过一些文件编辑器快速输入多行相同的数据来补全每一行中类的Objection命令.这里使用notepad++通过Shift+Alt对每一行首进行全选,并输入以下命令.
|
|
- 切割上述文件中的命令为多个文件,防止Objection一次性Hook太多类崩溃.
- 重新使用Objection附加到App上,并使用-c执行文件中的命令.
|
|
- 在手机上对App进行操作(这里主要是点击App中的登录按钮,抓通信数据.),如果Objection界面中没有任何函数被调到,就应该回到第8步,更换包含Hook命令的文本文件.如果在Objection界面看到一堆函数被调用,说明框架类型确认成功.
- 任意选择上图中被调用的函数,比如说选择com.android.okhttp.internal.http.RealResponseBody.source()这个函数.此时退出Objection,重新附加上App,使用下述命令进行单一Hook.
|
|
- 此时去点击App中的登录按钮,查看Objection界面.
这样就找到了发包函数com.cz.babySister.c.a.a
- Hook上述函数进行验证.
|
|
这里我们输入的账号和密码分别是123和qwertyuiop
缺点
上述过程过于依赖利用网络通信框架的关键词进行过滤,假如要分析的App本身存在强度非常大的混淆,将App中一些用来快速定位网络框架的关键字混淆成了无意义的字符,那么Hook抓包定位的方式就失效了.
OkHttpLogger
介绍
Github链接: https://github.com/siyujie/OkHttpLogger-Frida
这是一个能够完成混淆后的okhttp Hook的项目,在该项目中,Hook的方法脱离了直接经过字符串匹配的方式,反而通过反射去获取所有类并利用okhttp3框架的一些特征去验证App中是否使用了okhttp3这个网络通信框架.
示例Apk
步骤展示
- 将项目中的okhttpfind.dex放到手机的/data/local/tmp目录下,并为之提升权限.
|
|
- 启动App,使用下述命令将okhttp_poker.js注进去.
|
|
- 按照提示输入find()命令,执行寻找okhttp框架的功能.
- 将找到的结果全部复制并覆盖原okhttp_poker.js脚本中关于okhttp类的一些定义.
- 执行hold()命令,开启Hook,然后开始操作App,就会发现一堆网络连接的内容.
参考链接
<安卓Frida逆向与抓包实战>