问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
某cms的sql注入漏洞分析
漏洞分析
一.前言 某开源商城是基于thinkphp3.2.3,此商城中的sql注入漏洞很多,这篇文章主要举几个比较典型的例子,讲讲对漏洞的分析和自己审计代码时的一些思路。 二.代码审计 0x00.请求过程 ThinkPHP...
一.前言 ==== 某开源商城是基于thinkphp3.2.3,此商城中的sql注入漏洞很多,这篇文章主要举几个比较典型的例子,讲讲对漏洞的分析和自己审计代码时的一些思路。 二.代码审计 ====== 0x00.请求过程 --------- ThinkPHP的控制器是一个类,而操作则是控制器类的一个公共方法。 控制器类的命名方式:控制器名(驼峰命名法)+Controller 控制器文件的命名方式:类名+.class.php(类文件后缀) 首先通过`getController`和`getAction`两个方法定义`CONTROLLER_NAME`和`ACTION_NAME`的值  然后通过`CONTROLLER_NAME`获取当前操作名  然后通过`ACTION_NAME`获取类所在的路径并创建控制器实例  然后通过反射方法`ReflectionMethod`获取这个对象下对应的方法, 并且后续没有进行权限判断,导致所有请求都可以通过未授权访问  最后执行对应的应用程序  0x01.sql注入漏洞1 ------------- 在`Modules/Home/Controller/ApiuserController.class.php`文件中的`group_info`方法  $order\_id通过get请求传入,接着直接拼接进sql语句中,由于没有对参数进行过滤,并且没有对传入的`token`参数进行校验,直接拼接sql语句进行未授权执行。 ### 漏洞复现: payload: [http://127.0.0.1/index.php?s=/Apiuser/group\\\_info&order\\\_id=1%20and%20updatexml(1,concat(0x7e,database(),0x7e),1](http://127.0.0.1/index.php?s=/Apiuser/group%5C_info&order%5C_id=1%20and%20updatexml(1,concat(0x7e,database(),0x7e),1))  0x02.sql注入漏洞2 ------------- 在`Modules/Home/Controller/VipcardController.class.php`文件中的`get_vipgoods_list`方法  order\_id通过get请求传入,然后拼接到where语句中,由于是字符串,`$this->options['where']`的键就是`_string`  所以导致**不会**进入到下面的if判断语句中,`_parseType`方法用来检测传入的类型,由于传入的字符串类型,所以也就不会去判断是否符合字段数据类型  最终拼接成sql语句进行执行  还有注意一点的是,非array传出的参数会被添加(),所以有时候无法闭合的时候可以尝试添加括号看看 ### 漏洞复现 payload: [http://127.0.0.1/index.php?s=Vipcard/get\\\_vipgoods\\\_list&gid=1](http://127.0.0.1/index.php?s=Vipcard/get%5C_vipgoods%5C_list&gid=1) and updatexml(1,concat(0x7e,database(),0x7e),1)  0x03.sql注入漏洞3 ------------- 在`Modules/Home/Controller/ApiuserController.class.php`中的set\_default\_address方法  然后跟进`where`和`save`方法,然后在save方法中跟进`_parseOptions`方法  在`_parseOptions`方法中,由于这里`$val`是一个数组,所以`is_scalar`判断不是标量,也就不会进入`_parseType`方法用来检测传入的类型  在where子单元分析函数`parseWhereItem`中,`$exp`去了array中的第一个值bind,然后在下面的判断语句中拼接`$whereStr`  最后形成下面的sql语句,但此时的sql语句中任存在`:0`  在`execute`中,是将`:0`替换为外部传进来的字符串,所以我们让我们的参数也等于0,这样就拼接了一个`:0`,然后会通过`strtr()`被替换为1  ### 漏洞复现 payload: [http://127.0.0.1/index.php?s=Apiuser/set\\\_default\\\_address&id\\\[0\\\]=bind&id\\\[1\\\]=0%20and%20(updatexml(1,concat(0x7e,user(),0x7e),1](http://127.0.0.1/index.php?s=Apiuser/set%5C_default%5C_address&id%5C%5B0%5C%5D=bind&id%5C%5B1%5C%5D=0%20and%20(updatexml(1,concat(0x7e,user(),0x7e),1)))  三.tp框架下SQL注入漏洞挖掘思路总结 ==================== tp框架采用MVC架构,即`模型`(Model),`视图`(View),`控制器`(Controller)。他们大致的运行流程是用户与应用程序交互,向`控制器`发送请求,然后`控制器`收到请求分析用户请求,并调用响应的`模型`操作,`模型`操作访问数据库或其他数据源,对数据进行处理并返回给`控制器`,`控制器`接受模型返回的数据,并传递给`视图`,最后`视图`将数据呈现给用户。 在MVC架构下对于挖掘sql注入漏洞应该首先关注其模型,因为他是与数据库交互的地方,如果我们能发现其过滤不严导致直接将用户数据带入数据库中执行从而造成sql注入。 ### 1.使用`QUERY`方法对原生的SQL查询和执行操作 示例代码: $gid \\= $\_GPC\['gid'\]; $sql \\= "select xxx from xxx where gid='$id';" $result \\= M()->query($sql); 这种写法如果不对传入的gid变量加以过滤,很容易造成sql注入。 我们可以通过正则`M\(.*?\)->query\(.+?\)`搜索代码中使用query方法的代码,然后查看传入的参数是否可控.  2.使用字符串作为查询条件 ------------- 示例代码: $gid \\= $\_GPC\['gid'\]; $resultt \\= M('xxx')->where( "pid = {$gid}" )->select(); 我们可以通过正则`M\(.*?\)->where\(((?!array).)*\)`搜索代码中使用where方法且不是通过array传参的代码,然后查看传入的参数是否可控.  3.使用数组作为查询条件 ------------ 示例代码: $gid \\= $\_GPC\['gid'\]; $resultt \\= M('xxx')->where( array('gid' \\=> $gid) )->save(); 当使用数据进行传参情况就不一样了 如果传参是通过array的话,**会**进入到下面的if判断语句中,会对传入值的类型进行判断,若判断为int类型,参数将直接传唤为int类型将丢失后面的payload,   就算传入的类型可以为字符型也还会对传入的参数关键字符进行转义 所以这里我们只能另辟蹊径,只能通过tp3.2.3框架的几个sql注入漏洞来利用 例如这里我们可以使用tp3.2.3框架的bind注入,漏洞所在的地方一般都需要update的操作 我们可以通过正则`M\(.*?\)->where\(.+?\).>save\(.+?\)`搜索代码中使用where方法且不是通过array传参的代码,然后查看传入的参数是否可控.  另外tp3.2.3中还可以通过exp注入,原理和上面的bind注入差不多,但其条件参数必须是通过全局数组传参,而不是`I()`函数,因为`I()`函数会调用`think_filter()`函数,其中过滤了`exp`。在这一套cms中所有参数都是通过`I()`函数传参的,所以无法使用exp注入。
发表于 2023-05-30 09:00:00
阅读 ( 6549 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
中铁13层打工人
79 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!