```html SOA黑客入口:那些被遗忘的客入口接口 SOA黑客入口 2019年,某省级政务云平台做了一次内部红队测试。客入口攻击队没碰Web前端,客入口也没去爆破VPN。客入口他们翻出一份五年前的客入口SOA服务治理文档,找到一个叫UserAuthService的客入口接口,WSDL里写着checkPrivilege方法接受任意字符串作为sessionId。客入口试了三次,客入口返回true。客入口整个平台的客入口管理员权限到手。这个接口从来没被下线,客入口因为没人记得它还在跑。客入口 SOA架构的客入口核心思路是把业务拆成可复用的服务,通过ESB或者注册中心互相调用。客入口听起来很干净。客入口但实际部署里,服务边界一塌糊涂。开发为了赶进度,把内部调试接口直接暴露在注册中心,权限校验写个if (env == "prod")就完事。注册中心本身呢?很多团队用Zookeeper或者Nacos,默认无认证,或者认证信息硬编码在配置文件里,配置文件又跟着代码进了Git仓库。 spring.cloud.nacos.discovery.server-addr=10.0.12.33:8848 spring.cloud.nacos.discovery.username=nacos spring.cloud.nacos.discovery.password=nacos 你拿到注册中心权限之后能干什么?列出所有服务,看到每个服务的IP和端口,然后直接调用。很多服务之间的信任模型是“内网即安全”。服务A调服务B,B根本不验证A的身份,只看请求里带没带X-Internal-Call: true。这个头是网关加的,但网关只对来自外部的请求做校验。你在内网直接发请求,自己加上这个头,B就信了。 更隐蔽的入口在SOAP头里。WS-Security是个好东西,但实现起来经常出岔子。我见过一个系统,UsernameToken的密码摘要用了MD5,而且没加nonce。这意味着重放攻击完全可行。抓一个合法请求,把时间戳改到未来,密码摘要不变,服务端照样放行。为什么?因为代码里校验时间戳的逻辑写错了,比较的是字符串而不是时间对象。 个人观察:很多SOA安全事件的根本原因不是加密算法被破解,而是开发者对“服务”这个概念的理解有偏差。他们觉得服务是内部用的,不用像对外接口那么严格。但攻击者一旦进入内网——通过钓鱼、通过暴露的Redis、通过一个没打补丁的Jenkins——这些“内部服务”就成了没有锁的门。 还有个经典问题:WSDL泄露。很多SOA服务自动生成WSDL,放在/services/UserService?wsdl这种路径下。如果没做访问控制,任何人拿到WSDL就能生成客户端代码,直接调用。WSDL里还会暴露方法名、参数类型、甚至一些注释。我见过一个WSDL注释里写着// TODO: remove debug backdoor before release。那个backdoor方法叫resetAdminPassword,参数是String newPassword。没删。 ESB本身也是攻击面。很多企业用IBM Integration Bus或者Mule ESB,管理控制台默认端口不对外,但内部人员可以访问。控制台里能看消息流、能改路由规则、能部署新的服务。如果你能访问ESB控制台,你就能把发往/payment的请求重定向到你自己搭的假服务上。中间人攻击在SOA层比在网络层容易得多,因为服务之间本来就不怎么验证对方。 防御?别指望WAF。WAF看不懂SOAP,更看不懂那些藏在XML里的XPath注入。真正的办法是:把SOA服务当成外部API来对待。每个服务都要认证,每个调用都要鉴权,注册中心要加ACL,WSDL要下线或者至少加认证。还有,定期扫一遍注册中心,看看有没有叫test、debug、internal的服务还在跑。大概率有。 最后说个真事。某银行SOA治理团队花了半年做服务梳理,最后发现注册中心里有237个服务,其中41个没有负责人,19个连代码仓库都找不到了。这19个服务还在接收请求,还在返回数据。没人知道它们做什么,也没人敢关。这就是SOA黑客入口最讽刺的地方——入口一直都在,只是没人愿意承认它开着。 ``` |