最近看论坛里关于抓包的问题聊的火热,小弟我也借此机会献丑来分享一下我的抓包的研究成果。
毫无疑问,app逆向的第一步是抓包。通过抓包可以获取很多有用的线索,比如url,参数名等。再根据url,参数名等,可以逐步抽丝剥茧找到app收发数据的地方,然后就能找到最关键的签名所在的位置。研究清楚签名,接下来就可以做一些不可告人之事了~
安卓app常用的网络框架是okhttp,对于okhttp的抓包研究已经非常成熟了,无非是certificate pin或者hostname verify那一套。但是最近几年,出现了一些基于Google Cronet通讯框架的app,比如某音,某小破站等等。Cronet是从Chrome中抽出的给移动端使用的网络组件,目前针对Cronet抓包,证书校验的研究比较少,大多是奇技淫巧,没能从根本上挖掘。本文从Chrome源码出发,结合实例某音,研究一下使用Cronet安卓程序的正确抓包姿势。
打开手机代理,将https证书塞入手机的根目录,启动目标应用,结果:
请求全部失败,app界面也显示无网络,无所谓,我们打开日志先看看:
看到了:ERR_CERT_AUTHORITY_INVALID
很明显是检测到了证书 无效。
经常使用Chrome浏览器的朋友应该对这种ERR_开头的错误有印象:
没错,这正是Chrome的报错通用的格式。
那么我们就可以从报错入手,去Chrome源码里看看这个错误的来源,以此为根据寻求bypass的方式。
打开Chrome Code Search(在线的Chrome源码浏览网页,提供了强大的交叉引用和全文搜索功能)
全局搜索ERR_CERT_AUTHORITY_INVALID
出现了很多结果,观察后发现 net/cert/cert_status_flags.cc这个文件比较可疑,点进去看看:
发现 一个叫做MapCertStatusToNetError 的函数里,返回了这个ERR_CERT_AUTHORITY_INVALID。
(MapCertStatusToNetError )映射证书状态至网络错误类型,查看这个函数的被谁引用:
在一个cert_verify_proc_android.cc的文件里被引用。这个文件名已经暗示了在检查/校验证书,我们点进去看看:
在VerifyInternal这个函数里,先用TrustManager校验了一番,如果发现校验结果verify_result的cert_status出现了error,则直接将错误映射后返回。如果没有错误则检查了证书的发布者是否为known_root,然后返回OK。
我们再往上回溯VerifyInternal这个函数:
看到一个更抽象的名字:cert_verify_proc.cc(证书校验程序),点进去看看:
在这个函数中,rv保存了VerifyInternal的结果,如果结果是OK,则再继续进行了更多的检查:
比如证书是否使用了较弱的hash算法,是否过期,是否有效期过长(ssl证书有效期通常为1年)等等。
最后将rv返回。
我们看到无论是哪一步返回,rv的值都是MapCertStatusToNetError 这个函数赋予的。所以如果我们直接将这个的返回值改为OK,那么无论怎么校验,最终Verify的结果都是通过。换句话说,就是证书校验的过程被bypass了。所以我们考虑在app的so中找到这个函数的位置,然后修改即可。
我们观察MapCertStatusToNetError这个函数的特征:
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2023-8-3 18:25
被乐子人编辑
,原因: 补充特殊情况