HacKerQWQ的博客空间

TP5SQL注入漏洞分析(5.0.13-5.0.15,5.1.0-5.1.5)

Word count: 535Reading time: 2 min
2021/06/25 Share

参考学习链接

配置环境

  • 下载源码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #composer 选择特定分支
    composer create-project --prefer-dist topthink/think=5.0.15 tpdemo
    或者
    #从github下载整个库,然后选择分支
    cd D:\phpStudy\WWW
    git clone https://github.com/top-think/think tp5
    git checkout v5.0.22
    cd tp5
    git clone https://github.com/top-think/framework thinkphp
    git checkout v5.0.22

    这里采用composer

  • composer设置framework版本

    1
    2
    3
    4
    "require": {
    "php": ">=5.4.0",
    "topthink/framework": "5.0.15"
    }

    composer update更新framework

  • 将如下代码写入application/index/controller/Index.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    namespace app\index\controller;

    class Index
    {
    public function index()
    {
    $username = request()->get('username/a');
    db('users')->insert(['username' => $username]);
    return 'Update success';
    }
    }
  • 数据库导入
    application\database.php中配置数据库信息,然后在application\config中开启app_debugapp_trace,并创建如下数据库

    1
    2
    3
    4
    5
    6
    create database tpdemo;
    use tpdemo;
    create table users(
    id int primary key auto_increment,
    username varchar(50) not null
    );

payload

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

20210625145533

漏洞分析

20210625145857
username变量通过/a修饰符识别为array数组,传给$username变量,db('user')表示选择表user进行insert操作,接下来跟进到Query类的insert函数

20210625150210

parseExpress获取options的选项,此处options[data]为空,因此array_merge之后$data不变,$data的值如下
20210625150930
然后跟进到builderinsert方法
20210625151314
这里调用了parsedata方法,传入dataoptions,跟进,以下是关键代码
20210625151548
此时$val[0]是inc,$val[1]是updatexml(1,concat(0x7,user(),0x7e),1),$val[2]是1,经过函数parseKey拼接成sql语句
20210625151949
然后一路返回到Query处执行sql语句造成报错注入,通过debug模式回显结果
20210625152204
20210625145533

总结

tp5sql链

修复

官方在v5.0.16进行安全更新
20210625152604
没有对exp做过滤是因为在thinkphp/library/think/Request.php中设置了函数对传入的指定数据加了空格,从而进不到switch那个exp的分支
20210625162222

CATALOG
  1. 1. 简介
  2. 2. 配置环境
  3. 3. payload
  4. 4. 漏洞分析
  5. 5. 总结
  6. 6. 修复