1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
   | from flask import Flask, request, make_response, render_template, redirect, url_for import jsonpickle import base64 import json import os import time
  app = Flask(__name__) app.secret_key = os.urandom(24)
 
  class Account:     def __init__(self, uid, pwd):         self.uid = uid         self.pwd = pwd
 
  class Session:     def __init__(self, meta):         self.meta = meta
 
  users_db = [     Account("admin", os.urandom(16).hex()),     Account("guest", "guest") ]
 
  def register_user(username, password):     for acc in users_db:         if acc.uid == username:             return False     users_db.append(Account(username, password))     return True
 
  FORBIDDEN = [     'builtins', 'os', 'system', 'repr', '__class__', 'subprocess', 'popen', 'Popen', 'nt',     'code', 'reduce', 'compile', 'command', 'pty', 'platform', 'pdb', 'pickle', 'marshal',     'socket', 'threading', 'multiprocessing', 'signal', 'traceback', 'inspect', '\\\\', 'posix',     'render_template', 'jsonpickle', 'cgi', 'execfile', 'importlib', 'sys', 'shutil', 'state',     'import', 'ctypes', 'timeit', 'input', 'open', 'codecs', 'base64', 'jinja2', 're', 'json',     'file', 'write', 'read', 'globals', 'locals', 'getattr', 'setattr', 'delattr', 'uuid',     '__import__', '__globals__', '__code__', '__closure__', '__func__', '__self__', 'pydoc',     '__module__', '__dict__', '__mro__', '__subclasses__', '__init__', '__new__' ]
 
  def waf(serialized):     try:         data = json.loads(serialized)         payload = json.dumps(data, ensure_ascii=False)         for bad in FORBIDDEN:             if bad in payload:                 return bad         return None     except:         return "error"
 
  @app.route('/') def root():     return render_template('index.html')
 
  @app.route('/register', methods=['GET', 'POST']) def register():     if request.method == 'POST':         username = request.form.get('username')         password = request.form.get('password')         confirm_password = request.form.get('confirm_password')
          if not username or not password or not confirm_password:             return render_template('register.html', error="所有字段都是必填的。")
          if password != confirm_password:             return render_template('register.html', error="密码不匹配。")
          if len(username) < 4 or len(password) < 6:             return render_template('register.html', error="用户名至少需要4个字符,密码至少需要6个字符。")
          if register_user(username, password):             return render_template('index.html', message="注册成功!请登录。")         else:             return render_template('register.html', error="用户名已存在。")
      return render_template('register.html')
 
  @app.post('/auth') def auth():     u = request.form.get("u")     p = request.form.get("p")     for acc in users_db:         if acc.uid == u and acc.pwd == p:             sess_data = Session({'user': u, 'ts': int(time.time())})             token_raw = jsonpickle.encode(sess_data)             b64_token = base64.b64encode(token_raw.encode()).decode()             resp = make_response("登录成功。")             resp.set_cookie("authz", b64_token)             resp.status_code = 302             resp.headers['Location'] = '/panel'             return resp     return render_template('index.html', error="登录失败。用户名或密码无效。")
 
  @app.route('/panel') def panel():     token = request.cookies.get("authz")     if not token:         return redirect(url_for('root', error="缺少Token。"))
      try:         decoded = base64.b64decode(token.encode()).decode()     except:         return render_template('error.html', error="Token格式错误。")
      ban = waf(decoded)     if ban:         return render_template('error.html', error=f"请不要黑客攻击!{ban}")
      try:         sess_obj = jsonpickle.decode(decoded, safe=True)         meta = sess_obj.meta
          if meta.get("user") != "admin":             return render_template('user_panel.html', username=meta.get('user'))
          return render_template('admin_panel.html')     except Exception as e:         return render_template('error.html', error="数据解码失败。")
 
  @app.route('/vault') def vault():     token = request.cookies.get("authz")     if not token:         return redirect(url_for('root'))
      try:         decoded = base64.b64decode(token.encode()).decode()         if waf(decoded):             return render_template('error.html', error="请不要尝试黑客攻击!")         sess_obj = jsonpickle.decode(decoded, safe=True)         meta = sess_obj.meta
          if meta.get("user") != "admin":             return render_template('error.html', error="访问被拒绝。只有管理员才能查看此页面。")
          flag = "NepCTF{fake_flag_this_is_not_the_real_one}"         return render_template('vault.html', flag=flag)     except:         return redirect(url_for('root'))
 
  @app.route('/about') def about():     return render_template('about.html')
 
  if __name__ == '__main__':     app.run(host='0.0.0.0', port=8000, debug=False)
   |