type
Post
status
Published
date
Nov 27, 2025 20:00
slug
summary
tags
CTF
推荐
category
CTF-WP
category (1)
icon
password
comment
阿基里斯追乌龟
打开环境

点击追赶后抓包

对data解码,得到

直接将乌龟的距离清0构造data

进行发包

将返回数据解码得到flag

Vibe SEO
根据题目描述存在站点地图,去访问/sitemap.xml路由,得到如下结果

得到新的路由/aa__^^.php去访问得到如下报错

根据报错提示猜测是文件读取,参数是filename,先使用get传参读取自身文件(主要是为了看具体文件源码),然后查看源码得到

得知filename长度不能超过11,但是flag所在的文件文件名很长,所以直接读取肯定不行
看到有被打开的文件描述符$flag,想到伪协议php://fd/[文件描述符编号],但是试过长度太长不行,找了一个替代的文件目录/dev/fd/[文件描述符编号]
其中文件描述符编号需要自己爆破,最后爆破出来是13,得到flag

Xross The Finish Line
打开一看界面就知道肯定是xss然后外带

经过测试发现过滤了
构造相应的payload
输入到留言框提交
在公网服务器上开启一个php的网站服务

点击报告给管理员,就能外带管理员的cookie,就得到flag了

Expression
由题目意思知道这题应该是jwt伪造,先随便注册一个账号然后登陆抓包看jwt

得到了jwt去在线网站解密(https://www.jwt.io/),因为说密钥没有改,所以大概率猜是secret,结果发现验证通过了
其实也可以去爆破(爆破工具:c-jwt-cracker)


试一下伪造admin看看

将伪造后的值替换原来的token出发包

看到前端也显示admin了
去查看一下网站用什么写的

猜测可能是ejs模板注入,构造payload

进行jwt伪造发包,得到flag

popself
exp
得到flag

这题涉及到双md5还是0e开头的问题,下面贴一些符合要求的字符串
$md5 md5(md5($md5))
0e1138100474 0e779212254407018184727546255414
0e1576609003 0e783827937870189505146310298941
0e1576882155 0e063554437755195035165445789139
0e1687027651 0e824361684489256492954843919134
0e1808236718 0e935567136545220553710393252752
0e1883153115 0e215043081382353607609756824848
0e2010692162 0e514898998879174336203746127058
0e2191017163 0e990693510804099511097744934423
0e2263940937 0e468303117297464441647744757721
0e2268790262 00e73242608486551620036091555760
0e2366549572 0e691884388380428395250404229605
0e2815644399 0e662052678416572768754614486758
one last image
一句话木马,可以直接上传php但是<?php标签被过滤了,我们使用短标签构造木马
上传后得到地址

去访问木马所在的地址进行命令执行

得到了flag
Sequal No Uta
一题常规的sql注入,但是要注意这个不是mysql是SQLite,语法稍微有点不一样,思路都一样
直接上exp
爆出表和字段

去查看secret这个字段
得到flag

ez read
注册一个账户然后登陆进入读取故事界面,发现有任意文件读写

这种题目一般要先读取源码,然后进行代码审计利用漏洞获取flag,不然你flag文件的名字都不知道就很难搞,所以要rce
先去看看虚拟目录中的项目启动命令

看见启动看app.py文件所以猜测是flask,但是app.py的所在目录不知道无法读出这个文件的代码
再去看一下当前进程的虚拟目录的环境变量

得到了home目录,再去访问这个目录下的app.py文件
然后就看到了debug设置成了false

所以不能进入调试得换一个方法
然后开启了漫长的代码审计过程..........
源码
这边教一个技巧,一般代码中都会有waf,看看哪边调用了waf就去那边找漏洞..…

发现要先用session伪造user(其实直接注册也可以不伪造)然后去进行模板注入
session的key就是代码中的app_key

接下来是漫长的绕过waf的过程,这边可以用fenjing辅助,就自己本地运行一个让fenjin打
自己本地搭一个简化的服务
然后让fenjing去跑

发现成功,接下来只要填充到514位即可
首先需要保证自己的exp长度为114或者514,因为没有'('不行
下面是自己手搓的exp
获取所有类

解码后发现第147个类(其实是146,因为从0记)有os可利用popen

直接写exp利用(同样凑满514)
发现利用成功

直接反弹shell
然后去得到shell

发现还要提权我真的是麻了
查看当前有suid权限的文件

利用env命令进行提权

得到flag
百年继承
说实话有点猜谜了
大致逻辑是通过原型链污染去修改掉execute_method的值,execute_method的值就是要执行的字符串
exp

得到了flag
ez-seralize
题目环境提供了一个读取文件的接口,老样子能读文件必须先读取源码

源码如下
审计发现应该是利用phar反序列化去利用本来就存在的function.php然后进行相应的命令执行
所以先去看看function.php

得到源码
但是利用phar反序列化应当会有一个文件上传的点,我们去看一下robots.txt

发现文件上传的逻辑代码,我们老样子先看源代码

得到源代码如下
分析可知文件上传的后缀必须是白名单中的后缀
接下来是构造phar文件的exp
但是文件后缀要改,所以还要重新签名,签名脚本如下
得到了newtest.gif将其通过/uploads路由上传
这边有个坑,我代码审计没审仔细,还以为文件上传后文件名不变,其实仔细分析uploads.php这个代码能发现文件名变了,且文件吗写到/tmp/log.txt文件中 了
上传之后先去访问/tmp/log.txt得到真实的文件名

再去进行phar反序列化

然后此时flag被写入/tmp/flag文件中了,直接去读这个文件即可

获得flag
eeeeezzzzzzZip
扫描目录发现www.zip路由,直接访问获取源码
先看login.php源码
得到账号是admin密码是guest123,去进行登陆

登陆成功,去查看index.php源码
发现
@include($fullpath); 得知上传的zip文件可以被文件包含,要是上传的zip内容里有php恶意代码就可以命令执行了,接下来主要去看upload.php的源代码可以看到过滤了如下内容
但是接着看下去
发现这个代码仅仅对文件开头的4096个字节和文件最后4096个字节进行黑名单检测,那我们中间可以穿插恶意代码
得到exp文件

进行上传之后访问

获得flag
路在脚下
ssti注入但是没有回显
试了很久也不出网真的是麻烦,主要是这题还是easy………
那只能时间盲注了(第一次用)
可以参照以下博客:看看ssti | Err0r233
首先利用exp找出eval模块所在的位置
结果为103
先用脚本看一下根目录有哪些文件

可以看到flag就在根目录下,那就再去cat一下
被骗了根目录的flag是空的,脚本跑了半天啥都没有,我还以为脚本坏了……
那就试一下env吧,一般在环境变量最后,我倒着读ahhh
后来想了一下我为什么不直接访问指定名称的环境变量呢
echo $FLAG
这题还是不错的,学到了如何用SSTI进行盲注
路在脚下 revenge
顺手接着秒了,和《路在脚下》这题一样的思路
可能我一开始就是没用非预期
直接上exp

秒了
官方的wp是实现add_url_rule的底层逻辑来实现新版本flask的添加路由
Image Viewer
看到能传svg图片,就试试是不是xxe漏洞,直接构造payload上传

所得回显去解密得到flag

PDF Viewer
现利用ssrf漏洞读取一下/etc/passwd

获得提示,管理员是弱密码

去进行网站管理员的弱密码爆破

找到响应大小不一样的那个响应

可以看到登陆成功,密码是qwerty
得到了flag并提交
77777_time_task

看到这里有个定时任务感觉可疑,再看源代码
有一个7z解压功能,我们试一下可不可以通过软连接,将自己的shell反弹脚本写入定时任务中
这边很坑,要先下载它用的7z才能成功创建软连接的7z文件,本地试了好久
具体下载看下面的文件

然后先创建一个软链接目录指向/etc/cron.d,然后用下载的7zz程序进行软链接压缩上传


上传之后可以看到服务器那边软链接指向了/app/etc/cron.d目录

唉~失败了,服务器端的7z自动加上当前目录,最后想了一下找到了漏洞点
可以直接根据这个代码上传名字是
../../../etc/cron.d/./7z 的文件,本来想反弹shell的但是一直不成功,干脆直接发flag构造请求包上传

解压失败也没关系反正文件已经在服务器上了

最后得到flag
Xross The Doom
先查看源代码,发现很多文件,以下挑几个文件讲解
首先注意到/bot路由,访问这个路由可以获取flag,但是flag在cookie中,一开始想着xss外带但是这个题目用了最新的dompurify找不到相关的cve,所以行不通,后来看了好久,知道看到admin.js的逻辑
1.代码逻辑分析
这段代码的执行流程如下:
a.加载内容:从后端 API 获取帖子,经过
DOMPurify 清洗后插入页面 (innerHTML)。b.获取配置 (漏洞点):
代码尝试读取三个全局变量。如果在 JS 中没有定义这些变量(事实上确实没定义),浏览器会去 DOM 中寻找带有对应
id 或 name 的 HTML 元素,并将其赋值给 window.变量名。window.AUTO_SHARE
window.CONFIG_PATH
window.CONFIG_COOKIE_DEBUG
c.构建目标 URL:使用
buildTarget 函数,结合 /analytics 和 CONFIG_PATH。d.发送请求:如果
auto 为真,则向计算出的目标 URL 发送 fetch 请求,并且如果 includeCookie 为真,会把 Cookie 带上。2.核心利用点
我们需要满足三个条件才能窃取 Cookie:
条件 A:让
auto 变为 true攻击方法:注入任意一个带有
id="AUTO_SHARE" 的标签。
Payload: <a id="AUTO_SHARE"></a>- 效果:
window.AUTO_SHARE变成了这个<a>元素(对象),asBool返回true。
条件 B:让
includeCookie 变为 true攻击方法:注入任意一个带有
id="CONFIG_COOKIE_DEBUG" 的标签。
Payload: <a id="CONFIG_COOKIE_DEBUG"></a>- 效果:
window.CONFIG_COOKIE_DEBUG变成元素,asBool返回true。
条件 C:控制
path 并利用目录穿越这是最关键的一步。
并且看
buildTarget 函数:如果我们想把 Flag 发送出去,我们需要访问服务器上的
/log 接口(因为 /analytics 大概率没用或不存在)。
/analytics + ../../log -> /log。攻击方法:我们需要一个带有
action 属性的元素。在 HTML 白名单中,<form> 标签是允许带有 action 属性的。
Payload: <form id="CONFIG_PATH" action="../../log"></form>3. 完整的攻击 Payload
结合以上分析,需要构造一个帖子,内容包含以下三个 HTML 元素。将它们合并在一起:
4. 攻击流程演示
- 攻击者提交上述 Payload 到
/api/posts。
- 服务器使用 JSDOM/DOMPurify 处理。由于
<a>和<form>都是白名单标签,且id和action属性在默认配置下通常是被允许的(或者如你之前测试id="preview"能过,说明id肯定没被过滤),Payload 被完整存入数据库。
- 攻击者诱导 Bot (Admin) 访问
/bot?id=你的帖子ID。
- Bot 打开页面,执行 JS:
innerHTML渲染了那三个标签。window.AUTO_SHARE被劫持 ->true。window.CONFIG_COOKIE_DEBUG被劫持 ->true。window.CONFIG_PATH被劫持,asPath读取到action="../../log"。buildTarget('/analytics', '../../log')解析为/log。
- 触发 Fetch:
Bot 执行:
fetch('/log?id=...&ua=...&c=' + document.cookie)。
- 窃取 Flag:
请求发送到了服务器的
/log接口。 攻击者访问/logs接口(根据之前的server.js代码),查看最新的日志记录,其中cookie字段里就包含 Flag。
- 作者:qetx
- 链接:http://qetx.top/article/2b3b233d-8731-8079-b116-d1f02c4eca7e
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。








