前言

之前在t00ls上看到一位大佬随手发了某源码的一个sql注入,前几周有拿到了这个源码就按照他发的漏洞把漏洞代码跟了下,同时自己也审了个比较鸡肋的RCE,把审计过程记录了下。

1.sql注入

根据习惯先看代码最原始db目录下的数据库类操作文件,其中有个arr2sql()函数用于将数组转换为sql语句存在问题,如下所示:

private function arr2sql($arr) {
        $s = '';
        foreach($arr as $k=>$v) {
            $v = addslashes($v);
            $s .= "$k='$v',";
}
        return rtrim($s, ',');
    }

由上数组转成sql语句可以看出,arr2sql()函数只对数组中的value值进行了转义过滤,而没有对相应的key进行转义过滤,直接进行拼接返回。那我们就假设如果传入的数组$arr中相应的键我们在前端可以控制构造相应的payload即可造成sql注入。

​ 首先我们全局搜索那些地方调用了arr2sql()这个方法,找到两处函数调用了该方法如下所示:

执行插入操作的函数:

public function set($key, $data) {
        if(!is_array($data)) return FALSE;

        list($table, $keyarr) = $this->key2arr($key);
        $data += $keyarr;
        $s = $this->arr2sql($data);

        $exists = $this->get($key);
        if(empty($exists)) {
            return $this->query("INSERT INTO {$this->tablepre}$table SET $s", $this->wlink);
        } else {
            return $this->update($key, $data);
        }
    }

第二处跟新操作的函数:

public function update($key, $data) {
        list($table, $keyarr, $keystr) = $this->key2arr($key);
        $s = $this->arr2sql($data);
        return $this->query("UPDATE {$this->tablepre}$table SET $s WHERE $keystr LIMIT 1", $this->wlink);
    }

由上述函数可知$s经过arr2sql()处理后直接返回凭借执行sql语句。

​ 选一处进行分析数据流分析,全局搜索update()函数查找调用该函数的方法且传入数组中的键可控,找到如下方法:

public function ajaxset(){
点击收藏 | 2 关注 | 2
登录 后跟帖