本文标题较长:工作记录 | 跨越Android 11监听https数据包的三道难关——从Https加密、PKI体系到知产及反法侵权线索的分析

"工作记录"系列相关文章
[1]工作记录 | “口述作品”实质性相似的人工比对优化方案——语音识别?NLP?
[2]论统筹方法在法律类“重复性、机械化”工作中的应用
注:本文亦是文章《个人使用vpn"翻墙"是否违法?——基于规范性法律文件、案例以及相关计算机技术的分析与讨论》网络原理描述部分的延续和深入。

本文将同步发至本人个人网站:legalwyy.com。
本人个人网站部署了由Let's Encrypt颁发的免费数字证书,验证方式为Cloudflare DNS。
Let's Encrypt中间证书的顶级签发机构为DST ROOT CA X3。
如果你看不懂这两句话的意义,欢迎阅读本文。



目录
前言

一、法律人缘何抓包?

二、“抓包”的实质——从HTTPS协议说起

1、TCP协议的局限性

2、https的加密方法——对称加密和非对称加密

3、信任基础——CA机构和数字证书

4、证书链——“信任”的层层代理

5、我们能否自己签发一个证书?

6、http数据包抓包原理及其与https抓包的区别

7、https抓包原理——以Android APP Httpcanary为例

三、Android11抓包的困境与解决方案

1现代Android系统压根不支持用户自行导入根证书

2、获取root权限后竟然依旧无法实现对system分区的读写

3、magisk插件——Always Trust User Certicates

4、APP SSL PINNING技术——自带根证书,无视系统根证书




前言

本文10000余字,阅读时间不限。

通过本文对“对称加密”、“非对称加密”、“CA机构”等概念的分析,您可以了解https协议加密原理“皮毛”、以及略微了解互联网正常运作所依赖的信任基石——PKI体系

在了解https和数字证书的基本原理后,我们才可能弄明白:

1、抓包抓的究竟是什么?

2、抓包是如何办到的?

3、监听http数据包和监听https数据包有什么区别?

在实践阶段,笔者将呈现目前越发封闭的Android系统,是如何利用安全机制对抗用户的抓包(https)行为的,包括但不限于:

禁止用户导入系统级根证书;

Android 7及以上不再信任用户上传的证书;

必须获取root权限才能访问/system下的根证书存储路径;

Android10引入的动态分区阻止用户将system分区挂载为可读写;

APP自带的SSL Pinning (证书锁定),完全忽略系统内置根证书,因而用户无法通过添加根证书的方式实现数据包监听……


但在技术讨论之前,我们需要弄明白,为什么一个学法的文科生需要懂https协议,明白抓包的原理和操作方法——



一、法律人缘何抓包?
伴随着技术的蓬勃发展,从事互联网知产及反法法律服务的从业者应当愈加重视“抓包”的重要性。
在知识产权领域,司法界对作品信息网络传播权的侵权认定通常采服务器标准。从技术角度看,【“用户感知标准”、“实质替代标准】和【服务器标准之争的着眼点实际上在于:在对涉案行为的性质作出法律评价之前,在事实选取层面究竟依靠“前端视觉效果、可感知的操作逻辑”,还是仅着眼于隐含在前端背后的“底层技术和代码”。前述司法认定标准的争议的起因,来源于伴随着技术发展而产生的新型侵权模式,学界发明的“加框链接”、“深度链接”等概念便是明证。
毫无疑问,司法实践采取的“服务器标准”非常不利于维权方举证,因为原告通常并不掌握涉案资源所处服务器的控制权,进而难以严格采取证据保全公证。因此,在事实认定不清的情况下,原告往往寄希望于法院以模糊的“优势证据原则”为由认定被告侵权,但这种希望常常落空。
这时,我们可能需要掌握一定的技术手段,在侵权行为尚未停止之时,及时通过技术手段排查涉案行为相关资源的请求轨迹:报文究竟发往何处,而资源又从何处归来……

同样,在反不正当竞争法领域,“搭便车”、“爬虫”、“数据盗窃”等不正当竞争行为亦使我们越来越关心以深度链接、加框链接为组成部分的网页、app内嵌资源的实际来源。深度链接的概念毕竟是PC端互联网时代的产物,但近年来互联网领域的反法案件更多集中在手机端app,这是互联网产业逐渐倒向移动端的必然结果。
相较PC端网页时代发明的“深度链接”概念,手机端APP则表现为一个更“黑箱”——“深度”仅仅是深,并非深不可测;但就“黑”箱而言,往往黑到不可捉摸——在不借助技术手段的前提下,我们越来越难以判断某个APP展示的资源究竟来源于何处以及是否涉及数据盗窃……

http及https数据包监听是法律从业者的技术救星。
通过对网页内嵌资源及app来往数据报文的监听,我们得以彻底排查——
某张图片究竟来源于哪一台服务器、服务器的域名为何;
某个视频是表现为完整.MP4视频文件还是ts流媒体;
某款内容聚合平台的信息流加载功能究竟是基于谁的服务器提供的api接口实现的;
app弹出广告是通过哪一个广告联盟统计的;
用户点击行为被上传到了哪个分析平台
……

通过对侵权行为进行一定的技术分析,我们得以更好地诠释前述行为如何、以及为何落入了反法12“互联网专条”所称的何种“技术手段”。进一步,通过对具体手段进行分析和解释,我们得以洞见相关侵权主体在侵权行为中发挥的作用大小以及侵权的主观故意程度


二、“抓包”的实质——从HTTPS协议说起
1、TCP协议的局限性
在曾经的翻墙文中我们介绍过http协议中tcp的三次握手:
详见优秀文章:TCP 为什么是三次握手,而不是两次或四次?

TCP 三次握手好比在一个夜高风黑的夜晚,你一个人在小区里散步,不远处看见一位漂亮妹子迎面而来,但因为路灯有点暗等原因不能100%确认,所以要通过招手的方式确定对方是否认识自己。 

你首先向妹子招手(syn),妹子看到你向自己招手后,向你点了点头挤出了一个微笑(ack)。你看到妹子微笑后确认了妹子成功辨认出了自己。

但妹子有点不好意思,向四周看了一看,有没有可能你是在看别人呢?她也要确认一下。妹子也向你招了招手(syn),你看到妹子向自己招手后知道对方是在寻求自己的确认,于是也点了点头挤出了微笑(ack),妹子看到你的微笑后确认了你就是在向自己打招呼。于是两人加快步伐,走到一起,彼此相互拥抱。

CSDN 链接:https://blog.csdn.net/weixin_42221136/article/details/90765716
tcp协议的关键在于解决数据传输的可靠性,这种“可靠”体现在:我们必须在正确的时间和正确的人相爱
然而,这种“可靠”是相较于“完全无法保证TCP报文到达目的地的IP网络而言的——毕竟,在这个物欲横流的时代,人心也变坏了,tcp协议并不能真正解决现代社会信任缺失的问题,正如我们也曾提及一种叫做“RST重置”的东西:

我们依稀记得TCP建立连接前的三次握手,也一定还记得那天在小区里与美女浪漫的邂逅。将TCP RST重置套用到这个浪漫的故事里,可以直接表现为:

当你对着妹子招手时,旁边突然冲出来一陌生男子骗你说,“对不起,这是我的女朋友,请不要打扰她”

而随后,他又挡在你面前伪装成你的样子,冲向那位女子说,“刚刚招手的就是我,你别误会,我根本就不是在跟你打招呼,我只是在打蚊子,拜拜”——这个生动的故事为我们展现了,一个无耻的第三人就这样强行闯入了一个纯洁男子和妙龄女子的浪漫邂逅。

王宇扬,公众号:不能使用该名称个人使用vpn"翻墙"是否违法?——基于规范性法律文件、案例以及相关计算机技术的分析与讨论


2、https的加密方法——对称加密和非对称加密
http协议的内容是明文传输的,未经保护的数据包在从用户终端逐级发往代理服务器、路由及网络运营商等节点的过程中,轻易便能被劫持和篡改。若不采用一定的认证机制或信任策略,我们恐怕无法真正相信任何到达我们终端的数据报文,互联网世界的基本秩序亦因此难以维持。

详见优秀文章:彻底搞懂HTTPS的加密原理 - 顾伊凡 YGY的文章 - 知乎 https://zhuanlan.zhihu.com/p/43789231

于是,我们开始设想对http报文进行加密。

人们传统认知里的“加密”和“解密”通常是对称加密,即好比一把锁对应有唯一形状的钥匙,发送加密数据的一端和接收加密数据的另一端同时拥有两把完全相同的钥匙,这样即可保证锁住的东西在寄送过程中不被第三人轻易打开。

然而,这种方式在互联网时代无疑是一种掩耳盗铃。

首先我们必须确信的是:两把相同的钥匙不可能天然同时为互不认识的发送方和接收方同时持有,故而发送方第一次打造钥匙时,必然要同时把这把钥匙和加密数据同时发给接收方——这相当于数据在传输过程中,中间人可以直接拿现成的、以明文形式存在的钥匙解开加密信息


因此,“无需交换单一密匙”的非对称加密取代了单钥密码系统。
以某人向公安局报警为例,一个完整、严谨的非对称加密系统可描述如下:

①基本逻辑:任何由公钥X加密的内容只能通过与其对应的私钥X'才能成功解密,私钥X'私下保存,并不泄露
②钥匙数量:数据交换过程中一共有2组公钥及对应私钥

报警人公匙A和私匙A'警察局公匙B和私匙B’
③交换方式:报警人和警察局首先互相交换公钥A公钥B。随后报警人用警察局的公钥B加密报警内容“data”,经公钥B加密的数据只有通过私钥B'才能解开,而这把钥匙全世界只有那一家警察局拥有;同样,警察局的回复使用报警人的公钥A加密,只有报警人才能用其私下保存的私钥A'解密。


考虑到加密及解密的性能损失问题(事实上这种性能损失可能微乎其微),HTTPS的TLS协议并未采用纯“非对称加密”系统,而是采用了非对称加密+对称加密相结合的方式,还是以某人向警察局报警为例:

①基本逻辑不变:任何由公钥X加密的内容只能通过与其对应的私钥X'才能成功解密;
②钥匙数量:数据交换过程中一共有1组公钥及对应私钥+1个对称加密密钥
报警人随机生成的、用于对称加密的密钥X警察局公钥B和私钥B'
③交换方式:警察局把公钥B明文传输给报警人,报警人使用公钥B加密密钥X;警察局从报警人一端接收到加密的密匙X后,使用“全世界只有它一人拥有的”私钥B'解密。由于任何外人不享有私钥B',因此可以保证密匙交换绝对安

然而,单纯采用这种混合加密系统依然存在安全隐患,沿用上一个案例,以黑客干扰报警人向警察局报警为例:由于公钥B系明文传输,因此黑客可在报警人和警察局之间劫持明文传输的公钥B,替换成黑客自己享有公钥S,其自己拥有公钥S的唯一解密私钥S'。这时,报警人收到了黑客发给自己的公钥S,却误以为这把钥匙是警察局发来的,于是使用黑客的公钥S加密自己的密匙X,得到密文“*”。黑客劫持报警人发送的经公钥S加密的密文"*",使用自己所有拥有的私钥S'解密,得到密钥X,再使用之前劫持的警察局的公钥B加密成“#”传回给警察局。

这样,虽然警察局也可正常使用私钥B'解密“#”得到密钥X……
但此时,这个世界上已经有三个人知道密钥X的内容了——报警人、警察局和黑客,但报警人和警察局对此浑然不知



3、信任基础——CA机构和数字证书
为了解决中间人攻击的问题,我们打造了一款用于验证前述“公钥”真实性的身份证件,这一证件由可信任的CA机构颁布——就如同当你想要验证一个人的身份是否真实时,往往要求其展示公安局颁布给它的居民身份证。回到报警的例子,CA机构的作用可做如下描述:

①基本逻辑不变:任何公钥X只能通过与其对应的私钥X'才能成功解密;

②钥匙数量:数据交换过程中一共有2组公钥及对应私钥+1个对称加密密钥

报警人随机生成的、用于对称加密的密钥X
警察局公钥B和私钥B'
CA机构也拥有另一组公钥Z和私钥Z',其中公钥Z被一切互联网服务端保有和信任
③警察局申领数字证书:警察局携带自己的身份信息“info”公钥B向可信的CA机构申领数字证书,证书记载公钥B的内容以及公钥持有者的身份信息;
④CA机构制作数字证书:CA机构将警察局申领证书时提交的身份信息"info"公钥B作为数字证书的明文数据部分;与此同时,CA机构对前述明文进行基于md5的hash后得到固定值,并用其控制的私钥Z'对前述hash值进行加密,得到加密后的数字签名。前述明文数据加密数字签名组合,构成数字证书“.cer”
⑤交换方式:警察局把数字证书“.cer”传输给报警人,报警人同时获取了警察局的身份信息“info”、公钥B和经CA机构私钥Z'加密的数字签名。
⑥报警人验证公钥B是否被篡改:报警人事先拥有CA机构的公钥Z,在获得警察局之前申领到的数字证书“.cer”(由明文数据和经CA机构私钥Z'加密的数字签名)后,报警人用公钥Z解密数字签名得到警察局起初申领数字证书时向CA机构递交的“身份信息‘info’和公钥B”原始数据所对应的hash值,这一hash值是绝对原始和真实的。
随后,报警人使用证书记载的hash算法对明文数据部分的身份信息“info”、公钥B进行hash,得到的值倘若与证书数字签名解密后的hash值一致,则代表明文信息没有被篡改。
验证完成后,报警人使用公钥B加密密钥X;警察局从报警人一端接收到加密的密匙X后,使用“全世界只有它一人拥有的”私钥B'解密。


在此过程中,倘若黑客劫持了数字证书“.cer”,即使偷换明文公钥,并和报警人一样用公开的公钥Z解密数字证书“.cer”加密的数字签也因为无法拿到CA机构的私钥Z'解密后的数字签名进行重新加密,因而无法篡改数字签名

人们可能会问,为什么这时黑客不能使用自己瞎编的私钥S'把篡改的数字签名重新加密发给报警人呢?这是因为报警人此时手握公钥Z,只理睬由私钥Z'加密的数字签名——对于使用其他私钥加密的数字签名,报警人会直接收到“不安全”提示。
那么,黑客能不能伪造警察局的身份呢?——恐怕不行,黑客并不掌握警察局私下保存的私钥B',因而无法和数字证书“.cer”记载的公钥B一一对应。与此同时,即使黑客以自己的网站申领合法的数字证书,也因为域名不符难以顺利完成劫持。
总结来看,阻碍中间人攻击的重中之重便是CA机构的私钥警察局的私钥,任意一个泄露都将给“黑客”留下可乘之机。注意,上面一整段所称的“警察局”直接换成网站服务器站点、“报警人”换成请求访问前述网站页面的冲浪者,即可解释人们是如何通过https访问网站的。


4、证书链——“信任”的层层代理

在上一节中我们提及,网站服务器的公钥被附加在了网站部署的数字证书之中,那么如何验证用户浏览器端接收到的数字证书真实合法?

网站服务器申领的数字证书叫做服务端证书(End-user Certificates),这一证书是用来保证网站传输的公钥未被篡改、身份信息符合数字签名的记录。这一证书同时包含了其上级的授信信息:中间证书(Intermediates Certificates) 和根证书(Root Certificates)。

中间证书是签发服务器证书的CA机构用来验证服务器证书的真实合法性的,即确认https使用的end-user证书是属于该服务器所在域名的证书。根证书是用来验证中间证书真实合法的证书。换言之,服务端是通过中级证书机构的私钥Private Key签发的,而他们的证书又是Root CA通过它的私钥对中级机构提交的CSR签发的。


工作记录 | 跨越Android 11监听https数据包的三道难关——从Https加密、PKI体系到知产及反法侵权线索的分析-法学随想

因而,根证书、中见证书和服务器证书构成了一个完整、可溯源的信任链条。当我们在验证服务端证书的有效性的时候,会一层层的去寻找颁发者的证书,直到找到自签名的根证书,然后通过相应的公钥再反过来验证下一级的数字签名的合法性及吊销状态。Root CA作为自签名的顶级签发人,对他的签名只能无条件信任。

如何成为Root CA?CA机构可以申请将自己的根证书加入到各公用根证书库,通过行业审计后形成列表,终端厂商定期将列表增加到系统或者浏览器中——这便是为什么,我们的手机和电脑端系统会内置一些顶级CA机构的根证书。




5、我们能否自己签发一个证书?

任何人都可以自己给自己签发证书,但只有通过Webtrust认证才可能成为Root CA机构,向全球的终端用户散发自己的可信根证书。

但是,假如我们想要在自己家里用https加密内网访问,例如访问192.168.1.1路由器web端时加密传输,能否做到呢?当然可以!我们只需自行为路由器终端生成自签名证书和客户端证书,相互信任即可。


6、http数据包抓包原理及其与https抓包的区别
事实上两者区别不言而喻。由于http报文采明文传输方式,因此只需在设备终端设置一个代理服务器即可监听服务端向外上传的http数据包及报文内容。
当人们提及抓包,往往想到fiddler、Wireshark等专门用于监听数据包的工具。但事实上,善于翻墙的朋友们可能早已发现,Surfboard、Clash for Windows/Android、V2rayNG等proxy工具在实现数据包转发的同时便轻松以日志方式记录服务端应用向外发出的请求,甚至,对于像clash这样具有复杂代理规则的proxy的日志捕捉器中,你可以轻松看到不同app向外发出的请求适用了完全不同的代理规则,如bilibili访问的ip与GeoIP数据库匹配后自动使用“全球直连[direct]”规则、广告流量适用“全球拦截[reject]”规则、境外流量使用用户预设服务器节点等……当然,有些扯远了。
但这个现象给我的启示很简单——任何http报文,数据途径的物理和逻辑节点均可实现对这些报文的直接访问和记录。
然而,当我们谈及https数据包便不可同日而语了。由于用户端与服务器端以非对称加密+数字证书的形式秘密交换了用于对称加密的密匙,因而一旦互相发送的数据被密匙加密,途径的中间服务器便不可能实现对这些报文的解密——而在当前,大部分web网站和手机APP与服务端的通信都采取了SSL/TLS加密。

这便是搞互联网知产与不正当竞争案子的法律人最值得悲哀的地方。

倘若不采取技术手段“破解”被加密的报文,我们将永远无法得知——某个侵权网站、侵权app究竟访问了哪个服务器节点……
好在,司法实践中,早已认可了PC端抓包工具fiddler的合法性,该工具可通过导入自签名根证书的方式实现对windows端https连接的监听(具体原理见下一节,PPC平台与Android平台的监听http和https的原理并无二致)。
但是,虽然大家都知道,fiddler亦可被用于手机端数据包监听,只需保证PC端和手机端处于同一局域网之下,并为手机端设置http代理,ip地址为fiddler所处的地址,端口调整为fiddler监听的端口即可。这时,fiddler的工作方式实际上是前述翻墙代理工具实现数据包监听的另一种表现形式罢了。
但是,很少有人提及Android平台抓取https的困难。
下一节我们将首先讲述https数据包抓包原理,而后引入在安卓端遭遇的困境和相应解决方案。

7、https抓包原理——以Android APP Httpcanary为例
前文耗费大量篇幅讲述CA机构与数字证书,都是为这一节作铺垫的。
首先,抓包APP要实现对其他APP流量的监听,必须在本地建立代理服务器,将本地发出的一切请求交由代理服务器接管。此时,http报文已经不在话下,剩下的便是对https加密数据的“破解”。
我们还记得,在windows端,fiddler会申请向windows导入一张尤其签发的根证书。同样,在Android端,httpcanary也要求用户导入其签发的根证书。为什么监听https要导入根证书呢?或者说,为什么导入根证书能实现对https的监听?
在Android端,过程是这样的:
①当你在浏览器内键入baidu.com时,由于本地开启了代理服务器,这一请求便被转发给了httpcanary;
②httpcanary根据浏览器提供的SNI信息(baidu.com),生成一张不被公共领域认可的证书,证书签发的对象即是baidu.com。
然而,baidu.com实际部署的可信证书分明如下图所述

工作记录 | 跨越Android 11监听https数据包的三道难关——从Https加密、PKI体系到知产及反法侵权线索的分析-法学随想

httpcanary擅自为baidu.com签发证书显然是非法的伪造证书行为,那么这种行为为何能够通过本地验证而不会报“不可信”警告呢?
我们打开httpcanary,访问baidu.com,再点击chrome的小锁一探究竟,便可惊讶地发现:baidu.com部署的证书变成了由HttpCanary签发的证书。

工作记录 | 跨越Android 11监听https数据包的三道难关——从Https加密、PKI体系到知产及反法侵权线索的分析-法学随想

但是我们别忘了,在此之前,我们已在自己的终端安装了由httpcanary提供的根证书。当终端认定httpcanary是可信目标后,会和httpcanary完成常规的加密过程,httpcanary会把浏览器的请求数据打印在控制台上,然后转发给真实的baidu.com,真实的baidu.com返回了响应给了httpcanaryhttpcanary把响应数据打印在控制台上,然后转发给你的浏览器。既然所有的加密动作都是由httpcanary亲自操办的,那么访问https数据当然不在话下。
有人会认为,抓包工具httpcanary成功完成了一次中间人攻击,但亦有不少人对这种说法嗤之以鼻——httpcanary并非担任中间人的角色,其自始至终都是服务端的一部分,httpcanary伪造的根证书是由用户亲自导入进系统的,这相当于:某间屋子的主人亲自将小偷邀进房间,在主人的指使下偷盗自己的东西。在这种情况下,主人苛责小偷的恶意是非常滑稽的,因为一切都是主人自己的意志。

所以,Fiddler并不是用了多么高深的手段来破解了TLS的加密,而是Fiddler在你自己的配合之下,绕开了正常的信任策略,从而让你可以窥探你自己的通信流量,它既没有破解加密算法,也没有破解信任策略,一切都在安全框架之内。

HTTPS采用高安全性的TLS加密,可为什么Fiddler抓到HTTPS的包能解密? - CJey的回答 - 知乎 https://www.zhihu.com/question/395294859/answer/1247418814
但是我依旧认为:法律人光荣地完成了一次对app的中间人攻击
我们似乎认为,用户控制的设备与外界进行的通信似乎是永远是用户的私产——但事实上,app的加密https通信某种程度上是app运营者的“商业秘密”。举例而言,知乎app并不想告诉用户——当用户打开主页,点击一篇文章时,图片来源于哪台云服务器的对象存储。
在这个意义上,善于抓包的法律人似乎颇有些以违法手段维护法律权益的味道在。多么有趣!



三、Android11抓包的困境与解决方案

但到了Android平台上,一切都变得不那么有趣了。

我们通过上一章最后一节,已经知道了抓包的基本原理就是无条件信任由抓包工具自签名的根证书,进而以代理服务器身份与本地应用经常https数据通信,在通信过程中,使用的根证书不再是原网站部署的、为公有领域所信任的CA ROOT颁发,而是由抓包软件伪造——问题的关键就在于能否成功导入抓包软件自签名的根证书。

在Android端,开发者利用了大量手段对用户导入根证书进行限制,包括但不限于:


1、Android系统默认不支持用户自行导入根证书——必须获取root权限

在Android 7(Android N)之后,系统默认不再信任用户自己安装的证书。

In Android Nougat, we’ve changed how Android handles trusted certificate authorities (CAs) to provide safer defaults for secure app traffic. 

Apps that target API Level 24 and above no longer trust user or admin-added CAs for secure connections, by default.

https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html
与此同时,Android端原本就不含有用户导入“根证书”的交互功能。要实现根证书导入,必须修改system分区的数据:即手动将根证书文件导入专门存储根证书的路径。
然而,要实现对系统分区数据的修改,必须获取root权限,并将根目录或system分区挂载为可读写。
当前主流的root方式是Magisk,其在XDA的官方页面对其作出如下精确、简练的概括:The Universal Systemless Interface, to create an altered mask of the system without changing the system itself.
Magisk的工作原理是在boot中创建钩子,通过bind mount挂载一个在system文件系统基础上可自由读写、由Magisk管理的虚拟文件系统,在对这一虚拟文件系统进行修改使不必对原system分区实施任何改动。
因此,要使Magisk发挥作用,必须在Android的boot.img中植入。要实现boot.img的刷入,又必须首先解锁Android的Bootloader,许多手机厂商强制锁定了Bootloader,进而不具备获取root权限的可能性。
即使你是一加粉丝,万幸学会了:
如何搞到手机端当前系统版本的全量包
并学会了如何解密全量包导出boot.img
又学会了如何给电脑安装Android Boot loader Interface、ADB interface驱动
又学会了开启安卓开发者模式
又学会了如何通过cmd命令解锁bootloader
又学会了如何使用magisk客户端将magisk植入从全量包解密出来的boot.img
又学会通过命令刷入植入magisk的boot.img
又学会在magisk中设置root权限管理
……
以往,当我们获取root权限后,直接挂载系统分区为可读写即可实现对系统的任意修改,
但现在,你会惊讶的发现,即使获取了root,依旧动不了system分区……


2、获取root权限后竟然依旧无法实现对system分区的读写

原来,Google在Android 10引入了动态分区(Dynamic Partitions)技术。

动态分区是 Android 的用户空间分区系统。使用此分区系统,您可以在无线下载 (OTA) 更新期间创建、销毁分区或者调整分区大小。借助动态分区,供应商无需担心各个分区(例如 system、vendor 和 product)的大小。取而代之的是,设备分配一个 super 分区,其中的子分区可动态地调整大小。单个分区映像不再需要为将来的 OTA 预留空间。相反,super 中剩余的可用空间还可用于所有动态分区。

https://source.android.com/devices/tech/ota/dynamic_partitions
一台Android设备被分为了2个虚拟出来的槽,可同时容纳两个版本不同的系统。system、product、vendor这三个分区分别有A/B两个。

A/B分区结构,顾名思义,将系统分区分成了A和B两个槽(slot),手机启动时会选择A槽或者B槽启动,运行过程中仅使用当前槽位的分区。一旦当前运行的槽出现问题,系统仍可以选择另一个槽进行启动,从而保证系统良好的可用性。

Android系统分区与升级 - SYLVAIN的文章 - 知乎 https://zhuanlan.zhihu.com/p/364003927
基于目前笔者尚未研究清楚的原因,适用Dynamic Partitions的系统基本无法实现对system的挂载,进而无法对system进行读写。
说到这里,读者恐怕都快忘了我们获取root权限的初心——即复制一个由抓包软件伪造的根证书,内置于系统根目录中,以使得系统内所有app无条件信任这一证书,所有的https流量都在抓包软件构建的代理服务器中完成加密动作。
这时,笔者将注意力转移到了一个magisk插件之上。


3、magisk插件——Always Trust User Certicates
这一插件的作用名副其实,要达到的效果是使得所有服务端无条件信任用户证书。在前文我们忘了说,虽然用户无法上传根证书,但至少留有安装用户证书的入口(即之前举例的其他特殊用途,例如为家庭局域网构架https访问、特殊的交易机构的自有证书以实现交易安全需求等)。这一插件的作用方式是自动将用户证书复制到系统根证书目录。而借助了magisk构建的虚拟文件系统,我们得以在不修改system的条件下实现:将伪造的根证书导入成为系统级别的根证书——一切应用都无条件信任。
眼下,终于可以正常在httpcanary中监听到部分https流量了。

但十分离奇的是,在正常联网状态下,许多app似乎都发现自己被监听了,均无法正常联网。



4、APP SSL PINNING技术——自带根证书,无视系统根证书

原来,许多app为了保证数据通信绝对安全,往往将其通信过程中会用到的根证书至于app内部了,此时,app不再信任任何系统级根证书,而是调用存储在app内的根证书文件。当app发现其自带的根证书颁发机构与实际通信过程中接收到的根证书不符之时,便自动判定连接不安全,自行终止连接。

SSL Pinning ,即SSL证书绑定,是验证服务器身份的一种方式,是在httpst协议建立通信时增加的代码逻辑,它通过自己的方式验证服务器身份,然后决定通信是否继续下去。它唯一指定了服务器的身份,所以安全性较高。

https://blog.csdn.net/Gushiyuta/article/details/95492584



……


太累了。刚解决了root的问题,又解决了植入根证书的问题,眼下居然还有大量app防着我们。没办法,只能继续干他们!

笔者有幸发现一款xposed插件——TrustMeAlready。


xposed实现对app的侵入和篡改,是基于hook技术。


Hook 直译为 “钩子”,一般指将自定义的逻辑“钩”在要 Hook 的事件上。在Android 平台上,即意味着在指定函数被调用时执行各类插件的Hook 代码,根据插件的逻辑拦截修改原有的函数响应。

一切xposed插件皆依赖各种各样的hook环境。从用户端视角看,实现xposed插件的效果分为root和非root两种环境(即是否获取Android系统最高权限的两种状态)。

①就前者而言,其基本原理为:

ART是Android系统的一种虚拟化架构。一切安卓端app进程皆由Zygote进程孵化而来,Zygote进程由/system/bin/app_process得到。每当一个app运行时,系统会构建一个ART虚拟机实例,并使app运行在虚拟机中。Xposed框架利用Root权限替换appprocess,将XposedBridge.jar注入,Zygote会将这一被注入的运行环境拷贝到每一个app的虚拟机实例中,从而导致xposed框架可实现“对任何app进程的执行流程进行劫持和修改”。(Edxposed则使用Riru注入系统自带的动态链接库 libmemtrack.so,此处略)。

②就后者而言,以weishu开发的太极(Tai Chi)框架为例

该框架通过对app进行解包,添加hook代码并重新打包,从而达到无须root权限便可注入、修改app进程的效果。


TrustMeAlready通过勾住app中所有用于校验SSL证书的API,并进行屏蔽,以防止app对根证书进行校验,从而不再能判断由httpcanary伪造的顶级签发人httpcanary root ca和相应根证书是否与内置ssl证书不符。


自此,我们终于实现了对Android 11 所有APP的Https数据包监听。




四、文章主旨的升华(悲春伤秋,不看也罢)

互联网时代,迫于技术门槛的提高,我们越来越难以做自己的主人了。

手机握在我们手中,我们当然享有对这台手机的排他权利——然而实现这台手机全部价值的应用软件所进行的数据交互却越来越不受我们的控制。

系统开发商、手机厂商、APP运营商以各种理由限制用户的手脚——美其名曰:为了安全。

这么说确实有些道理,但我越来越觉得,平台经济把我们娇生惯养成了一个生活不能自理的人。

我们刷着精美的app,却再也无法理解app背后真正的原理,进而难以探知这个世界的运作原理。

我们的信息被悄无声息地发往远方却浑然不知。

我们似乎已经习惯各类APP的唤醒链,我们也习惯快速点击“授予app敏感权限”的提示框确认按钮……

我们相信平台经济、双边市场理论灌输给我们的“公平交易”概念,以为拿隐私换便捷、用看广告的方式换取免费服务是超值的事情——但却忘了,平台经济的垄断地位悄然建立之时,我们再无任何议价权。

我一向认为,Android平台的root权限、xposed插件的hook技术是普通人借助技术对抗平台经济唯一的机会。之后有空,我会考虑单独开一篇讨论这一话题的文章。


全文完。


本篇文章来源于本人微信公众号:不能使用该名称