DocCms最新版SQL注入(insert注入技巧)

首先大致说下这个SQL是如何产生的,看到 WooYun: DocCms最新版sql注入漏洞 ,它利用url编码绕过过滤进行了注入,就有了点点想法,会不会还有其他编码绕过过滤的问题?

开始

Doccms中首先对输入进行了全局过滤,但是后面为了过滤XSS,又对经过全局过滤的用户输入进行了html解码,因此,可以通过编码绕过过滤进行注入。

Doccms在/loader/doc.php对输入的内容进行了全局的过滤,如下

 

跟进cleanArrayForMysql看一下,/inc/function.php


 

可以看到对用户的输入调用了mysql_real_escape_string()进行过滤,这个函数把sql的几个特殊字符过滤掉了,特别是’,但是这个函数并不过滤%,后面会用到这个特性。

在用户有输入的地方,doccms对用户的输入进行XSS过滤。比如本次注入的地方,在 联系我们-->招商加盟,点提交时,会调用/content/order/index.php 文件中的create()函数

 

可以看到

 

调用了RemoveXSS()函数,RemoveXSS()内容如下

 

为了更好的过滤XSS,RemoveXSS把用户输入进行了html解码,因而整个流程是这样的:用户输入内容--->mysql_real_escape_string()---->RemoveXSS()---->mysql_query(),也就是说用户输入内容首先被mysql_real_escape_string()过滤掉sql特殊字符,然后RemoveXSS()进行html解码,最后带入执行sql语句。

因此问题就来了,先把SQL特殊字符进行html编码,绕过mysql_real_escape_string(),然后由RemoveXSS()解码还原,然后就可以执行了,注入也就产生了。

这样产生的注入虽然可以引入’,但是由于RemoveXSS()无法使用逗号,这也给注入带来了点点麻烦。不过不用逗号一样可以构造注入语句。

注入不能使用逗号,且注入是在insert处,因此使用case when then 进行注入,可以有效的避开逗号问题。因是在insert的values中构造注入语句,又不能使用逗号,暂时没想到如何使用case when then + “布尔注入” 来注入。本次注入使用case when then + “延迟盲注”进行注入。

以“公司名称:”这个注入点为例进行验证:

单引号可以这样引入

引诱逗号证明副本.jpg

公司名处的注入payload(未编码):or (select case when (select username from (select * from doc_user) as a where id=1) like 'a%' then sleep(3) else sleep(0) end) or '

编码以后的payload为:' or (select case when (select username from (select * from doc_user) as a where id=1) like 'a%' then sleep(3) else sleep(0) end) or '

根据提交成功返回的时间即可判断doc_user中第一个用户的用户名是不是以a开头的,若是返回时间约为3s后,若不是则立即返回提交成功。假若第一个字符是a,测试第二个字符时,固定a不变,修改b的值即可,payload如下:' or (select case when (select username from (select * from doc_user) as a where id=1) like 'ad%' then sleep(3) else sleep(0) end) or '

证明:

结果副本.jpg

解决方案:

过滤