去年秋天,漏洞调查某市政务系统的漏洞调查一次例行巡检里,运维人员发现一台服务器CPU占用率持续在90%以上。漏洞调查查了三天,漏洞调查没找到明显异常进程。漏洞调查第四天,漏洞调查有人在日志里翻出一条不起眼的漏洞调查记录:某个内部接口被调用了两万多次,而正常业务一天最多几百次。漏洞调查顺着这条线摸下去,漏洞调查最终定位到一个刚上线两周的漏洞调查查询功能——它没做权限校验,任何人只要知道参数格式,漏洞调查就能拉走整张用户表。漏洞调查
这就是漏洞调查漏洞。它不总是漏洞调查电影里那种敲几行代码就黑掉卫星的戏剧场面,更多时候,漏洞调查它藏在一次“应该没问题”的偷懒里,或者一句“以前都这么写”的惯性中。
我后来和负责修复的工程师聊过。他说那个接口写起来只花了二十分钟,测试也过了,因为测试用例只覆盖了正常登录后的调用。没人想过“不登录直接调”会怎样。这种盲区很典型:开发盯着功能实现,安全测试盯着已知攻击模式,中间那块灰色地带,往往要等真实流量撞上来才暴露。
漏洞调查这件事,最怕的是只盯着代码看。有次我参与一个电商平台的排查,用户反馈“偶尔会看到别人的订单”。第一反应是越权,查了权限模块,逻辑严密。再查缓存,发现订单列表的缓存键设计有问题——它用用户ID做了哈希,但哈希碰撞概率没控制好,极端情况下两个用户会落到同一个缓存槽。问题不在权限,在数据结构。如果只按“越权漏洞”的模板去套,可能一周都找不到根因。
调查的起点通常是异常。异常可能来自监控告警、用户投诉、甚至安全圈子里有人放出了利用脚本。关键是别急着下结论。我见过一个案例,某App的登录接口被爆存在SQL注入,安全团队连夜修了过滤逻辑。结果第二天攻击者换了个参数名,照样注入成功。原来问题出在框架层的一个自动绑定功能上,修一个接口没用,得改配置。如果第一轮调查只满足于“堵住这个点”,后面还得反复救火。
工具当然有用。静态扫描能翻出不少低级错误,动态测试能模拟攻击路径。但工具的报告往往是一堆“疑似”,需要人去判断哪些是真风险。有次扫描器报了一个“硬编码密钥”,点进去一看,是测试环境用的假密钥,提交记录里写得清清楚楚。这种误报多了,人就会麻木,真漏洞反而被淹没。所以调查流程里,人工复核这一步省不掉。
还有一个容易被忽略的环节:漏洞修完之后。补丁上线了,但旧版本还在某些渠道流通,或者攻击者已经留了后门。某次调查一个WebShell事件,清理了服务器上的恶意文件,以为完事了。两周后同一台机器又出现了新WebShell。回头查,发现第一次入侵时攻击者改了一个很少用的系统服务配置,那个服务会定期从外部拉取脚本执行。只清文件不查配置,等于没修。
说到底,漏洞调查不是找一个人来背锅。它是把“怎么会这样”拆成一个个可验证的假设,然后挨个排除。有时候答案很蠢——比如某次数据库泄露,原因是有个运维图方便,把生产库的只读账号密码设成了和测试库一样,而测试库的密码写在了一个公开的Wiki页面上。这种链条里,每个环节都觉得自己没大错,但串起来就是一个洞。
写这份记录的时候,我又看到一条新闻:某开源组件爆出远程执行漏洞,影响范围极广。评论区照例在吵“谁该负责”。其实调查清楚漏洞怎么进来的、影响哪些版本、怎么确认自己中没中招,比吵架有用得多。毕竟,洞就在那里,不查,它不会自己消失。