一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权( 三 )

我们构造恰当的 EL 表达式(注意各种转义,下文的输入参数相对比较明显在做什么了,实际上还有更多黑科技,比如各种二进制转义编码啊等等),就能直接执行输入代码,例如:可以直接执行命令,“ls -al”,返回了一个 UNIXProcess 实例,命令已经被执行过了 。

一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权

文章插图
 
比如,我们执行个打开计算器的命令,搞个计算器玩玩~
一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权

文章插图
 
我录制了一个动图,来个演示可能更生动一些 。
一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权

文章插图
 
这还得了吗?这相当于提供了一个 webshell 的功能呀,你看想运行啥命令就能运行啥命令,例如 ping 本人博客地址(ping www.tanglei.name),下面动图演示一下整个过程(从运行 ping 到 kill ping) 。
一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权

文章插图
 
岂不是直接创建一个用户,然后远程登录就可以了 。后果很严重啊,别人想干嘛就干嘛了 。
我们跟踪下对应的代码,看看内部实现,就会“恍然大悟”了 。
一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权

文章插图
 

一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权

文章插图
 
经验教训幸亏这个漏洞被扼杀在摇篮里,否则后果还真的挺严重的 。通过这个案例,我们有啥经验和教训呢?那就是作为程序员,我们要对每一行代码都保持“敬畏”之心 。也许就是因为你的不经意的一行代码就带来了严重的安全漏洞,要是不小心被坏人利用,轻则……重则……(自己想象吧)
此外,我们也应该看到,程序员需要对常见的安全漏洞(例如XSS/CSRF/SQL注入等等)有所了解,并且要有足够的安全意识(其实有时候研究一些安全问题还挺好玩的) 。例如:
  • 用户权限分离:运行程序的用户不应该用 root,例如新建一个“web”或者“www”之类的用户,并设置该用户的权限,比如不能有可执行 xx 的权限之类的 。本文 case,如果权限进行了分离(遵循最小权限原则),应该也不会这么严重 。(本文就刚好是因为是测试环境,所以没有强制实施)
  • 任何时候都不要相信用户的输入,必须对用户输入的进行校验和过滤,又特别是针对公网上的应用 。
  • 敏感信息加密保存 。退一万步讲,假设攻击者攻入了你的服务器,如果这个时候,你的数据库账户信息等配置都直接明文保存在服务器中 。那数据库也被拖走了 。
如果可能的话,需要对开发者的代码进行漏洞扫描 。一些常见的安全漏洞现在应该是有现成的工具支持的 。另外,让专业的人做专业的事情,例如要有安全团队,可能你会说你们公司没有不也活的好好的,哈哈,只不过可能还没有被坏人盯上而已,坏人也会考虑到他们的成本和预期收益的,当然这就更加对我们开发者提高了要求 。一些敏感权限尽量控制在少部分人手中,配合相应的流程来支撑(不得不说,大公司繁琐的流程还是有一定道理的) 。
毕竟我不是专业研究Web安全的,以上说的可能也不一定对,如果你有不同意见或者更好的建议欢迎留言参与讨论 。




推荐阅读