web573
thinkphp 3.2.3sql注入漏洞 源代码
class IndexController extends Controller {
public function index(){
$a=M('xxx');
$id=I('GET.id');
$b=$a->find($id);
var_dump($b);
}
}
来调试一下看为什么普通的注入不行。本地sql表内数据如下。  传入?id=1' 首先在I函数里面有个过滤,调用think_filter函数   但是没什么影响,就算匹配到了最多加个空格。 跟进find函数,在find函数中_parseOptions 对$options 进行了处理,继续跟进 
_parseType 对$options 进行了处理,跟进  可以看到如果我们的数据库中的id是int型会进入intval函数,会直接去掉其他字符达到过滤的效果,如果id的类型是char则会接着往下走。  执行完_parseType 后回到find 中的select  跟进buildSelectSql  跟进parseSql 
我们知道我们的id的值在$options[‘where’]中,跟进parseWhere  最终是进到了parseValue  在parseValue中中我们看到了具体的转义函数   也就是通过addslashes()函数进行转义
addslashes() 函数会在预定义字符之前添加反斜杠的字符串。
预定义字符是:
单引号(')
双引号(")
反斜杠(\)
NULL
那么假设我们传入的内容是数组呢?id[where]=1' 当我们传入的是数组时,不会进入下面的if中,所以$options['where']="1'" ,否则的话就是 $options['where']['id']="1'"
 按照刚才的方式往下走到_parseOptions ,如果我们的$options['where'] 是数组的话会进入_parseType ,我们前面说到,现在的$options['where']="1'" 是个字符串,也就不会进入这个if,所以当目标数据库中的id字段是int型时可以绕过intval过滤。  接着往后走,直接在parsewhere中进入if$whereStr = $where; 最终返回的内容是WHERE 1'   最终执行的sql语句是select * from xxx where 1' limit 1 这样我们的单引号就保留了下来。  剩下的就很简单了。 payload:?id[where]=id=0 union select 1,flag4s,3,4 from flags 前面的跑表名和列名就不具体写了。
|