$this->show 造成命令执行
在 Home\Controller\IndexController
下的index中传入了一个可控参数,跟进调试看一下。
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: 24px 48px;"> <h1>:)</h1><p>欢迎使用 <b>ThinkPHP</b>!</p><br/>版本 V{$Think.version}</div><script type="text/javascript" src="http://ad.topthink.com/Public/static/client.js"></script><thinkad id="ad_55e75dfae343f5a1"></thinkad><script type="text/javascript" src="http://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script></p>Hello '.$n, 'utf-8');
}
}
跟进 display()
protected function show($content,$charset='',$contentType='',$prefix='') {
$this->view->display('',$charset,$contentType,$content,$prefix);
}
一路跟进到 fetch()
,然后一路进入 Hook::listen('view_parse', $params);
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;
}
关键地方在这,我们之前 index
里的内容被存入了缓存文件php文件中,连带着我们输入的可控的php代码也在其中,然后包含了该文件,所以造成了命令执行。
public function load($_filename,$vars=null){
if(!is_null($vars)){
extract($vars, EXTR_OVERWRITE);
}
include $_filename;
}
sql注入
/Application/Home/Controller/IndexController.class.php
添加一段SQL查询代码。http://localhost/tp323/index.php/Home/Index/sql?id=1
查询入口。
public function sql()
{
$id = I('GET.id');
$user = M('user');
$data = $user->find($id);
var_dump($data);
}
传入 id=1 and updatexml(1,concat(0x7e,user(),0x7e),1)--+
,跟进调试。进入 find()
函数,先进行一段判断,传入的参数是否是数字或者字符串,满足条件的话 $options['where']['id']=input
。
if(is_numeric($options) || is_string($options)) {
$where[ $this->getPk()] = $options;
$options = array();
$options['where'] = $where;
}
随后进行一个判断 if (is_array($options) && (count($options) > 0) && is_array($pk))
,getPk()
函数是查找mysql主键的函数,显然 $pk
值是 id
,不满足条件文章来源:https://www.toymoban.com/news/detail-531561.html
$pk = $this->getPk(); // $pk='id'
if (is_array($options) && (count($options) > 0) && is_array($pk)) {
//
}
随后执行 $options = $this->_parseOptions($options);
,文章来源地址https://www.toymoban.com/news/detail-531561.html
protected function _parseOptions($options=array()) {
if (is_array($options)) {
$options = array_merge( $this->options, $options);
}
if (!isset($options['table'])) {
// 自动获取表名
$options['table'] = $this->getTableName();
$fields = $this->fields;
} else {
// 指定数据表 则重新获取字段列表 但不支持类型检测
$fields = $this->getDbFields();
}
// 数据表别名
if (!empty($options['alias'])) {
$options['table'] .= ' '.$options['alias'];
}
// 记录操作的模型名称
$options['model'] = $this->name;
// 字段类型验证
if (isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) {
// 对数组查询条件进行字段类型检查
foreach ($options['where'] as $key=>$val) {
$key = trim($key);
if (in_array($key, $fields, true)) {
if (is_scalar($val)) {
$this->_parseType($options['where'], $key);
}
} elseif (!is_numeric($key) && '_' != substr($key, 0, 1) && false === strpos($key,
到了这里,关于【安全漏洞】ThinkPHP 3.2.3 漏洞复现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!