在密码学和计算机安全领域中,中间人攻击(Man-in-the-middle attack,缩写:MITM)是指攻击者与通讯的两端分别建立独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。
中间人攻击原理:
Https中间人攻击,最常见的攻击方式:SSL/TLS证书欺骗攻击,即劫持客户端网络请求,伪造证书,如下图所示:
客户端被中间人攻击的主要原因:
客户端对返回的证书链校验不严谨
证书链默认校验原理(如下图):
1、网站的证书链通常分为三级(不完全是):CA根证、CA二级证书、域名证书;
2、CA根证作为移动设备系统预埋、默认授信的证书(可在手机设置里面看到);
3、当Https网络请求时,服务端默认返回除CA根证外的证书链;
4、从域名证书信息中查找自己的签发根证,逐级直到CA根证;
5、从CA根证取出公钥校验其签发证书的签名,逐级直到域名证书;
如果手机中已安装了抓包工具的CA根证(如Charles、Fiddler导出的根证书文文件),当我们Https请求时,抓包工具会返回经过伪造的证书。所以,当通过上面这种常规的校验方式时,无论怎么校验都是通过的,因为:这三个证书都是抓包工具伪造的。
中间人攻击方式:
1、将中间人的CA根证安装到移动设备授信证书列表中;
2、拦截Https网络请求,伪造完整证书链;
3、逐级查找证书链时,完全正确;
4、逐级校验证书签名信息时,完全正确;
5、这样客户端会认为服务器返回的证书没有问题,可以继续操作;
如何防御?
1、将服务器CA根证预埋客户端,仅基于该CA根证校验;
2、将服务器CA根证的公钥预埋客户端,判断公钥合法性;
3、Https双向校验;
4、除了使用Https,业务数据再单独加密(安全性高);
防御方式一:将服务器CA根证预埋客户端,仅基于该CA根证校验;
通常做法:
1、将服务器对应的CA证书放置客户端:
a、可以是单个CA根证书文件
-- 程序中设置使用该CA根证校验
-- 但是,CA根证也有过期时间,如果CA根证过期,需要升级客户端,比较麻烦
b、也可以是预埋多个CA根证书文件,可使用bks证书库来管理
-- 程序中设置使用该bks证书库校验
-- 如果当前CA根证过期,bks中还有其他CA根证可备选,仅升级服务端即可(服务端更换匹配的证书)
2、代码中指定使用该CA根证书校验(非设备授信清单里的根证)
3、这样中间人抓包就会失效了,因为咱们指定的CA根证书中并不包含其根证。
如何破解(后面再详细介绍)?
1、Root设备,安装Xpose工具,抹掉指定根证校验的代码即可;
2、Root设备,安装Xpose工具,安装JustTrustMe.apk,禁止TLS证书验证;
防御方式二:将服务器CA根证的公钥预埋客户端,判断公钥合法性
与方式一类似,请参考方式一即可。
防御方式三:Https双向校验
在方式一的基础上,本地再预埋客户端证书,当Https通信时,做两次校验,即:客户端对服务器证书进行认证,服务器对客户端证书进行认证,以防止证书被篡改。
这种校验方式的破解难度,要比方式一难很多,即使将本地的客户端校验给破解了,也很难解决服务器端的校验逻辑。但是要注意本地证书库密钥的管控,尽量不要直接硬编码到程序中。
防御方式四:除了使用Https,业务数据再单独加密(安全性极高)
这种方式也是目前很多银行和支付软件常用的方式,Https仅是作为常规的加密手段,更重要的是应用内业务数据单独加密的逻辑,即:客户端与服务器握手时,单独约定密钥,使用约定密钥对业务数据进行加密,加密后的数据再通过Https传输。
这样,即使设备被Root、Hook,破解了Https,获得的仍然是密文数据。
除此之外,一些银行或支付软件会还会采用本地预埋证书的方式进行单/双向校验,以增加Https被破解的难度。
开发者如何对自己的APP Https抓包?
1、如果APP没有采用上面的防御方式,就比较简单了:
知识点:
1、手机设置中授信的根证列表,有两种:系统级、用户级
2、第三方根证,默认只能安装在用户及授信的根证列表中
3、谷歌在安卓7.0修改了安全策略,用户添加的CA证书(用户级授信根证列表)不能再用于安全连接
常规抓包方式:
1、7.0以下手机,安装抓包工具CA根证,配置抓包代理,直接抓包即可
2、7.0以上手机,增加程序配置,设置用户级授信根证列表可信任:networkSecurityConfig,抓包
3、7.0以上手机,Root,将抓包工具CA根证安装到系统级授信根证列表中,直接抓包即可
4、Root手机,安装Xpose工具,安装JustTrustMe.apk,禁止TLS证书验证,抓包;
2、如果APP采用了方式一:
常规抓包方式:
1、注释指定本地CA根证校验的代码,然后参考上面的抓包方式
2、将抓包工具的根证也放在本地(如:导入bks),参与Https校验(注意:千万别打包到生产包中)
3、Root手机,安装Xpose工具,安装JustTrustMe.apk,禁止TLS证书验证;
3、如果APP采用了方式二:
参考上面抓包方式
4、如果APP采用了方式三、四:
代码在手,逻辑自由 o(*^@^*)o 哈哈~
能不能抓包成功,是由开发者对程序代码逻辑的熟悉度决定的,好好分析一下~