一个攻击者不需要直接触碰目标系统,基于击方只需要不停向它提问,查询就能摸清它的基于击方底细。这听起来像魔术,查询其实是基于击方基于查询的攻击——本质上是把系统当作一个黑箱,通过观察输入输出关系来逆向工程。查询你问它问题,基于击方它回答,查询答案里就藏着秘密。基于击方
最经典的查询例子是SQL注入。攻击者向登录框输入一段精心构造的基于击方字符串,比如' OR '1'='1,查询数据库就会老实回答“这用户存在”。基于击方更狠的查询是盲注——页面根本不显示任何错误信息,攻击者就问“第一个字符是基于击方不是a?”如果页面正常返回,说明是;如果报错,说明不是。一个字符一个字符地猜,像在玩二十个问题,但机器不会烦。这种攻击在2000年代初横扫互联网,如今仍存在于大量老旧系统中。
另一种更隐蔽的形式是时序攻击。系统处理不同输入时,耗时会有细微差别。攻击者测量这些毫秒级差异,就能推断出内部状态。比如比较密码时,如果程序逐字符比对,遇到不匹配就提前退出,那么攻击者可以发送一个以“a”开头的密码,再发送以“b”开头的,测量哪个响应更慢。更慢的那个说明第一个字符猜对了——因为程序继续检查了第二个字符。我见过一个真实案例:某银行API的令牌校验存在这种漏洞,攻击者通过数千次请求,硬是把一个128位的随机令牌给逐位猜了出来。听起来不可思议,但时间戳的噪声可以用大量重复请求来平均掉。
还有一类查询攻击干脆不碰具体数据,专打缓存。比如缓存侧信道攻击,攻击者和目标共享同一台物理服务器(常见于云计算环境)。攻击者不断查询某个特定内存地址,观察自己的请求是命中缓存还是未命中——如果命中,说明目标刚刚访问过这里。通过反复试探,就能重建目标的访问模式。著名的Spectre和Meltdown漏洞就是这么干的,只不过它们把查询目标从内存地址换成了CPU的预测执行单元。这类攻击最阴险的地方在于,它们不依赖任何软件漏洞,纯粹利用硬件设计上的性能优化。
说到底,查询攻击的核心逻辑很简单:信息不会凭空消失,它只是换了一种形式存在。系统每一次响应,无论多么简短,都在泄露些什么。防御者的任务是确保这些泄露的信息足够碎片化,让攻击者拼不出全貌——但这很难,因为攻击者有的是耐心。他们可以发一亿次查询,而每一次查询的成本几乎为零。
我曾在一次渗透测试中模拟过类似手法。目标是个内部API,返回JSON里有个冗余字段,显示的是服务器处理时间。我写了个脚本,每分钟发几百个请求,统计不同参数组合的响应时间分布。结果发现,当某个特定参数存在时,平均响应时间会高出约3毫秒——这说明后端在调用一个更慢的加密函数。就凭这点差异,我定位到了他们用的具体加密库,然后查到了该库已知的弱点。整个过程中,我没有触发任何告警,因为我的请求量看起来就像普通用户流量。
所以别以为系统“看起来正常”就安全了。攻击者不需要攻破防火墙,不需要上传恶意文件,只需要坐在那里,像个体面的用户一样,不停地问问题。