2024 楚慧杯 线下awdp web | Writeup
队里有几个成员去打,回来后在群里发了附件,看了一下感觉不难,就决定复现一下 因为不知道具体题目顺序和名字,只有队员给的附件(复现也都是按照队员给的附件内容来,如果同样有参加的师傅发现缺漏,欢迎在评论区告诉我),所以就按照我的做题顺序来排序。同时为了还原真实线下做题场景,不使用在线工具 第一题 攻 首页一个登录框和一个注册,扫一下目录发现有个cache,访问一下得到一个.pyc文件,用pycdc反编译后得到下面代码 # Source Generated with Decompyle++ # File: app.cpython-38.pyc (Python 3.8) from flask import Flask, request, render_template, redirect, url_for, session, send_from_directory import os import pickle import base64 app = Flask(__name__) app.secret_key = 's3cr3t_Key_Y0u_Nev3r_GuesS' USERS_DIR = 'users' if not os.path.exists(USERS_DIR): os.makedirs(USERS_DIR) def register(): Unsupported opcode: BEGIN_FINALLY (97) username = request.form.get('username') password = request.form.get('password') user_data = { 'username': username, 'password': password } user_file = os.path.join(USERS_DIR, base64.b64encode(username.encode('utf-8')).decode('utf-8') + '.data') # WARNING: Decompyle incomplete register = app.route('/reg', [ 'POST'], **('methods',))(register) def register_page(): return render_template('register.html') register_page = app.route('/register')(register_page) def login(): Unsupported opcode: BEGIN_FINALLY (97) username = request.form.get('username') password = request.form.get('password') user_file = os.path.join(USERS_DIR, base64.b64encode(username.encode('utf-8')).decode('utf-8') + '.data') # WARNING: Decompyle incomplete login = app.route('/login', [ 'POST'], **('methods',))(login) def index(): data = session.get('data', None) if data: data = base64.b64decode(data) if b'R' in data and b'built' in data or b'setstate' in data: return 'hacker???' user_data = None.loads(data) username = user_data['username'] return render_template('index.html', username, **('username',)) return None(url_for('login_page')) index = app.route('/index')(index) def login_page(): return render_template('login.html') login_page = app.route('/')(login_page) def logout(): session.pop('data', None) return redirect(url_for('login_page')) logout = app.route('/logout', [ 'POST'], **('methods',))(logout) def download_cache_file(): cache_file_path = os.path.join('__pycache__', 'app.cpython-38.pyc') if os.path.exists(cache_file_path): return send_from_directory(os.path.dirname(cache_file_path), os.path.basename(cache_file_path), True, **('as_attachment',)) return None download_cache_file = app.route('/cache')(download_cache_file) if __name__ == '__main__': app.run('0.0.0.0', **('host',)) 核心利用逻辑在这里 ...