X闽健康码分析

属于是白忙活了,但没完全白忙活

起因是某个选修课的老师觉得我这个识别口罩自动开关门的项目太简单了,事实上我也觉得很简单,甚至自动开关门我都想用只一个被驱动的异步电机糊弄过去
后来想着加点活,然后想到了去医院体检的时候,医院门口的门禁是识别口罩+扫X闽健康码
所以就想着可能X闽健康码的内容应该挺好解析的
截图后丢直接微信扫一扫,和我想得一模一样的Base64编码
传到电脑上解码的时候蚌埠住了,估计是加密了,格式如下
“MZTJKM_” + 236字节Base64编码 + “#|” + 精确到毫秒的Unix时间戳
所以就想着去把中间的Base64解出来
然后凭着上次且仅一次的三个月前渗透APP的模糊记忆
打开jadx,先看看有没有双向认证,很庆幸是"零向认证"
搜索关键字"AES",然后找了半天的密钥
换了"CBC"搜索,然后还找到了3DES的算法
感觉不对劲了
想办法抓手机APP的包,一通瞎摁点出了个请求X闽健康码的HTTP请求,虽说后面再也没摁出来过了
然后我拿着HTTP请求的URL回jadx接着搜索,然后浪费了一个小时
后来我才想到,这APP就是个壳子罢了
二维码的内容实际上还是Server给的
而且请求的URL不在APP里面而是在HTML页面里
然后开F12看JS去了,属实是有点坐牢
看到后面看到了个"decrypt"的字样,感觉有戏
跟进之后就是混淆的JS,此时感觉差不多寄了
先把JS反混淆一下大概看看
然后把混淆的代码丢console里,挨个跑被混淆的解密参数
然后从之前X闽健康码HTTP响应的json里扒拉出来data
解密之后得到了姓名,身份证号,健康状态,还有二维码的文本形式(没有后面的时间戳,时间戳是js另外加的)等
挺有意思都,新生杯密码学压轴就出这个了
到头来X闽健康码的内容还是不知道咋解析
回头想想去医院扫健康码的过程
要么是医院的门禁内置了X闽健康码的解密函数,能进一步提取里面的信息
要么那玩意就提取二维码的文本后匹配"^MZTJKM_[0-9a-zA-Z+/=]{236}#|[0-9]{13}$"
但是要是有人拿个红码能进去吗,应该不行
所以可能扫码有个颜色识别,这个我就不会了


后来又分析了下
16字节的分组加密,分组加密方式是ECB
我一开始以为应该是AES,后来跟老师讨论的时候说这种政府的项目应该是国密SM4之类的
根据我的猜测,中间存在一段在固定位置变动的22字节Base64编码,换算下来解码后正好差不多16字节
HTTP响应里也有个12字节的response_code会变动,所以这部分一直变动的16字节大概率是对应response_code
剩下4字节可以枚举,但是存在5种位置分布的情况
差不多(96 ** 4) * 5种可能
而且就算枚举出了全部的可能,也没办法通过明文与密文来还原出密钥,爆破16字节的密钥更不可能了,得爆破(256 ** 16) * (96 ** 4) * 5次,能爆破出来(96 ** 4) * 5个密钥,而且其中只有一个是对的
除非我有台量子计算机
也还有种可能,就是跟省人民政府去谈项目,但是没这个路子
总结来说就是,寄