[SWPUCTF 2022 新生赛]1z_unserialize
分析题目
这段 PHP 代码定义了一个名为 lyh
的类,并在其中定义了一些属性和方法。然后,它使用 unserialize
函数来反序列化从 POST 请求中接收到的数据,并最后使用 highlight_file
函数高亮显示当前文件的源代码。
类定义 (lyh
)
-
属性:
-
$url
: 一个公共属性,被初始化为字符串 'NSSCTF.***'。 -
$lt
: 一个公共属性,没有初始化。 -
$lly
: 一个公共属性,没有初始化。
-
-
方法:
-
__destruct()
: 这是一个析构函数,当对象不再被引用时,它会自动被调用。在这个函数中,它首先从$this->lt
获取一个值,并将其存储在变量$a
中。然后,它尝试将$a
作为函数来调用,并传递$this->lly
作为参数。
-
代码执行流程
-
接收 POST 数据:
unserialize($_POST['nss'])
这行代码会从 POST 请求中获取名为 'nss' 的数据,并尝试将其反序列化。 -
反序列化: 如果 POST 数据包含有效的序列化对象,
unserialize
函数会将其转换回 PHP 对象。在这种情况下,它会尝试创建一个lyh
类的实例。 -
对象销毁与代码执行: 当 PHP 脚本执行完毕或对象不再被引用时,
__destruct
析构函数会被调用。如果$lt
属性包含一个可调用的值(例如一个函数名或一个闭包),那么$a($this->lly)
会执行该函数,并将$lly
作为参数传递。 -
文件高亮:
highlight_file(__FILE__)
会高亮显示当前 PHP 文件的源代码。
这个题目是一题很标准的反序列化
$a = $this->lt;
$a($this->lly);
这是这一题的注入点只要传参把$a变成system();$this->lly变成ls或者cat就是一个简单的命令注入了
构造链条
得到以下payload=O:3:"lyh":3:{s:3:"url";s:10:"NSSCTF.***";s:2:"lt";s:6:"system";s:3:"lly";s:2:"ls";}
接着传参发现能够正常执行命令
然后将 ls 改为其他命令,如 cat /flag
就可以查看 flag 文件:
nss=O:3:"lyh":3:{s:3:"url";s:10:"NSSCTF.***";s:2:"lt";s:6:"system";s:3:"lly";s:9:"cat /flag";}
[SWPUCTF 2022 新生赛]ez_ez_unserialize
分析代码
<?php
class X
{
public $x = __FILE__;
function __construct($x)
{
$this->x = $x;
}
function __wakeup()
{
if ($this->x !== __FILE__) {
$this->x = __FILE__;
}
}
function __destruct()
{
highlight_file($this->x);
//flag is in fllllllag.php
}
}
if (isset($_REQUEST['x'])) {
@unserialize($_REQUEST['x']);
} else {
highlight_file(__FILE__);
}
首先定义了一个名为 X
的类,它有一个公共属性 $x
,该属性被初始化为当前文件的路径(由 __FILE__
魔术常量提供)。
当创建 X
类的新实例时,就调用它构建的函数,它接受一个参数 $x
并将其赋值给类的 $x
属性。
当对象被反序列化时,__wakeup
方法会被自动调用。这个方法的目的是确保 $x
属性的值始终是当前文件的路径,即使它在反序列化之前被更改了。
当对象被销毁时,__destruct
方法会被自动调用。这个方法使用 highlight_file
函数来高亮并显示 $x
属性所指向的文件的内容。注释提到了一个名为 fllllllag.php
的文件,这可能是一个提示,表示真正的标志(flag)可能在该文件中。
所以我们的目的就是获得fllllllag.php
这个文件
将fllllllag.php序列化O:1:"X":1:{s:1:"x";s:13:"fllllllag.php";}
因为要绕过wakeup函数,只要序列化的中的成员数大于实际成员数,即可绕过
将O:1:"X":1:{s:1:"x";s:13:"fllllllag.php";}修改为O:1:"X":2:{s:1:"x";s:13:"fllllllag.php";}即可绕过
SWPUCTF 2021 新生赛]ez_unserialize
打开一看只有一张动图
先查看页面源码
看见有disallow,告诉搜索引擎都有哪些文件不被抓取,也成为禁止抓取
一般情况下,大多数网站创建者或管理员都会在网站的根目录放置一个名为robots.txt的文本文件,用来控制自己的网站哪些目录允许SE搜索引擎爬行并收录,哪些目录禁止搜索引擎收录,Disallow,正是robots.txt文件中设置禁止搜索引擎收录哪些目录的一个词语。
所以我们去看看robots.txt
看到有cl45s.php文件,打开看看
这就是题目
-
error_reporting(0);
:关闭所有 PHP 错误报告。这通常是一个不安全的做法,因为它会隐藏潜在的问题和漏洞。 -
show_source("cl45s.php");
:显示cl45s.php
文件的源代码。这通常用于调试,但在生产环境中是不安全的,因为它会泄露源代码。 -
class wllm { ... }
:定义了一个名为wllm
的类。这个类有两个公共属性:$admin
和$passwd
,以及两个魔术方法:__construct()
和__destruct()
。-
__construct()
:构造函数,当创建wllm
类的实例时会自动调用。它将$admin
设置为 "user",将$passwd
设置为 "123456"。 -
__destruct()
:析构函数,当对象不再被引用时会自动调用。它检查$admin
和$passwd
的值。如果它们分别是 "admin" 和 "ctf",则包含并执行flag.php
文件,并输出$flag
变量的值。否则,它会输出$admin
、$passwd
的值,并加上 "Just a bit more!"。
-
-
$p = $_GET['p'];
:从 GET 请求中获取名为p
的参数,并将其值赋给变量$p
。 -
unserialize($p);
:对$p
进行反序列化。如果$p
包含有效的 PHP 对象序列化数据,那么这些数据将被转换回 PHP 对象。由于wllm
类定义了__destruct()
方法,当反序列化完成时,该方法将被自动调用。
复制源码,把不需要的部分删掉,再加上序列化的代码,将admin和passwd的值改为触发if条件的值,即可得到payload
得到 O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}
构造payload:
?p=O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}