复现地址:https://buuoj.cn/challenges#[GKCTF%202021]hackme

直接访问靶机是一个登录界面

image-20230329165150877

给了提示:unicode , 注意server和其配置文件

右键查看源代码,可以看到一个注释,,这里是三个单词而不是四个,do you nosql?

什么是 Nosql

NoSQL 即 Not Only SQL,意即 “不仅仅是SQL”。在现代的计算系统上每天网络上都会产生庞大的数据量。这些数据有很大一部分是由关系数据库管理系统(RDBMS)来处理。 通过应用实践证明,关系模型是非常适合于客户服务器编程,远远超出预期的利益,今天它是结构化数据存储在网络和商务应用的主导技术。

NoSQL 是一项全新的数据库革命性运动,早期就有人提出,发展至 2009 年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

什么是 MongoDB

MongoDB 是当前最流行的 NoSQL 数据库产品之一,由 C++ 语言编写,是一个基于分布式文件存储的数据库。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

1
2
3
4
5
6
7
8
9
10
11
{
"_id" : ObjectId("60fa854cf8aaaf4f21049148"),
"name" : "bohemian",
"description" : "the admin user",
"age" : 19,
"status" : "A",
"groups" : [
"admins",
"users"
]
}
Nosql 注入的简介

NoSQL 注入由于 NoSQL 本身的特性和传统的 SQL 注入有所区别。使用传统的SQL注入,攻击者利用不安全的用户输入来修改或替换应用程序发送到数据库引擎的 SQL 查询语句(或其他SQL语句)。
换句话说,SQL 注入使攻击者可以在数据库中 SQL 执行命令。

与关系数据库不同,NoSQL 数据库不使用通用查询语言。NoSQL 查询语法是特定于产品的,查询是使用应用程序的编程语言编写的:PHP,JavaScript,Python,Java 等。这意味着成功的注入使攻击者不仅可以在数据库中执行命令,而且可以在应用程序本身中执行命令,这可能更加危险。

  • 重言式注入

又称为永真式,此类攻击是在条件语句中注入代码,使生成的表达式判定结果永远为真,从而绕过认证或访问机制。

默认用户输入账号密码后的username password 为这样的

1
username=bohemian&password=657260

进入 PHP 后的程序数据如下:

1
2
3
4
array(
'username' => 'bohemian',
'password' => '657260'
)

为一个数组,将此带到入到mongodb中为

1
> db.users.find({'username':'bohemian', 'password':'657260'})

在mongodb中有一些条件操作符,

  • $eq: (equal)等于

  • $gt:(greater than)大约

  • $gte: (greater than equal)大约等于

  • $in:等于数组中的某一项,{field:{$in:{value1,value2…}}}

  • $lt:(less than)小于

  • $lte:(less than equal)小于等于

  • $ne:(not equal)不等于

  • $nin:(not in)不等于数组中的任何一项

//查询age = 22的记录

db.userInfo.find({“age”: 22});

//相当于:select * from userInfo where age = 22;

//查询age > 22的记录

db.userInfo.find({age: {$gt: 22}});

//相当于:select * from userInfo where age > 22;

如果当我们输入username[$ne]=1时,就会成为

username=array($ne=>1) == ‘username’:{$ne:1}

带入到mongodb中db.users.find({‘username’:{$ne:1}, ‘password’:{$ne:1}})

当页面没有回显时,那么我们可以通过 $regex 正则表达式来进行盲注, $regex 可以达到和传统 SQL 注入中 substr() 函数相同的功能。