zoukankan      html  css  js  c++  java
  • Thinkphp 3.2.3 parseWhere设计缺陷导致update/delete注入 分析

    分析

    首先看一下控制器,功能是根据用户传来的id,修改对应用户的密码。

    13行把用户传来的id参数送入where()作为SQL语句中的WHERE语句,将pwd参数送入save()作为UPDATE语句。
    这里我们假设请求id参数为array("bind","aaa"),pwd参数为bbb。

    其中11行12行的意思是获取id、pwd参数,并通过I函数进行过滤。我们跟进一下I()

    可以看到,这里首先对参数进行htmlspecialchars过滤,然后在最后调用think_filter()函数进行过滤,跟进一下这个函数

    可以看到,这里通过匹配参数中的一些关键字,并在其后加上空格。
    到这里I函数就结束了。

    回到控制器继续往下走,首先进入where()

    可以看到由于$where是数组、$parser是null,所以三个if都不满足,直接到1813行,接下来就是将$this->options['where']与$where拼接到一起,用于最终拼凑成一条完整的SQL语句。

    继续跟进就到save函数了。

    由于$data非空,到409行。这里主要对比$data与数据库中的表中的各个字段的数据类型是否一致,如果不一致则会进行一些强制转换或是直接报错【TODO】。
    然后到416行调用了_parseOptions(),这里用于解析出表名、where中的字段名等【TODO】。

    下面直接跳到最后,调用update函数准备执行SQL语句

    跟进update,直接进入899行

    跟进parseWhere

    其中在536行调用了parseWhereItem,跟进

    可以看到,这里直接拼接了$key和$val[1]到$whereStr中

    最后可以看到,$whereStr="`id` = :aaa",其中aaa就是我们一开始传入的id=array('bind', 'aaa')数组中的第二项。由于后来直接被拼接到SQL语句中,因此这个里存在注入。

    http://127.0.0.1/thinkphp/thinkphp_3.2.3_full/index.php/home/index/sqli1?id[0]=bind&id[1]=0%20and%20(updatexml(1,concat(0x7e,user(),0x7e),1))&pwd=bbb
    

    总结

    本质原因是框架处理pdo时,将用户可控的字符串作为了占位符,导致sql注入在预处理之前就已经形成了,而所谓的过滤bind只是治标不治本而已(没做过开发,也有可能这本来就是一种写法?)。也有可能就是本来入口也就不多吧【TODO】。

    哎,好菜。
    01点46分

  • 相关阅读:
    mongodb 创建auto increment 自增函数
    QT通过IP地址定位地址(用get方法取数据)
    VC程序快速删除自己(可能做升级程序的时候有用)
    让程序出现在控制面板(写注册表)
    亲测VS2010纯静态编译QT4.8.0,实现VS2010编译调试Qt程序,QtCreator静态发布程序(图文并茂,非常详细) good
    Qt configure 参数不完全说明
    C语言和C++篇
    C#开源实现MJPEG流传输
    前端EASYUI的简化调用
    .NET Mvc Razor
  • 原文地址:https://www.cnblogs.com/litlife/p/11273647.html
Copyright © 2011-2022 走看看