泛指非关系型的数据库,多和关系型数据库共存

特点:

不要预定义表,可以存储非结构化数据,数据量大,用于模糊处理,使用灵活,可拓展等

代表数据库:

MongoDB(默认端口号27017)、Redis(默认端口号:6379)、Memcache

数据类型:

类型 用法 说明
布尔型 {“a”:true} 与java的boolean一样
Null {“a”:null} null表示空值或者不存在的字段
数值 {“a”:1.34}{“a”:NumberInt(“3”)} 表示4字节的整数 不区分整数或浮点
字符串 {“a”:”string”} UTF-8的字符串
日期 {“a”:newDate()}
数组 {“a”:[“b”,”c”,”d”]}
内嵌文档 {“a”:{“b”:”c”:”d”}}
对象id {“a”:ObjectID()} 对象id一个12字节的ID,文档的唯一表示,对象的默认主键_id就是一个对象id

MongoDB操作

操作 语句
开启服务 sudo mongod
登陆mongodb数据库 mongo –host 127.0.0.1

数据库的操作

操作 语句
查看所有的数据库 show dbs
切换数据库 use 数据库名
查看集合 show collections
数据库的创建 user数据库名。有值自动创建,当use的时候,系统就会自动创建一个数据库。
删除数据库 进入数据库后db.dropDatabase(); 注意:如果没有选择任何数据库,会删除默认的test数据库

集合的操作

操作 语句
查看集合 show collections
创建集合 db.createCollection(“xxx”)
删除集合 db.xxx.drop()

文档(行)的增删改

操作 语句
增加数据 db.xx.insert({key:value})
举例:
db.ichunqiu.insert({_id:1,name:”web”,age:10})
删除数据 db.xx.remove(删除的条件)
1、全部删除:
db.xx.remove({})
2、根据条件删除,默认是删除所有符合条件的数据:
db.xx.remove({age:10})
3、只删除符合条件的第一个:
db.xx.remove({gender:true},{justOne:true})
更改操作 db.xx.update({查找的条件},{修改的内容})
1、修改内容:
默认其他原有字段删除了,替换掉原有数据db.xx.update({age:10},{name:”NoSQL ”})
2、保持原有的字段,加一个修饰$set:
默认只修改第一个且对已存在的原有属性是替换,不存在的属性是添加db.stu.update({age:10},{$set:{like:“study”}})
说明:把like:”study”添加到数据里面,并不是替换

文档查询简单语句:

操作 语句
基本查询 db.xx.find({查询条件})
1、查询所有的数据:
db.xx.find() 或db.xx.find({})
2、默认查出所有符合条件的数据:
db.xx.find({age:10})
3、查找符合条件的第一个:
db.xx.findOne({age:10})
4、格式化输出——pretty()函数:
db.xx.find({age:10}).pretty()
条件查询 举例:
db.xx.find({age:{$lt:20}}) 查询年龄小于20岁的
db.xx.find({age:{$ne:18}}) 查询年龄不等于18的
逻辑运算 $and,$or
1、$and:
默认的的查询条件就是且的关系
举例:
db.xx.find({age:28,gender:true})db.xx.find({$and:[{age:28},{gender:true}]}) 查询年龄是28岁且性别为女
2、$or:
或的关系 举例:
db.xx.find({$or:[{age:{$lt:30}},{gender:false}]}) 查询年龄小于30岁,或者性别为男

条件查询–常用条件:

函数 字符
$lt <
$ne !=
$or or
$lte <=
$in in
$not 反匹配(1.3.3及以上版本)
$gt >
$nint not in
$regex 正则
$gte >=
$all all

Nosql注入

分类 说明
综合分类(4种) 重言式/永真式(重要)
JavaScript注入(难度较大)
联合查询注入(被淘汰)
mongo shell拼接注入(难度中等,危害大)
语言、代码逻辑角度分类(3种) PHP数组注入
JS注入
Mongo shell拼接注入
攻击手段角度分类(3种) 重言式(永真式)
联合查询
JavaScript注入
分类 说明
重言式/永真式 /login.php?username[$ne]=1&password[$ne]=1
防御:
可以通过函数is_array()将输入参数转变为字符串类型来解决
如:
db->logins->find(array("username"=>(string)$_POST["username"],"password"=>(string)$_POST["password"]));

注意:
1、必须要结合PHP语言才能导致重言式注入(依据PHP语言的特性)
2、如果是POST方法传参,可以结合BurpSuite抓包、改包进行绕过。
3、使用正则表达式,也可以构造永真式如:
username[$regex]=.?&password[$regex]=.?
.?为匹配所有字符串
变为 ?username[$regex]=^a&password[$regex]=.?
不断爆破a即可,^ab…直到爆不出,爆破字符为数字字母符号,符号需要转义
JavaScript注入 ';return true;var a='
注入产生的原因
1、MongoDB中$where操作符是可以执行JavaScript语句的。
2、在PHP语言中是不能直接写入JavaScript语句的,需要写在字符串中。使用字符串就会引用到单引号和双引号,因此容易出现闭合的问题
3、在MongoDB 2.4之前,通过$where操作符使用map-reduce、group命令可以访问到mongo shell中的全局函数和属性。也就是说可以操作数据库中的数据。

注意:
1、闭合的方法有很多,只要return的值为真即可。
2、该注入方法较难,主要是因为payload不易构造,在有源码的情况下容易构造闭合语句,没有源码只能猜测。
3、$where执行的JavaScript语句只能进行简单的逻辑操作。
mongo shell拼接注入 "});db.表名.insert({"name":"hi"});db.表名.find({"author":"1
在两个db.message.find中间的位置,插入任意想要执行的代码
产生的原因:
PHP中,通过executeCommand可以执行shell命令,可以直接执行语句。同样是存在字符串拼接的问题,因此通过使用单引号、双引号构造闭合语句,就可以执行任意的语句。