WordPress Gravity Forms是由国外著名高手开发的一个表单插件,对于想给自己WordPress站点添加订购表格的站长来说,带来很大的方便。Gravity Forms可以支持分页表单,让定义有步骤的进行;定义限期表单,可以设置在某段时间才能够提交表单等功能。本文漏洞分析所面向的对象就是Gravity Forms插件。

QQ截图20150302141313

漏洞发现

在定期清理过程中,我们遇到了一个再感染事例,这引起了我们的注意。在这个特定的环境中,并没有什么特殊的东西,只有1个WordPress的安装更新和3个过时的插件,这就相当合理了,可能漏洞就存在于这些插件中。在清除工作结束之后,竟然再一次地受到了感染,攻击者不停地向服务器上传恶意文件。

1

在2月21日,恶意文件被上传到了目录“wp-content /uploads/ gravity_forms”和“wp-content /uploads”中,但是攻击者如何做到的呢?

幸运的是,我们找到了访问日志,发现了一些对特定文件的有趣请求。鉴于此,我们开始寻找“_input_”的不同变量,并发现很多针对这些文件的请求:

2

我们在日志中查找了几天前的记录,以期找到这些请求之前的内容以及这些内容的来源。

3

漏洞分析及测试

通过分析这些文件,我们发现一些针对“?gf_page=upload”的请求。然后,我们尝试在文件系统中搜索该字符串,并在WordPress插件GravityForms(过时版本1.8.19)中发现一个实例。

经过进一步调查,我们发现”?gf_page =upload“存在于common.php文件的第3635行。

4

有趣的是,针对该请求并没有进行安全处理。出于测试目的,我发送了一个请求“?gf_page =upload”看看会发生什么,有趣的是,我们得到下图所示内容:

5

然后,我们搜索处理该消息的地方。

6

通过检查upload.php文件,我们发现必须设置$_REQUEST[“form_id”],不然上传就会失败。不过,此时我们已经绕过了任何阻止未授权用户访问资源的保护机制。

然后,我将form_id的值设置为1,然后发起了另一个精心制作的请求,这次的错误看起来有点不同。

7

接着,我试着发送一个test.php,然后触发了一个函数file_name_has_disallowed_extension(),此函数阻止了该文件的上传。通过在common.php文件中检查这些函数的声明,我们明白了为什么会阻止该文件上传。

在get_disallowed_file_extensions()函数中含有一个包含允许扩展名的列表,函数file_name_has_disallowed_extension()检测了我所上传的文件,因为扩展名“php”在禁止列表之中,所以才导致上传失败。

8

这基本上意味着我们不能上传.php文件了是吗?其实,答案是否,接下来让我们看看为什么会这样。

在“includes/upload.php”中可看到,我们完全可以控制上传文件的文件名,还可以控制文件在服务器上如何存储。54和55行的代码使我们可以通过简单的HTTP请求就能做到这些。

同时,我们可以看到如果$field为空,执行将会在59和60行处停止。所以我们将field_id设置为1。(安全脉搏 www.secpulse.com)

9

将test.php名字改为test.jpg之后,我们得到了一个有趣的响应。

10

文件成功上传到了服务器,但名字却变成了“_input_1_”,下面的代码告诉我们“_input_1_”临时文件名是如何创建的:

11

分解之后,我们得到了下面的内容:

$form_unique_id	= We didn't set any value here
_input_			= Hardcoded
$field_id		= We set that 1 as mentioned above
_				= Harcoded
$file_name		= We control this data, therefore we can set .php here

到这里,$tmp_file_name创建成功。

12

结论

这是一个非常危险的漏洞,你需要尽快更新你所有使用该插件的网站。不过,从GravityForms更新日志中,我们发现在1.8.20版本中已经修复了此漏洞。然而,1.8.19以及更早版本将会受到该漏洞的影响。

【原文:malware-cleanup-to-arbitrary-file-upload-in-gravity-forms   安全脉搏PulseO0O整理发布】

源链接

Hacking more

...