|
2017年,意思安全研究员Orange Tsai在Black Hat大会上演示了一个漏洞:他在某知名厂商的意思服务器上,通过一个精心构造的意思HTTP请求,让远端服务器乖乖执行了他上传的意思代码。整个过程不到几分钟,意思一台本应固若金汤的意思机器就变成了他的“肉鸡”。这个漏洞的意思类型,就是意思RCE。 RCE,意思全称Remote Code Execution,意思远程代码执行。意思说白了就是意思:攻击者能在你的机器上跑他自己的代码。这跟普通漏洞有本质区别——SQL注入是意思偷数据,XSS是意思劫持用户浏览器,而RCE是意思直接拿下服务器。权限够高的话,读文件、装后门、横向渗透内网,想干什么干什么。 为什么RCE是漏洞里的“王炸” CVSS评分体系里,RCE几乎永远站在9.0以上的位置。不是没有原因的。一个网站被SQL注入,你丢的可能只是数据库里的用户信息;被RCE,整台服务器的控制权都没了。更关键的是,服务器往往不是孤岛——它连着内网、挂着数据库、存着密钥。攻下一台,等于拿到一把打开整个网络的钥匙。 我印象很深的一个案例是Struts2。这个Java框架在国内政企系统里用得极广,从2013年到2017年连续爆出多个RCE漏洞(S2-016、S2-032、S2-045……)。最夸张的时候,一个HTTP请求头里的Content-Type字段就能触发命令执行。POC公开后,全网扫描器几乎同时开动,大量未及时打补丁的系统在几小时内就被植入了挖矿程序。这种速度,其他类型的漏洞做不到。 RCE是怎么发生的 根子上就一句话:程序把用户能控制的数据,当成了代码来执行。 拿命令注入举例。一个ping功能,后端写的是 system("ping " + ip)。用户输入 127.0.0.1; cat /etc/passwd,分号一拼接,系统就多跑了一条命令。开发者觉得“我只是拼了个字符串”,但操作系统不这么想——它只认分隔符。 反序列化又是另一条路。Java的ObjectInputStream、PHP的unserialize(),这些机制本意是方便对象传输,但如果反序列化的数据用户可控,攻击者就能构造一条特殊的对象链,在反序列化过程中自动触发命令执行。WebLogic、JBoss这些中间件历史上的RCE,大多走的是这条路。 还有表达式注入。Spring的SpEL、OGNL、EL,这些表达式引擎功能强大,能调方法、能反射。一旦用户输入被拼进表达式里求值,等于把编程能力交给了攻击者。S2-045就是Content-Type里塞了OGNL表达式,服务器解析时直接执行。 防御没那么多花活 最有效的办法其实很朴素:别把用户输入拼进任何会被执行的地方。命令执行用参数化API,别用字符串拼接。反序列化做白名单校验,或者干脆换成JSON这类纯数据格式。表达式引擎关掉不必要的功能,输入做严格过滤。 但现实是,遗留系统太多,框架版本太老,补丁打不过来。RCE漏洞不会消失,只会换个地方冒出来。对开发来说,每次写下 eval()、exec()、unserialize() 的时候,都该问自己一句:这个输入,我能100%控制住吗? 答不上来,就别写。 |