0%

buuctf awdp加固题|web

前言:

备赛国赛awdp的fix部分

ezsql

分析代码可以找到sql注入的漏洞点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
error_reporting(0);
include 'dbConnect.php';
$username = $_GET['username'];
$password = $_GET['password'];
if (isset($_GET['username']) && isset($_GET['password'])) {
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = $mysqli->query($sql);
if (!$result)
die(mysqli_error($mysqli));
$data = $result->fetch_all(); // 从结果集中获取所有数据
if (!empty($data)) {
echo '登录成功!';
} else {
echo "用户名或密码错误";
}
}
?>

fix:addslashes()处理特殊字符+sql预处理(这题不需要)

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
<?php
error_reporting(0);
include 'dbConnect.php';
$username = $_GET['username'];
$password = $_GET['password'];
$username = addslashes($username);
$password = addslashes($password);

if (isset($_GET['username']) && isset($_GET['password'])) {
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$result = $stmt->get_result();
if (!$result)
die(mysqli_error($mysqli));
$data = $result->fetch_all(); // 从结果集中获取所有数据
if (!empty($data)) {
echo '登录成功!';
} else {
echo "用户名或密码错误";
}

$stmt->close();
}
?>

[CISCN2021 总决赛]babypython

用bandit做一下代码审计

1
docker run --rm -v "${pwd}:/app" bandit:1.9.4 -r /app -f html -o /app/bandit_report.html

fix:添加黑名单限制命令执行

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
# -*- coding: utf-8 -*-
from flask import Flask,session,render_template,redirect, url_for, escape, request,Response
import uuid
import base64
import random
import secret
from werkzeug.utils import secure_filename
import os
random.seed(uuid.getnode())
app = Flask(__name__)
app.config['SECRET_KEY'] = str(random.random()*100)
app.config['UPLOAD_FOLDER'] = './uploads'
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024
ALLOWED_EXTENSIONS = set(['zip'])
blacklist = ["system", "ls", "c", "a", "t", "flag"]

def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET'])
def index():
error = request.args.get('error', '')

if(error == '1'):
session.pop('username', None)
return render_template('index.html', forbidden=1)
if not 'username' in session:
session['username'] = "guest"

if 'username' in session:
return render_template('index.html', user=session['username'], secret=secret.secret)
else:

return render_template('index.html')


@app.route('/upload', methods=['POST'])
def upload_file():
if 'the_file' not in request.files:
return redirect(url_for('index'))
file = request.files['the_file']
if file.filename == '':
return redirect(url_for('index'))
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file_save_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
if(os.path.exists(file_save_path)):
return 'This file already exists'
file.save(file_save_path)
else:
return 'This file is not a zipfile'


try:
extract_path = file_save_path + '_'
if extrac_path in blacklist:
return 'failed'
break
os.system('unzip -n ' + file_save_path + ' -d '+ extract_path)
read_obj = os.popen('cat ' + extract_path + '/*')
file = read_obj.read()
read_obj.close()
os.system('rm -rf ' + extract_path)
except Exception as e:
file = None

os.remove(file_save_path)
if(file != None):
if(file.find(base64.b64decode('ZmxhZw==').decode('utf-8')) != -1):
return redirect(url_for('index', error=1))
return Response(file)


if __name__ == '__main__':
#app.run(debug=True)
app.run(host='127.0.0.1', debug=False, port=10008)

[CISCN2021 总决赛]iiNote

JWT密钥fix:这题主要问题就是这个,ENCRYPT_KEY和SQL密码也同理但是这里不需要

1
2
3
4
import secrets

secret = secrets.token_hex(32) # 生成64位十六进制字符串
print(f"生成64位十六进制字符串: {secret}")

目录穿越fix:这题没有影响,刚好做个收集

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
@note.route('/read', methods=['POST'])
def read():
try:
_id = g.json['id']
except KeyError:
return {'status': 'parameter error'}, 400

if not _id.startswith(g.path+'/'):
return {'status': 'not your note'}

try:
with open(os.path.join(current_app.config['NOTE_PATH'], _id)) as f:
title = f.readline().strip('\n')
content = f.read()
except:
return {'status': 'note error'}

return {'status': 'success', 'title': title, 'content': content}


# fix
@note.route('/read', methods=['POST'])
def read():
try:
_id = g.json['id']
except KeyError:
return {'status': 'parameter error'}, 400

# 1. 获取基础路径
base_path = os.path.abspath(current_app.config['NOTE_PATH'])
user_base = os.path.abspath(g.path)

# 2. 规范化用户请求的路径
try:
# 先拼接再规范化
requested_path = os.path.abspath(os.path.join(base_path, _id))
except Exception:
return {'status': 'invalid path'}, 400

# 3. 严格验证路径是否在允许的范围内
if not requested_path.startswith(base_path):
return {'status': 'access denied'}, 403

# 4. 验证路径是否在用户目录下
if not requested_path.startswith(user_base):
return {'status': 'not your note'}, 403

# 5. 额外安全检查
if os.path.islink(requested_path):
# 如果是符号链接,检查其真实路径
real_path = os.path.realpath(requested_path)
if not real_path.startswith(base_path) or not real_path.startswith(user_base):
return {'status': 'invalid note'}, 403

try:
with open(requested_path, 'r', encoding='utf-8') as f:
title = f.readline().strip('\n')
content = f.read()
except FileNotFoundError:
return {'status': 'note not found'}, 404
except PermissionError:
return {'status': 'permission denied'}, 403
except Exception as e:
# 记录详细错误但不返回给客户端
current_app.logger.error(f"Error reading note: {str(e)}")
return {'status': 'note error'}, 500

return {'status': 'success', 'title': title, 'content': content}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@app.errorhandler(404) 
def page_not_found(error):
# 不要使用 render_template_string(render_template(...))
# 直接渲染 404.html,并将错误信息作为变量传入
return render_template("404.html", uri=error.description), 404


from flask import escape

@app.errorhandler(404)
def page_not_found(error):
# 将描述信息转义为纯文本,使其无法包含 {% 或 {{
safe_description = escape(error.description)
return render_template_string(render_template("404.html", uri=safe_description)), 404