PHP反序列化
原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
serialize() //将一个对象转换成一个字符串
unserialize() //将字符串还原成一个对象

演示一把
上代码

改代码中接受以get方式传过来的str参数的值,并且如果该值经过反序列化之后的值如果等于$key(xiaodi)时就输出flag
因此我们要把xiaodi这个字符串先进行序列化一番

序列化的值为 “s:6:“xiaodi”;” #s表示字符串,6表示长度,后面为数据
好了,现在以这个值进行提交:

成功输出flag!
这里提醒一下当对数字序列化时是不会显示长度的

CTF题目

因为点击登录没反应,而有提示htint所以就在Url后面添加hint参数
观察代码发现,有两个坑点:其接收的参数要经过反序列化与key值进行比较,相等则输出flag
第一个坑:提交的时候不能携带hint对象,因为代码中明显显示如果提交hint参数就不会执行反序列化操作
第二个坑:要进行比较的$key值在最下面,这时提交进行比较的$key值因为执行顺序就是个空值
空值的序列化结果为:s:0:"";

因为参数是以cookie方式接收,故要把序列化信息填写到cookie处
经过上述理解,我们抓取数据包,去除hint参数,并把空值的序列化结果填入cookie位置

成功回显flag!

有类的序列化
上面的两个是没有类
参考:https://www.cnblogs.com/20175211lyz/p/11403397.html
__construct()//创建对象时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发
__wakeup() //当执行unserialize()函数时会触发
__toString() //当执行打印输出时自动执行
class ABC{
public $test;
function __construct(){
$test =1;
echo '调用了构造函数<br>';
}
function __destruct(){
echo '调用了析构函数<br>';
}
function __wakeup(){
echo '调用了苏醒函数<br>';
}
}
echo '创建对象a<br>';
$a = new ABC;
echo '序列化<br>';
$a_ser=serialize($a);
echo '反序列化<br>';
$a_unser = unserialize($a_ser);
echo '对象快要死了!';
?>
执行结果

ctf序列化
题目为:

代码:
<?php
include("flag.php");
highlight_file(__FILE__);
class FileHandler {
protected $op;
protected $filename;
protected $content;
function __construct() {
最低0.47元/天 解锁文章

1025

被折叠的 条评论
为什么被折叠?



