加密漏洞
进入网站发现有用户名与密码均为guest的用户,登录进去查看。


因没有可交互的地方且为普通用户权限不够。
尝试利用robots.txt文件查看不允许网络搜索引擎的漫游器获取的文件。
robots.txt(统一小写)是一种存放于网站根目录下的ASCII编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。因为一些系统中的URL是大小写敏感的,所以robots.txt的文件名应统一为小写。robots.txt应放置于网站的根目录下。如果想单独定义搜索引擎的漫游器访问子目录时的行为,那么可以将自定的设置合并到根目录下的robots.txt,或者使用robots元数据(Metadata)。
发现一个app.py.bak文件,将其输入到URL后下载发现是生成cookie的代码文件。
from flask import Flask, render_template, request, redirect, url_for, make_response
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import json
import os
import datetime
app = Flask(__name__)
# ---------------------------------------------------
# CRYPTO CONFIGURATION (VULNERABLE)
# ---------------------------------------------------
# HARDCODED KEY! This is the primary vulnerability.
# AES-ECB is also used, which is weak, but the key leak is the fatal flaw.
SECRET_KEY = b'SafeBox_Secret_K' # 16 bytes
BLOCK_SIZE = 16
def encrypt_data(data):
cipher = AES.new(SECRET_KEY, AES.MODE_ECB)
ct_bytes = cipher.encrypt(pad(data.encode('utf-8'), BLOCK_SIZE))
return base64.b64encode(ct_bytes).decode('utf-8')
def decrypt_data(b64_data):
try:
ct = base64.b64decode(b64_data)
cipher = AES.new(SECRET_KEY, AES.MODE_ECB)
pt = unpad(cipher.decrypt(ct), BLOCK_SIZE)
return pt.decode('utf-8')
except (ValueError, KeyError):
return None
# ---------------------------------------------------
# ROUTES
# ---------------------------------------------------
@app.route('/')
def index():
auth_cookie = request.cookies.get('auth_token')
if auth_cookie:
user_data_json = decrypt_data(auth_cookie)
if user_data_json:
user_data = json.loads(user_data_json)
return redirect(url_for('dashboard'))
return redirect(url_for('login'))
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
# Simple Login Logic (No database for simplicity in this specific lab, focused on Crypto)
if username == 'guest' and password == 'guest':
user_data = json.dumps({'username': 'guest', 'role': 'user', 'exp': str(datetime.datetime.now())})
token = encrypt_data(user_data)
resp = make_response(redirect(url_for('dashboard')))
resp.set_cookie('auth_token', token)
return resp
else:
return render_template('login.html', error="Invalid credentials. Try guest/guest")
return render_template('login.html')
@app.route('/logout')
def logout():
resp = make_response(redirect(url_for('login')))
resp.set_cookie('auth_token', '', expires=0)
return resp
@app.route('/dashboard')
def dashboard():
auth_cookie = request.cookies.get('auth_token')
if not auth_cookie:
return redirect(url_for('login'))
user_data_json = decrypt_data(auth_cookie)
if not user_data_json:
return redirect(url_for('login'))
user_data = json.loads(user_data_json)
if user_data.get('role') == 'admin':
return render_template('admin.html', user=user_data, flag="flag{dont_hardcode_keys_and_dont_roll_your_own_crypto}")
else:
return render_template('dashboard.html', user=user_data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
该代码存在漏洞,将密钥与加密方法均写在代码文件中,我们便可利用泄露的密钥与加密方法将"role"改为"admin"构建一个payload文件生成"admin"管理员token。
#Payload代码
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64
import json
import datetime
SECRET_KEY = b'SafeBox_Secret_K'
BLOCK_SIZE = 16
def encrypt_data(data):
cipher = AES.new(SECRET_KEY, AES.MODE_ECB)
ct_bytes = cipher.encrypt(pad(data.encode('utf-8'), BLOCK_SIZE))
return base64.b64encode(ct_bytes).decode('utf-8')
# 构造 Payload
admin_payload = json.dumps({
'username': 'admin',
'role': 'admin',
'exp': str(datetime.datetime.now())
})
print(f"Admin Token: {encrypt_data(admin_payload)}")
执行结果
Admin Token: lWfFm0XN7GE3GaHQb+neJDfwA2wfT5ZMFo12i+o00BKMCEQAMdrdxwMnxiaPvg9MnxiATf1lnDoHgRCtNRUfbSrYIDqqyXJE5kBBgg5bx4Q=将得到的原本的token改为得到的结果刷新网页,我们将返回到admin管理员页面。

