泛指非关系型的数据库,多和关系型数据库共存
特点:
不要预定义表,可以存储非结构化数据,数据量大,用于模糊处理,使用灵活,可拓展等
代表数据库:
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命令,可以直接执行语句。同样是存在字符串拼接的问题,因此通过使用单引号、双引号构造闭合语句,就可以执行任意的语句。 |