某核酸检测信息查询平台的漏洞发现

最近我在的城市疫情有点严重,连续被捅了8次嗓子,在某次查询核酸结果的时候,我发现了查询网站好像不那么安全,于是开始了研究。

漏洞发现

平台界面

在查询核酸检测结果时,发现每次请求的API参数是相同的,并且请求无需通过验证。那么,这里的验证码很可能只有前端验证,后端并没有进行验证,并且加密算法是固定的。只要知道是如何加密的,就可以直接通过身份证号查询到公民信息。

加密算法

通过F12,发现接口发送的参数为IdCard。在所有的JS文件中搜索IdCard,排除掉几个无用的文件后,发现了真正发送数据的JS文件。

相关代码段
1
2
3
this.resultList = [], this.idCode = "", T("******", {
IdCard: s
})

把这个JS文件直接下载到本地进行分析,按住Ctrl点变量s,追踪到s是由O函数得到的。

1
2
3
var e = this,
s = O(t),
a = this;

O函数的功能是对输入的身份证进行AES加密,返回的密码被发送到接口。这里的AES加密模式为ECBPkcs7填充,在O函数的上方,还发现了密钥。

1
2
3
4
5
6
7
8
9
var A = CryptoJS.enc.Utf8.parse("******");
function O(t) {
var e = CryptoJS.enc.Utf8.parse(t),
s = CryptoJS.AES.encrypt(e, A, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return s.ciphertext.toString()
}

验证

由于O函数位于闭包函数内,不便于调用,所以将用于加密的aes.js文件下载到本地,然后在控制台直接调用O函数得到密文。

控制台输出

再将密文直接发送到接口,得到公民信息。

接口返回信息

此网站还有个功能为通过二维码批量获取核酸检测结果,猜测开发者为了省事,后端没有对验证码和请求频率进行限制,从而增加了泄露公民信息的隐患。

修复建议

  1. 验证码采用后端验证的方式。
  2. 接口仅返回必要信息。
  3. 后端限制请求频率,避免大规模的信息泄露。
  4. 验证姓名是否与身份证匹配。

后续

反馈邮件

有关部门很积极地处理了本次事件,目前已经将平台升级,验证码采用后端验证的方式,接口仅返回必要信息。

升级后的平台界面

升级后的接口返回信息