PHP反序列化ctf题解

admin 2024年12月10日12:37:11评论10 views字数 2067阅读6分53秒阅读模式

unseping(序列化)

题目:

<?php
highlight_file(__FILE__);

class ease{

private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}

function __destruct(){
if (in_array($this->method, array("ping"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}

function ping($ip){
exec($ip, $result);
var_dump($result);
}

function waf($str){
if (!preg_match_all("/(||&|;| |/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
return $str;
} else {
echo "don't hack";
}
}

function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf($v);
}
}
}

$ctf=@$_POST['ctf'];
@unserialize(base64_decode($ctf));
?>

我们对代码进行分析之前,首先需要了解一些序列化的知识。首相序列化本身的目的是将数据经过处理,以json的形式传输。

PHP中的序列化一般使用serialize()函数进行处理,使用unserialize()可以对序列化的字符进行解密,下面是序列化的数据。

PHP反序列化ctf题解

上面使用了几种构造方法:

__construct构造方法

当使用new关键字实例化一个对象时,构造函数将会自动调用。如果构造函数有参数的话,那么在实例化的时候也需要传入对应的参数。

绕过:

反序列化的时候,类的构造函数即不会被执行。

__destruct()析构方法

析构函数只有在对象被垃圾收集器收集之前,才会被自动调用。析构函数允许我们在销毁一个对象之前执行一些特点的操作,例如关闭文件,释放结果集。

触发条件:

主动调用unset函数将指向对象的变量删除

指向对象的变量被置为空,导致对象无法引用

程序自动结束、垃圾回收机制回收

__wakeup()方法

在 unserialize()调用之前,会检查是否存在一个wakeup方法。如果存在,会先调用他,预先准备对象数据。

wakeup绕过

将需要进行反序列化的对象的序列化字符串中的成员数,大于实际成员数量。

调用wakeup方法,序列化字符串中表示对象属性个数大于真实的属性个数时,就会跳过wakeup执行。

printf绕过

Linux中的printf函数,可以将十六进制或者八进制的字符数字转化ASCII字符内容输出。

Linux中对空格过滤

Linux中的IFS变量,我们通过设置这个变量为空格、tab、回车的其中一个或者几个。我们设置其变量为空格的时候,可以绕过空格的过滤。

$()与` `(反引号)

在命令中,这两个都是用来作为命令替换,例如:

$ echo today is $(date "+%Y-%m-%d"),

执行结果:

today is 2014-07-01

$$()会将$()返回的结果视为命令进行执行,命令窗口里会有一个$

思路

我们需要通过序列化进行命令执行。所以我们要绕过其中的一些正则过滤

其次整个代码的意思,是可以接收post传来的ctf的值,然后对这个进行base64编码以及反序列化,我们可以控制ctf变量。

我们来研究下他的一个过滤规则,wakeup方法中,进行了正则过滤,再看destruct方法,该方法检测ping是否在method中,并且调用了名为method的方法,以数组arg的值为参数。

综合来看就是在通过$method和__construct来调用构造的ping方法,接着通过$args来作为输入口进行命令的输入。

也就是说我们需要将我们要执行的命令,进行序列化,然后加密为base64之后传入进去

O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1 {i:0;s:4:"l''s";}}

PHP反序列化ctf题解

发送之后可以看到

PHP反序列化ctf题解

文件下有两个文件,一个index,一个flag

我们可以ls一下flag文件,这里面的命令使用双引号单引号绕过

PHP反序列化ctf题解

执行上面这段代码进行序列化之后,我们就可以获得flag文件

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyNDoibCIicyR7SUZTfWYiImxhZ18xc19oZXJlIjt9fQ==

PHP反序列化ctf题解

最后我们cat一下这个flag.php文件

PHP反序列化ctf题解

PHP反序列化ctf题解

获得flag

原文始发于微信公众号(白安全组):PHP反序列化ctf题解

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月10日12:37:11
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PHP反序列化ctf题解https://cn-sec.com/archives/3490481.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息