热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mongodb修改数据语句_MongoDB操作语句及注入

首发于安恒公众号这几天读了一本《MongoDB权威指南》的动物书,简单了解了这类nosql(NotOnlySQL)数据库的操作语句。书上的业务层面以及sql优化部分我

首发于安恒公众号

这几天读了一本《MongoDB权威指南》的动物书,简单了解了这类nosql(Not Only SQL)数据库的操作语句。书上的业务层面以及sql优化部分我就略过了。书上是2.x版本的MongoDB,部分语句已经废弃了,在踩坑后我把那些删掉了

Mongo的最大特点就是存储数据格式的多样化和反关系范式:相对于关系化数据库的”矩形”存储格式,Mongo可以存储任意的json格式数据,例如{'u': 'admin', 'pwd': '***'}。当然有利必定有弊,假如存储的是格式化的数据,如用户表这样每一行都是相同字段,那么每一行都需要存储一遍字段名,解决办法?字段名取短一点,就像我举得例子一样

反关系范式需要好好设计,根据读写比例,在数据冗余的数据引用之间做好平衡。比如用户表里的用户粉丝,我会这样设计:{'u': 'admin', 'e': 'x@x.cc', 'tel': '110', 'sex': 1, 'fs': [{'u': 'user1', 'sex': 1}, {...}]}。经常和用户一起查询出的粉丝信息内嵌入文档中(用户名,性别),避免跨表查询;而其余信息则使用用户引用查询(邮箱,电话)

核心思想

在MongoDB中,没有表、列的概念,取而代之的是集合(collection)、文档(document)库(DB):数据库,包含多个集合

当前数据库名存储在全局变量db中

admin库,库中用户有数据库所有权限,local库,不可复制,本地数据库,config库

集合(Collection):一组文档

以名称进行标识,不能为空字符串

不能以system.开头,不能使用字符$(特殊含义字符)

文档(Document):键值对的一个有序集,即有序的哈希表

键值不能有'\0'

不能存在.和$

区分类型("1"和1)与大小写

MongoDB内置Javascript解释器,它的文档是JS中的对象({...}),就是那种没成员函数的对象

MongoDB运行于27017端口,且启动后会在28017端口启动一个基本的Http服务器。启动后会连接到test数据库,use [database]切换当前数据库

MongoDB以BSON格式保存数据,即Binary Json

CRUD操作

观察发现:MongoDB中的方法函数基本都是以Javascript命名习惯的,即word1Word2Word3,如addEventListener

文档插入后会自动添加一个_id属性,为唯一标识符{"_id": ObjectId("56064886ade2f21f36b03134")}

Create

创建数据库

> use [newdbname]//不存在则会创建

创建collections

db.createCollection()

创建集合

集合的insert方法,插入单个文档

db.collection.insert({

key1: value1,

ley2: value2

})

Read

集合的find方法,第一个参数是用来确定返回的文档,第二个参数确定返回的键值的过滤条件

db.collection.find()// 返回全部文档

db.collection.find({"age": 20})// 按条件查询

db.collection.find({

"age": 20,

"name": "ivan"

})// condition1 && condition2

返回指定键值

db.collection.find({}, {key1: 1})// 会返回"_id"和key1

db.collection.find({}, {key1: 0})// 不返回key1

查询条件$lt$lte$gt$gte$ne<<&#61;>>&#61;!&#61;

db.collection.find({

"age": {"$gt": 18, "$lt": 30}

})// 返回年龄18<<30$in$nin$or$not$size指定列表&#xff0c;成员可为不同类型不在列表中条件逻辑或元操作符&#xff0c;可用于其余任何条件大小

db.collection.find({

"number": {"$in": [1, 2, 3]}

})

db.collection.find({

"$or": [{key1: value1}, {key2: value2}]

})

db.collection.find({

"$not": {"age": 20}

})

db.collection.find({

"name": {"$size": 4}

})

null值

db.collection.find({key1: null})// 会返回所有无key1键的文档

RegExp

db.collection.find({"name": /^[a-z]{0,4}$/i})// 可加入正则flag位&#xff0c;如i忽略大小写

$slice&#xff0c;返回键中数组切片

db.collection.find({},

{"comments": {"$slice": 10}})// 返回前十切片

db.collection.find({},

{"comments": {"$slice": 10}})// 返回后十切片

db.collection.find({},

{"comments": {"$slice": [23, 10]}})// 返回24~33切片&#xff0c;神奇的左开右闭

$where&#xff0c;危险语句&#xff0c;可执行任意JS函数

db.collection.find({"$where": function(){

for (var i in this){

for (var j in this){

if (i!&#61;j && this[i]&#61;&#61;this[j])

return true;

}

}

return false;

}})

其实就是传入一个返回值为bool的匿名函数&#xff0c;对文档进行选择

游标

var cursor &#61; db.collection.find();

while (cursor.hasNext()){

//do sth by use cursor.next()

}

limit、skip、sort方法

db.collection.find().limit(3)

db.collection.find().skip(3)

db.collection.find().sort({key1: 1, key2: -1})//键值1为升序&#xff0c;-1降序

Update

修改器

$inc&#xff0c;原子操作&#xff0c;并发安全

db.collection.update({key: value}, {"$inc": {a: 1}})//find操作后键值a会自增1

$set&#xff0c;存在则修改&#xff0c;不存在则创建&#xff0c;就像sql语句的REPLACE一样

db.collection.update({"_id": "xxxxxx"}, {"$set": {key: value}})

$unset&#xff0c;set的逆操作

$push&#xff0c;修改文档数组&#xff0c;因为Javascript的数组增删元素就是用push&pop

$each&#xff0c;批量修改数组

db.collection.update({}, {"$update": {key: {"$each": [val1, val2, val3]}}})

$addToSet&#xff0c;同一般语言中set&#xff0c;去重

upsert操作&#xff1a;指定update的第三个参数进行原子操作

db.collection.update({}, {"$inc": {a: 1}}, true)//true为upsert操作

更新多个文档&#xff0c;指定第四个参数

db.collection.update({}, {"$set": {key: 1}}, false, true)//true为更新多个文档

Delete

db.collection.remove()//删所有文档

db.collection.remove({key: value})//指定查询条件

db.collection.drop()//删集合

db.dropDatabase()删库

NoSQL注入

我将MongoDB装在我的Debian 9虚拟机上&#xff0c;创建了以下内容&#xff1a;

> use sqli

switched to db sqli

> db

sqli

> db.createCollection("users")

{ "ok" : 1 }

> db.users.insert({"uname": "admin", "passwd": "admin"})

WriteResult({ "nInserted" : 1 })

> db.users.insert({"uname": "iv4n", "passwd": "iv4n"})

WriteResult({ "nInserted" : 1 }

> db.users.find()

{ "_id" : ObjectId("5ba3412314139eac63f891f7"), "uname" : "admin", "passwd" : "admin" }

{ "_id" : ObjectId("5ba3424114139eac63f891f8"), "uname" : "iv4n", "passwd" : "iv4n" }

以下是PHP代码&#xff0c;这里是PHP 7.x&#xff0c;和5.x的mongoDB库使用有差异&#xff1a;

// init mongoDB engine

$server &#61; new MongoDB\Driver\Manager("mongodb://localhost:27017");

$uname &#61; $_POST["uname"];

$passwd &#61; $_POST["passwd"];

$filter &#61; ["uname" &#61;> $uname,

"passwd" &#61;> $passwd,

];

$option &#61; [

"projection" &#61;> ["_id" &#61;> 0],

"sort" &#61;> ["_id"&#61;> -1],

];

$query &#61; new MongoDB\Driver\Query($filter, $option);

$cursor &#61; $server->executeQuery("sqli.users", $query);

foreach ($cursor as $doc){

if ($doc->passwd &#61;&#61; $passwd){

echo "Login Successfully!
";

echo "username is: ".$doc->uname."
";

echo "password is: ".$doc->passwd."
";

} else {

echo "Invalid user and pass";}

}

?>

index页面为一个post方法登录

这里的filter为查询条件&#xff0c;语句为db.users.find({"uname": $uname, "passwd": $passwd})

正常登录&#xff0c;用户名密码错误无回显

$ne选择器注入&#xff0c;返回所有不等于的document&#xff0c;传入数据库的语句实际是db.users.find({"uname": {"$ne": "a"}, "passwd": {"$ne": "a"}})&#xff1a;

可以看到&#xff0c;返回了数据库的全部信息

$lt/$gt注入&#xff1a;

前面说过&#xff0c;MongoDB内置的是Javascript的解释器&#xff0c;所以它在字符串的大小判断也遵循JS的逻辑

JS的字符串大小判断逻辑&#xff1a;按字节从左比较ascii码&#xff0c;假如相等则比较下一字节&#xff0c;不等则返回当前位的比较结果

所以我们可以利用大小操作符来注入&#xff1a;

正则注入&#xff1a;

$regex&#xff0c;传入数据库的语句实际为db.users.find({"uname": {"$regex": "^a"}, "passwd": {"$ne": "a"}})

可以看到&#xff0c;返回了以a开头的用户信息&#xff0c;实际上它和SQL的正则盲注是一样的道理

未授权访问

MongoDB最初安装部署后是不会添加auth选项的&#xff0c;一般的初始化步骤是&#xff1a;不开启auth选项时连接数据库&#xff0c;添加管理员账户

开启auth&#xff0c;利用管理员账号登录连接&#xff0c;添加数据库账户

但是很多开发者并不知道这些Tips&#xff0c;没有开启auth选项&#xff0c;且数据库监听了公网&#xff0c;就导致了MongoDB的未授权访问

其实MongoDB的未授权访问和Redis数据库是差不多的&#xff0c;这里利用一个工具NoSQLMap来进行数据库信息枚举&#xff0c;有SQLMap那么也就有针对NoSQL数据库的NoSQLMap&#xff0c;它可以注入以及利用未授权访问漏洞

我将数据库不开启auth启动&#xff0c;然后NoSQLMap的1选项设置想关信息

接着点击2选项&#xff0c;提示存在未授权访问漏洞

点击枚举数据库信息

这个工具目前来说还不是很完善&#xff0c;动不动就会直接exception退出&#xff0c;和SQLMap相比差距还是很大&#xff0c;



推荐阅读
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • uniapp开发H5解决跨域问题的两种代理方法
    本文介绍了uniapp开发H5解决跨域问题的两种代理方法,分别是在manifest.json文件和vue.config.js文件中设置代理。通过设置代理根域名和配置路径别名,可以实现H5页面的跨域访问。同时还介绍了如何开启内网穿透,让外网的人可以访问到本地调试的H5页面。 ... [详细]
author-avatar
yzh148448
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有