凌晨两点,排查漏洞安全团队的排查漏洞值班手机响了。告警信息很简短:某台边缘节点服务器的排查漏洞CPU占用率飙到97%,持续了二十分钟。排查漏洞我爬起来连上VPN,排查漏洞第一反应是排查漏洞挖矿木马——这年头,暴露在公网上的排查漏洞机器十台有八台被人扫过SSH,剩下两台在被人扫MySQL。排查漏洞
登上去一看,排查漏洞进程列表里躺着一个叫kworker的排查漏洞东西,名字伪装得不错,排查漏洞但路径不对。排查漏洞正常的排查漏洞kworker跑在内核态,这个却指向/tmp/.x/下面一个没有扩展名的排查漏洞二进制文件。我把它拖进沙箱跑了一下,排查漏洞行为很典型:先连C2服务器拉指令,然后开始扫内网段,找Redis未授权访问的端口。
漏洞在哪?不是Redis本身。Redis没设密码这件事,运维三个月前就知道,当时觉得“内网嘛,没事”。问题出在一台跳板机上——那台机器开了SOCKS代理,内网任何一台机器都能通过它访问其他网段。攻击者拿下一台边缘节点后,用这台跳板机横向移动,Redis只是顺手牵羊。
排查漏洞这件事,最怕的就是“单点思维”。看到Redis没密码就只修Redis,看到SSH爆破就只换密钥。真正的漏洞往往不在那个报错的组件上,而在它和它邻居之间的连接方式上。我见过一个案例:某公司把所有服务器都打了最新补丁,结果被一个五年前的Tomcat弱口令拿下了。为什么?因为那台Tomcat跑在一个没人管的测试环境里,而测试环境的数据库密码和生产环境一模一样。
说回这次。我顺着代理日志往回查,发现跳板机的SOCKS配置是0.0.0.0/0,意思是任何来源都能用。更离谱的是,这台跳板机的认证方式居然是“用户名+空密码”。运维的解释是“当时测试用的,后来忘了改”。忘了。这两个字在安全事件报告里出现的频率,比“0day”高十倍不止。
修补过程没什么好说的:封代理、改密码、加防火墙规则、把那个二进制文件扔进威胁情报平台。但真正让我在意的是另一件事——这台边缘节点上跑着一个日志采集Agent,它每五分钟往中心上报一次进程列表。而那个伪装成kworker的进程,在进程列表里被标记为“系统进程”,因为Agent的白名单里写了“kworker”这个关键词。攻击者只是把文件名改成kworker,就绕过了监控。
漏洞排查不是拿着扫描器跑一遍就完事。扫描器告诉你“这里有个CVE”,但不会告诉你这个CVE在当前的网络拓扑里能不能被利用、利用之后能走到哪一步、有没有别的路径绕过去。你得自己画攻击路径图,从入口点开始,一个节点一个节点地推。哪条路能走通,哪条路被挡住了,挡住的那条路上有没有侧门。
我习惯在排查完之后做一件事:把整个攻击链写成时间线,从第一个告警到最后一个受影响的服务,标出每一个“本可以拦住”的节点。这次的时间线里,有四个节点本可以拦住攻击者:跳板机的空密码、SOCKS的全局配置、Redis的未授权访问、Agent的白名单绕过。任何一个环节堵住了,攻击者都到不了下一步。但四个环节同时失效,这就是典型的“纵深防御”变成“纵深漏洞”。
写完报告,天已经亮了。我泡了杯茶,顺手把跳板机的密码策略改成强制12位混合字符。运维在群里回了个“收到”,然后问:“那个kworker文件要不要留个样本?”我说留,放沙箱里,别放生产环境。他回了个OK的表情。我知道他大概率会忘,但至少下次告警响的时候,他会先看一眼进程路径,而不是直接点“忽略”。