CTF比赛中发现PHP远程代码执行0day漏洞

2019年10月25日00:03:37 发表评论

CTF比赛都是人为构造漏洞环境,人为制造安全漏洞,供安全从爱好者研究,好磨练和增强自己的安全技能。

CTF比赛中发现PHP远程代码执行0day漏洞

但是,就像所有的游戏一样,在一些未知的地方,总是存在BUG。有时候参赛人员出人意料的行为和动作,会接触到一些从未有人探索过的领域0day。

意外发现的PHP 0day 漏洞

我们的故事开始于Realworld CTF比赛,时间为2019年9月14日到9月16日。Wallarm的安全研究员Andrew Danau在攻克一个CTF任务时偶然发现了一个不寻常的PHP交互行为。

当Andrew Danau往URL中插入了%0a(换行)字符,然后发送给服务器,但服务器的响应很奇怪,它返回的数据比料想的要多,并且这些额外的数据与URL中%0a之后的字节数有关。

通常来说,这种异常响应与内存损坏有关,这应该是一种信息泄露攻击。这说明它可能会导致敏感数据的泄露。更糟糕的是,尽管没有直接出现,但这种异常行为可能隐藏着远程代码执行。

Andrew没有找到解决这个CTF关卡的方法。他决定和队友就这一不同寻常的发现进行深入研究,希望能够理解其中的缘由,开发成一个远程代码执行漏洞。

这个异常的原因是关于Nginx+fastcgi的底层,特别是fastcgi_split_path指令以及涉及换行符的正则表达式的特点。对于%0a字符,Nginx会将其设为一个空值,但fastcgi+PHP不期望这样。

由于Emil对哈希表使用了一些“黑魔法”,所以可以放置任意FastCGI变量,比如PHP_VALUE。我强烈建议你通过学习Emil的脚本来了解更多,利用脚本链接:https://github.com/neex/phuip-fpizdam/。

如果你想了解源码,链接在这:

https://github.com/php/php-src/blob/master/sapi/fpm/fpm/fpm_main.c#L1142

以上一切意味着你可以调用任意的PHP代码——在本例中,通过使用Nginx配置文件中的fastcgi_split_path指令来处理任何用户的数据,比如URL。

在进一步的调查中,我们在GitHub上发现有大量代码涉及fastcgi_split_path(超过6千):

https://github.com/search?q=fastcgi_split_path&type=Code

防御方法

在得知Andrew的发现后,我们立刻据此测试了一些安全解决方案,如Wallarm Cloud Native WAF,并确认Wallarm的WAF能拦截这个漏洞。

而我们在后续研究中也发现可以通过一些简单的方法拦截攻击,比如你正在使用ModSecurity安全软件,那么就可以通过过滤URL中的%0a/%0d来防御这种攻击,相关的mod_security规则如下:

  1. SecRule REQUEST_URI "@rx %0(a|d)" "id:1,phase:1,t:lowercase,deny"

此外我们还建议你通过执行以下简单的bash命令来识别是否可能存在漏洞,它可以识别在你的Nginx配置中是否有错误配置:

  1. egrep -Rin --color 'fastcgi_split_path' /etc/nginx/

最后,在PHP发布相关补丁时,要及时安装。

结论

有时候,思考偏离轨道并不是坏事,Andrew Danau无意中为安全做出了大贡献。我们也相信PHP的开发团队能迅速修复该漏洞。

发表评论

后发表评论