[GHCTF 2024 新生赛]理想国 flask session伪造

忙着毕业论文几天没做题了。
进入页面发现几个api接口,注册登录搜索登出4个。

利用postman访问注册接口注册。

可以看到返回了token,利用token访问login。

尝试search页面传入file参数试试能不能目录穿越。

得到secret-key,这里有个非预期解,访问/proc/1/environ直接得到flag。

预期解:访问/app/app.py得到源码。

点击查看代码
# coding=gbk
import json
from flask import Flask, request, jsonify, send_file, render_template_string
import jwt
import requests
from functools import wraps
from datetime import datetime
import osapp = Flask(__name__)
app.config['TEMPLATES_RELOAD'] = True
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')response0 = {'code': 0, 'message': 'failed', 'result': None}
response1 = {'code': 1, 'message': 'success', 'result': current_time}
response2 = {'code': 2, 'message': 'Invalid request parameters', 'result': None}def auth(func):@wraps(func)def decorated(*args, **kwargs):token = request.cookies.get('token')if not token:return 'Invalid token', 401try:payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])if payload['username'] == User.username and payload['password'] == User.password:return func(*args, **kwargs)else:return 'Invalid token', 401except:return 'Something error?', 500return decorateddef check(func):@wraps(func)def decorated(*args, **kwargs):token = request.cookies.get('token')if not token:return 'Invalid token', 401try:payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])if payload['username'] == "Plato" and payload['password'] == "ideal_state":return func(*args, **kwargs)else:return 'You are not a sage. You cannot enter the ideal state.', 401except:return 'Something error?', 500return decorated@app.route('/', methods=['GET'])
def index():return send_file('api-docs.json', mimetype='application/json;charset=utf-8')@app.route('/enterIdealState', methods=['GET'])
@check
def getflag():flag = os.popen("/readflag").read()return flag@app.route('/api-base/v0/register', methods=['GET', 'POST'])
def register():if request.method == 'POST':username = request.json['username']if username == "Plato":return 'Your wisdom is not sufficient to be called a sage.', 401password = request.json['password']User.setUser(username, password)token = jwt.encode({'username': username, 'password': password}, app.config['SECRET_KEY'], algorithm='HS256')User.setToken(token)return jsonify(response1)return jsonify(response2), 400@app.route('/api-base/v0/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.json['username']password = request.json['password']try:token = User.tokenpayload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])if payload['username'] == username and payload['password'] == password:response = jsonify(response1)response.set_cookie('token', token)return responseelse:return jsonify(response0), 401except jwt.ExpiredSignatureError:return 'Invalid token', 401except jwt.InvalidTokenError:return 'Invalid token', 401return jsonify(response2), 400@app.route('/api-base/v0/logout')
def logout():response = jsonify({'message': 'Logout successful!'})response.delete_cookie('token')return response@app.route('/api-base/v0/search', methods=['POST', 'GET'])
@auth
def api():if request.args.get('file'):try:with open(request.args.get('file'), 'r') as file:data = file.read()return render_template_string(data)except FileNotFoundError:return 'File not found', 404except jwt.ExpiredSignatureError:return 'Invalid token', 401except jwt.InvalidTokenError:return 'Invalid token', 401except Exception:return 'something error?', 500else:return jsonify(response2)class MemUser:def setUser(self, username, password):self.username = usernameself.password = passworddef setToken(self, token):self.token = tokendef __init__(self):self.username = "admin"self.password = "password"self.token = jwt.encode({'username': self.username, 'password': self.password}, app.config['SECRET_KEY'], algorithm='HS256')if __name__ == '__main__':User = MemUser()app.run(host='0.0.0.0', port=8080)
所以实质就是伪造session,用户名为Plato,密码为ideal_state,secret-key已经知道了,直接在jwt.io进行下一步,利用伪造的session访问enterIdealState页面得到flag。

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

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

相关文章

Arduino UNO和Nano的区别

Arduino UNO 和 Arduino NANO 的区别 ATmega328p UNO对于用过Arduino开发板的小伙伴来说应该是比较熟悉的了,主要说说NANO,UNO和NANO控制芯片同样用的ATmega328p,不同的是芯片封装不同,UNO是DIP28封装 NANO是TQFP32封装(NANO比UNO多了4个引脚出来)图 Arduino Uno图 Arduino…

避免图纸外泄:企业加密软件选择的4条建议

在当今竞争激烈的商业环境中,企业的核心图纸和技术资料是其竞争力的关键。然而,随着信息技术的发展,图纸外泄的风险也日益增加。为了有效保护这些宝贵的无形资产,企业必须选择适合的加密软件。以下是一些专业的建议,帮助企业在选择图纸加密软件时做出明智的决策。一、加密…

阿里400+天,我为什么离开阿里

阿里还是挺不错了,感谢公司,感谢同事们! 零丶前言 今天是我在阿里的lastday,明天我将回成都(此处嘴角弯,我爱成都),端午后入职另外一家互联网大厂。 在去年3月份的时候,我从成都的某家金融科技银行跳槽到杭州阿里巴巴淘天集团,这篇《跳槽!阿里工作100+天,菜鸡职业生涯…

在线RSA公钥私钥生成工具

在线RSA非对称加密公钥私钥生成工具,提供便捷、安全的公私钥生成服务。支持多种密钥长度选择,满足个性化需求。一键生成PEM格式证书,让您快速实现数据加密与身份验证,保障数据安全,提升网络安全防护能力。在线RSA公钥私钥生成工具

自媒体必用的50 个最佳 ChatGPT 社交媒体帖子提示prompt通用模板教程

ChatGPT不仅能帮你快速生成高质量的内容,还能给你带来创意灵感,让每一个社交媒体帖子都变得与众不同。不管你是想写一个吸引眼球的标题,还是想问个有趣的问题,或者分享一句励志的名言,ChatGPT都能帮你搞定。在这个信息爆炸的时代,社交媒体已经成为我们生活中不可或缺的一…

数据治理--模板

支持重跑 建临时表的方式

【日记】遇到了一个很奇怪的大爷(845 字)

正文花了昨天和今天两天时间,把数据转移完了。这块 2T 的硬盘可以光荣退休了。目前是没什么存储焦虑了。农发行净开发一些垃圾系统。今天没什么业务,但跟 ActiveX 斗智斗勇了一整天,最后实在搞不过 IE 浏览器。我也懒得管了,又不多挣一份工资。晚上去跳舞,才注意到老师的妻…

面试必会 --> MyBatis篇

什么是MyBatisMybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。MyBatis 可以使用 XML 或注解来…

H3C模拟延时测试ping包

1.拓扑2.各路由器配置 sysname R1ospf 1area 0.0.0.0network 10.0.12.0 0.0.0.255network 10.0.13.0 0.0.0.255interface LoopBack0ip address 1.1.1.1 255.255.255.255ospf 1 area 0.0.0.0interface GigabitEthernet0/0ip address 10.0.12.1 255.255.255.0interface GigabitEt…

机器学习算法(一):1. numpy从零实现线性回归

系列文章目录 机器学习算法(一):1. numpy从零实现线性回归 机器学习算法(一):2. 线性回归之多项式回归(特征选取) @目录系列文章目录前言一、理论介绍二、代码实现1、导入库2、准备数据集3、定义预测函数(predict)4 代价(损失)函数5 计算参数梯度6 批量梯度下降7 训…

约束条件补充、主键和外键约束、过滤条件(查询语法)

【一】约束条件补充 -- 【一】什么是约束条件 -- 约束条件就是为了限制表中的数据,保证数据的准确性和可靠性而存在的限制规则 -- 在创建表和字段的时候,约束条件是可有可无的,但是某些情况下为了约束数据的准确所以要必须加约束条件 -- 【二】约束条件概览 -- 【1】null 和…

Markdown 速查表

基本语法 标题 # Heading level 1 ## Heading level 2 ### Heading level 3 #### Heading level 4 ##### Heading level 5 ###### Heading level 6Heading level 1 Heading level 2 Heading level 3 Heading level 4 Heading level 5 Heading level 6 段落 I really like using…