赞
踩
我们在做内网渗透的时候,往往通过ARP投毒、DNS欺骗、会话劫持等来发起中间人攻击(MITM)。利用这些手段攻击HTTP协议的网站简直易如反掌。但是现在几乎所有的网站都已经升级为更加安全的HTTPS协议了,那么是不是意味着中间人攻击就无效了呢?
我们先看HTTP协议为什么不安全。我认为主要可以分为3点:
由于以上原因,现在网站基本上都升级为HTTPS协议了。在讲HTTPS之前,需要先弄清楚什么是PKI。
公钥基础设施(Public Key Infrastructure)英文简称PKI。听名字就不太好理解,因为它不是某个具体的算法或协议,而是一系列设施的集合,是一个体系。完整的 PKI 系统必须具有数字证书、认证中心(CA)、证书资料库、证书吊销系统、密钥备份及恢复系统、PKI 应用接口等组成部分。其中CA包括CA中心和CA系统。CA系统是专门负责颁发数字证书的系统,该系统功能包括:
然后,负责管理并运营 CA 系统的机构称为 CA 中心。我们习惯性统称为CA。CA是具有权威性而且值得信任的。而且CA证书是存在信任链的,根CA授权并信任中间CA,那么中间CA也是可信的。根 CA 是指在组织的 PKI 中最受信任的 CA 类型。如果根 CA 被泄漏或向未经授权的实体颁发了证书,则组织中任何基于证书的安全性都变得易受攻击。
因此,通常根 CA 的物理安全性和证书颁发策略都比中间 CA 更严格。根 CA 虽然可以直接向最终用户颁发证书,但实际上,它们只向其他 CA(称为从属 CA或中间CA)颁发证书。以Chrome浏览器为例,看浏览器内置的根CA:
加密基元 | 算法 |
---|---|
散列函数 | MD5、SHA-1、SHA-2 |
非对称加密 | RSA |
对称加密 | AES、DES |
它们是怎么发挥作用的,举个例子:我们访问京东时,浏览器地址栏输入www.jd.com,然后回车就能进入官网购物了。但是我们怎么判断我们访问的是不是真正的京东呢。因为攻击者通过DNS欺骗完全可以把你引导至一个伪造的京东。这时就需要数字证书,这个证书是CA机构颁发给京东官网的,当你访问时把证书发给你就可以辨别真伪了。如果攻击者也伪造一个证书呢?这就需要用到数字签名了。数字签名使用的就是RSA非对称加密算法。
非对称加密算法需要两个密钥:公开密钥(Public Key,简称公钥)和私有密钥(Private Key,简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。大致如下图:
很多人说HTTPS就是披了一层 SSL 的 HTTP。可以这么理解。
在SSL更新到3.0时,IETF对SSL3.0进行了标准化,并添加了少数机制(不过几乎和SSL3.0无差异),标准化后,IETF将其更名为TLS1.0(TransportLayer Security 安全传输层协议),可以说TLS就是SSL的新版本3.1。TLS(传输层安全)是更为安全的升级版 SSL。由于 SSL 这一术语更为常用,因此我们仍然将安全证书称作 SSL。事实上我们现在用的都是TLS,但因为历史上习惯了SSL这个称呼,平常还是以SSL为多。
建立HTTPS就需要用到PKI,需要CA颁发证书。建立HTTPS通信过程大致分3个步骤:
用图来描述CA、服务器和客户端之间关联大致如下:
我们来详细解剖第一个步骤验证数字证书的全过程,刚开始学的时候在网上查了很多资料,众说纷纭,后来慢慢通过实践才总结出来,因此学网络安全很多时候需要自己慢慢积累和摸索。当浏览器收到服务器发来的证书时,会进行以下4步验证:
拿Chrome浏览器举例,2021年8月,谷歌进一步更新了其浏览器的默认安全策略。目前默认的安全级别:只要以上4步有任何一步出现问题,立即阻止本次用户的访问,而且是强行阻止(用户无法选择继续访问)。
但这仅仅是Chrome浏览器,其它浏览器和APP并非都想谷歌一样谨慎。接下来讨论Android APP的HTTPS中间人攻击。
前面讲过,现在绝大部分通信都采用了HTTPS协议,使得在Android渗透过程中,会经常遇见https证书校验,从而导致不能抓取数据包。
几乎所有网络数据的抓包都是采用MITM的方式,包括常用的Fiddler、Burpsuite等抓包工具。所以我们以抓包来描述中间人攻击。
现在的APP都是HTTPS服务提供商自己开发的,开发者可以先将自己服务器的证书打包内置到自己的APP中,或者将证书签名内置到APP中,当客户端在请求服务器建立连接期间收到服务器证书后,先使用内置的证书信息校验一下服务器证书是否合法,如果不合法,直接断开。
当APP是HTTPS时,单纯的使用Burpsuite无法抓取数据包,原因是APP启用了SSL Pinning(又称“SSL证书绑定”)。HTTPS建立有单向认证和双向认证两种情况,如下图所示:
双向认证时客户端也是有一个证书的,建立通信时不仅客户端要验证服务端的合法性,服务端还要验证客户端的合法性。这样APP抓包就有三种情况:
情况1,客户端不存在证书校验,服务器也不存在证书校验。
情况2,客户端存在校验服务端证书,服务器不存在证书校验,单项校验。
情况3,客户端存在证书校验,服务器也存在证书校验,双向校验。
情况1没有难度就不讨论了,在情况2的前提下,我们使用JD-GUI进行反编译,然后全局搜索:checkClientTrusted 或者checkServerTrusted 字符串,如下图:
SSL-pinning有两种方式:
证书锁定(Certificate Pinning) 和公钥锁定( Public Key Pinning)。
证书锁定:
开发者在客户端代码内置仅接受指定域名的证书,而不接受操作系统或浏览器内置的CA根证书等任何证书,通过这种授权方式,保障了APP与服务端通信的唯一性和安全性,因此客户端与服务端之间的通信是可以保证绝对安全。但是CA签发证书都存在有效期问题,缺点是在证书续期后需要将证书重新内置到APP中。
公钥锁定:
提取证书中的公钥并内置到客户端中,通过与服务器对比公钥值来验证连接的正确性。制作证书密钥时,公钥在证书的续期前后都可以保持不变(即密钥对不变),所以可以避免证书有效期问题,一般推荐这种做法。
不过安全性高的都采用了证书锁定,比如微信在6.7.3版本以后就是采用证书锁定的方式,它不再信任系统内置的证书,而只信任自己的证书。而Android系统从7.0开始也不再信任用户CA证书,只信任系统内置的证书。
有两种绕过方式,方法一是在已经root的设备上安装CA证书,然后直接抓包即可,在本机无法取得root的情况下,通过模拟器也可抓到https数据包。方法二不需要root,而是通过反编译apk,找到校验证书方法,将校验部分删除,从而变成情况1,再编译apk,就可以抓取数据包。举个例子:利用Androidkiller.exe反编译apk文件,找到checkServerTrusted方法的smali代码,如图:
前面我们提到有些APP不再信任用户安装的CA证书,也有一个绕过方法:在AndroidManifest配置文件中修改networkSecurityConfig选项。
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config">
......
</application>
</manifest>
然后在项目res目录下新增一个文件夹,命名为xml,然后在xml目录下新建一个network_security_config.xml文件,命名跟上面匹配。
<?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证书的校验给予通过。不过此方法往往只对少数apk管用,大部分APP都做了加固,很难通过该方法来绕过证书验证。
另外还可以调低targetSdkVersion < 24。如果想抓一个APP的包,可以找个历史版本,只需要其targetSdkVersion < 24即可。然而,随着GooglePlay开始限制targetSdkVersion,现在要求其必须>=26。2019年8月1日后必须>=28,国内应用市场也开始逐步响应这种限制。目前绝大多数APP的targetSdkVersion都大于24。所以这种方法基本行不通了,就算可以也不是长久之计。
还有一种方法就是可以使用平行空间或者Virtualapp来曲线救国。平行空间和VirtualApp这种多开应用可以作为宿主系统来运行其它应用,如果平行空间和VirtualApp的targetSdkVersion < 24,那么问题也就解决了。不过这个方法经过我多次尝试,发现往往不好使。
最后一种方法是把CA证书安装到系统内置列表里,这种方法需要root。
然后来看实例,我先开一台虚拟机A伪造服务端,可以自签证书。用另一台电脑B正常上网(假装是受害者)。然后对B发起中间人攻击。
正常情况下,浏览器安全肯定不会这么脆弱,来看浏览器是如何借助HTTPS抵御中间人攻击的。用Edge浏览器访问www.baidu.com。如图:
但是可以发现用户依然能选择"继续转到网页(不推荐)"。如果我们使用Chrome浏览器会是这样的:
上述中间人攻击实践中使用到了Fiddler及Burpsuite仅是为了方便控制及调试中间人攻击的状态,实际操作中并不需要Fiddler,也就是说你的手机不需要连接任何代理,因为往往流量的劫持发生在更隐蔽的网络节点中,如链路中的网络设备完全可以在无感的情况下将经过自己的流量转发到中间人服务器,或者这种劫持也可能由DNS解析引起。事实上ARP投毒,WPAD劫持,DNS欺骗,BGP路由劫持,都会为这种中间人攻击创造条件。
补充:我偶尔发现有的APP应用层使用的并非HTTP协议。比如微信和QQ,应用层使用的就不是HTTP协议,而是其私有的协议,这种情况需要使用其它的抓包工具从传输层分析,比如Packet Capture这种直接解析TCP/UDP协议的,但是往往非HTTP协议的数据包即使抓到了也无法解析出来,因为大概率都是二进制而非文本格式的。比如QQ应用层是腾讯私有协议,传输层是TCP和UDP混用,而且做了加固防止反编译等等,安全性极高。
最后,针对HTTPS的中间人攻击,是建立在开发者没有正确的对证书进行校验的前提下。在这种证书校验不严格的前提下才能实施MITM攻击,如果证书校验严格的话,从理论上来讲是无法攻击的。网上那些教程,像利用ettercap或者bettercap进行中间人攻击,全部是针对HTTP协议的,但是他们普遍没有说明这一点。像这样的:
与本篇内容相关的资料在公众号"极客随想"内回复消息:内网渗透,即可获取。公众号不定期分享一些经验和干货,欢迎关注。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。