NoSQLインジェクションアルファベット

SQLインジェクションがあります! NoSQLインジェクションは可能ですか? はい! Redis、MongoDB、memcached-これらのソフトウェア製品はすべて、一般的なMySQL、Oracle Database、MSSQLの反対の非リレーショナルDBMSのクラスに属します。 これらのデータベースへの関心が最近大幅に高まっているため、すべてのストライプのハッカーがそれらのデータベースをすり抜けることはできません。









NoSQLとは何ですか?



データベースは、相互接続されたエンティティ(テーブル)で構成されているため、DBMSのリレーショナルモデルに精通していると思います。 データは、構造化照会言語であるSQLを使用してアクセスされます。 リレーショナルDBMSの例(MySQL、Oracle、Microsoft SQL Server)を探す必要はありません。 アーキテクチャが従来のリレーショナルモデルとは異なる他のすべてのDBMSは、NoSQLソリューションのクラスに安全に帰属できます。



NoSQL-DBMSとそのSQL指向の競合他社との主な違いは、単一の統一されたクエリ言語がないことです。 たとえば、MongoDBはクエリ言語としてBSONを使用し、eXistはXQueryを使用します。SonicGraphDBは、グラフ形式のデータをクエリするための言語であるGraphQLを開発者が知っている必要があります。 NoSQL-DBMSの人気は日々高まっており、それはあなたと私に影響を及ぼしています。 まもなく明日、文字通り、SQLインジェクションを探す必要はありませんが、次のプロジェクトではNoSQLインジェクションを探す必要があります。 時間を無駄にせず、潜在的な脆弱性について話しません。



NoSQL DBMSはとても安全ですか?



SQLを使用せず、攻撃者がSQLインジェクションなどの攻撃を実行できないため、非リレーショナルDBMSは安全であるという声をよく耳にします。 ある程度、これは事実です。SQLなし-SQLインジェクションなし。 しかし、SQLコードをシステムに注入することが不可能な場合、これは安全であるという意味ではありません。 NoSQLは潜在的な脆弱性を1つ閉じますが、さまざまな悪意のあるアクションを実行できるようにする他の12の脆弱性を開きます。



NoSQLデータウェアハウスにアクセスできる典型的なアプリケーションアーキテクチャを検討してください。 通常、次の3つのレベルで構成されます。



攻撃者はこれらの各レベルを攻撃できます。 最下位レベルから、つまりDBMSから直接始めましょうアプリケーションと同様に、DBMSはバッファオーバーフロー攻撃を受けやすく、認証スキームが脆弱である可能性があります。 このレベルを攻撃することは非常に困難です。なぜなら、製品と開発会社の周りに形成されたコミュニティは、発見されたエラーを修正しようとしているからです。 ただし、非常に大きな利点があります。ほとんどのソフトウェア製品にはソースコードが付属しているため、完全に分析して価値のあるものを見つけることができます。 運がよければ、ほとんどすべてのデータベースの鍵になります! 次のレベルはクライアントAPIです。 ほとんどのNoSQL DBMSには、データにアクセスするためのさまざまなライブラリの動物園があります。 ほとんどのライブラリはオープンソースプロジェクトですが、それらの一部はもはやサポートされていないことに注意してください。 クライアントライブラリの脆弱性を検出する確率は、DBMS自体で直接検出するよりもはるかに高くなります。 また、このAPIに基づいて構築されたすべてのアプリケーションへのアクセスを許可する唯一の脆弱性を見つけることができなかったとしても、クライアントコードとデータベースサーバー間の対話がどのように行われるか、どのプロトコルが使用され、セッションをインターセプトできるかどうかを想像できます。

そして最後に、トップレベルはあなたがハッキングしようとしているアプリケーションです。 ここでは、まず、プログラマが入力データを確認するのを忘れた場所を見つけて、それを悪用しようとする必要があります。 この場合、SQLインジェクションを検索するときと同じアプローチを使用する必要があります。つまり、コードとエラーメッセージを分析する必要があります。今回は、JSON、JavaScript、または同様のものを扱う必要があります。

それでは、ハックの時間です! 今日の目標は、最も一般的なNoSQL DBMSの1つであるMongoDBです。



MongoDBでのNoSQLインジェクション



小さなWebアプリケーションをクラックします。 そのソースコードを次に示します (インストールプロセスの詳細は、README.RU.txtファイルに記載されています)。 インストールが成功した場合、アプリケーションはhttp://127.0.0.1 {1337。 今日議論される主な攻撃:



正規表現を使用する際のエラーを使用したハッキン​​グから始めましょう。





MongoDB Webインターフェイス


正規表現



MongoDBは、他の多くのNoSQL DBMSと同様に、正規表現を使用して検索できます。 これは非常に強力ですが、同時に不適切に使用すると重大な損害を引き起こす危険な治療法です。

MongoDBは$ regex演算子を使用して、正規表現を使用して検索します。 たとえば、「ログインが「ro」で始まるすべてのユーザーに戻る」というクエリは次のようになります。



db.users.find({ login: { $regex: "^ro" } })
      
      





ちなみに、MongoDBクエリ言語に慣れていない場合は、開発者ガイドから学習を始めることをお勧めします。 しかし、アプリケーションに戻ります。 テストWebサイトを開き、MongoDBメニューで「正規表現のインジェクション」を選択します。





テストアプリケーションのユーザー認証ページ


このページの仕組みを見てみましょう。 Libフォルダーのmongodb.jsファイルを開きます。 MongoDbControllerクラスを実装します。このクラスは、アプリケーション内のすべてのページの機能を担当します。 ここで、regexpメソッドに興味があります。



 var regexpPwd = new RegExp("^" + password, "i"); var loginParam = { login: login, password: regexpPwd };
      
      





ご覧のとおり、ユーザー認証は、正規表現をパスワードとして指定する要求を通じて行われます。 同時に、パスワード変数は一切フィルタリングされないため、アクションの完全な自由が与えられます。 ここでは、パスワードの代わりにルートのユーザー名と正規表現を指定できます(例:[\ s \ S] *)。 その結果、MongoDBは「db.users.findOne({login: 'root'、password:/ ^ [\ s \ S] * / i})」というリクエストを実行し、脆弱なサイトにrootとして正常にログインします(thisこの手法は、従来のSQLインジェクション「1 'または1 = 1-」に似ています)。 このような攻撃から身を守ることは非常に簡単です。 まず、入力データがどこから来たかに関係なく、常にユーザーから、または外部ファイルから、またはデータベースから入力データをチェックします。 プログラムでデータを使用する前に、確認する必要があります。 次に、本当に必要な場合にのみ正規表現を使用します。 たとえば、上記のクエリは次のように書き換えることができます。



 db.users.findOne({ login: 'root', password: 'p@ssw0rd' })
      
      





ご覧のとおり、より安全で高速です。



JSON注入



はい、MongoDBはSQLをサポートしていませんが、DBMSはクエリ言語なしでは実行できません。 MongoDB開発者は、SQLの代わりに一般的なJSONテキスト交換フォーマット(BSON)を使用することにしました。 したがって、さまざまな種類のインジェクション攻撃を実行できます(もちろん、入力データがフィルター処理されていない場合)。 このような攻撃は、一般的にJSONインジェクションと呼ばれます。

そのため、アプリケーションを再度開き、「JSON Injection」ページに移動します。 前の例のように、ユーザー名とパスワードを入力するフィールドが表示されます。 このページで認証プロセスを担当するコードを見てみましょう。 これは、MongoDbControllerクラスのjson-injectionメソッドに含まれています。



 var loginParam = eval("({ login: '" + login + "', password: '" + password + "' })");
      
      





上記のコードは、JavaScriptオブジェクト(MongoDBへのリクエスト)のテキスト表現をオブジェクトに変換します。 このオブジェクトをデータベースサーバーに転送すると、ユーザー認証が行われます。 このコードには非常に弱点が1つあります。入力データは一切制御されていないため、ほとんどすべてのクエリをデータベースに生成できます。 たとえば、ユーザー名「root '})//」(パスワードはオプション)を指定し、「ログイン」ボタンをクリックします。 おめでとうございます、再びログインしました! どうして起こったの? すべてが非常に簡単です。 ユーザー名「root '})//」を指定すると、eval関数で次のトリックが発生しました。



 //  ({ login: 'root'})//', password: '' }) //  db.users.findOne({ login: 'root' })
      
      





実際、このスクリプトはWebサーバー上でJavaScriptコードを実行できるため、さらに危険です。 たとえば、ユーザー名「 '+ process.execPath})//」は、次の形式のクエリを形成します



 db.users.findOne({ login: 'C:\\node.exe' })
      
      





このタイプの脆弱性は、サーバーサイドJavaScriptインジェクションまたは単にSSJIと呼ばれます。

このような攻撃から身を守る方法は?

  1. 外部ソースからのすべてのデータを確認してください。 たとえば、ログインは正規表現「^ [a-zA-Z] + $」と一致する必要があります。
  2. JSONを操作するためにeval関数を使用しないでください。 JSON.parse関数はNode.jsで使用できます。Node.jsは、入力文字列を解析し、それに基づいてオブジェクトを作成します。






テストアプリケーションでの成功した認証


RESTインターフェースの操作



インターネットとサービス指向アーキテクチャ(SOA)の急速な発展により、RESTソリューションはますます人気を集めています。 最新の非リレーショナルDBMSは最新の業界トレンドに従って編成されているため、これらのシステムの多くはRESTを実装するか、サードパーティ製品を使用してRESTfulアーキテクチャを使用してデータにアクセスします。 MongoDBも例外ではありません。このDBMSには、読み取り専用モードでデータにアクセスできるシンプルなRESTインターフェイスが含まれています。 さらに、完全なRESTサポートを実装するSleepy Mongooseというプロジェクトがあります。

MongoDBに組み込まれたRESTインターフェースがどのように機能するかを見てみましょう。 DBMSサーバーは、「-rest」パラメーターで起動する必要があります。 RESTサービスは、http://127.0.0.1:28017 /で入手できます。 これは、DBMSの現在の状態に関する情報を表示し、データベースクエリを生成できる非常にシンプルなWebアプリケーションです。 興味深いリンクを次に示します。



一般に、データベースへのRESTリクエストを生成するには、次の形式のURLが使用されます。



http://127.0.0.1:28017/_//?filter_=







Webアプリケーションの「RESTインターフェースを使用した操作」ページで、MongoDB RESTインターフェースを使用してユーザー認証が実行されます。 MongoDbControllerクラスのrestメソッドに実装されています。



 var restQry = "/secure_nosql/users/?filter_login=" + login + "&filter_password=" + password; var hash = restQry.indexOf("#"); if (hash > -1) { restQry = restQry.substring(0, hash); }
      
      





スクリプトはRESTリクエストを生成し、「#」文字の後のすべてのデータを無視します。 REST要求の準備ができると、スクリプトはサーバーへのHTTP要求を生成し、JSON形式の結果を予期します。 たとえば、secure_nosqlデータベースのルートユーザー情報のリクエストは、http://127.0.0.1:28017 / secure_nosql / users /?filter_login = root&filter_password = p @ ssw0rdのようになります。 すべて問題ありませんが、「#」記号を処理するときに現れるコードにエラーがあります。 「ルート#」という名前でログインしようとすると、システムにログインします。 この問題は、次のURLの形成により発生します:http:// localhost:28017 / secure_nosql / users /?Filter_login = root#&filter_password =。 filter_passwordパラメーターが無視され、認証がリクエストhttp:// localhost:28017 / secure_nosql / users /?filter_login = rootを介して実行されたという事実から成ります。

ほとんどのRESTインターフェイスは、クロスサイトリクエストフォージェリ(CSRF)に対しても脆弱であることに注意してください。



 <img src="http://localhost:28017/secure_nosql/users/" />
      
      





正直なところ、私はRESTfulアーキテクチャについてかなり懐疑的です。RESTfulアーキテクチャは攻撃者にとって大きなチャンスを開くからです。 RESTを使用しないようにしてください。 しかし、それがなければ、まずクロスサイトリクエストフォージェリの堅牢な防御の記事を読んでください。RESTセキュリティのすべての側面について詳しく説明しています。



Javascriptインジェクション



最新のリレーショナルDBMSでは、ストアドプロシージャを作成できます。 ANSI SQLの機能を拡張し、ほぼすべてのビジネスアプリケーション要件に準拠できるMicrosoft SQL Serverを見てみましょう。 T-SQLの機能が不足している場合(これはSQL Serverに実装されたSQLの方言です)、C#またはその他の.NET互換言語でストアドプロシージャを記述できます。

MongoDBには、サーバーサイドJavaScriptなどの豊富な機能があります。 実際、ほとんどすべてのコードをデータベースサーバーで実行できます。 一方では、これにより、データ処理用の非常に複雑なアプリケーションを作成できます。他方では、アプリケーションの脆弱性が高まります。

MongoDBのJavaScriptはどこで使用できますか?

  1. $ where演算子を使用したクエリ 。 たとえば、クエリdb.orders.find({$ where:“ this.amount> 3”})は、3つ以上のアイテムを持つ注文のリストを返します。
  2. Db.evalチーム 。 たとえば、db.eval( "function(x){return x * x;}"、2)は4を返します。
  3. データベースに保存する関数 。 MongoDBを使用すると、JavaScriptで記述された関数をデータベースに保存できます。 このために、特別なシステムコレクションsystem.jsが使用されます。 新しいストアド関数foo(x)を作成するには、次のコードを実行します。



      db.system.js.save( { _id: "foo", value: function (x) { return x * x; }})
          
          





    これで、db.eval( "foo(2)")のように呼び出すことができます。
  4. マップ/縮小 。 Map / Reduceは、Googleが大量のデータを対象とした並列コンピューティング用に開発したソフトウェアフレームワークです。 これには、データの前処理に使用されるmapと結果を検索するreduceの2つの操作が含まれます。

    MongoDBを使用すると、データベースサーバーでマップを実行したり、操作を削減したりできます。 DBMSはプロセスの並列化と集約を処理し、開発者はmapとreduceコマンドを実装する初期データと関数を指定するだけです。 詳細については、 MongoDBのドキュメントをご覧ください。


テストアプリケーションの$ whereステートメントにJavaScriptインジェクションがあり、db.evalコマンドに同様の脆弱性があります。

$ whereステートメントから始めましょう。 アプリケーションを開き、「JavaScriptインジェクション」メニューで$ whereアイテムを選択します。 ページ上の認証は、MongoDbControllerクラスのssji-whereメソッドで実装されます。



 var js = "this.login === '" + login + "' && this.password === '" + password + "'"; var loginParam = { "$where" : js };
      
      





最初に、ユーザー名とパスワードをチェックするスクリプトが生成されます。 残念ながら、パスワードおよびログイン変数のデータはまったくチェックされないため、サーバー上で任意のスクリプトを実行できます。

次に、rootとしてログインしてみましょう。 ユーザー名「root '//」を入力して、ログインしてみます。 もう一度、ログインに成功しました! これは、MongoDBへの次のリクエストがサーバーで生成されたために可能です。



 { '$where': 'this.login === \'root\' //\' && this.password === \'\'' }
      
      





「//」はJavaScriptのコメントなので、結果のクエリは「this.login === 'root'」の形式になります。

幸いなことに、リクエストが実行された時点では、データベースは「読み取り専用」モードになっているため、攻撃者はデータを変更するスクリプトを作成できません。 しかし、これはそのような攻撃が不可能であることを意味しません。 「JavaScriptインジェクション-db.eval(...)」ページを開きます。 今回は、データベースサーバーでeval関数を呼び出して認証を行います。



 var js = "function () { return db.users.findOne ({ login: '" + login + "', password: '" + password + "' }); }" db.eval(js);
      
      





ご覧のとおり、データベースサーバー上で任意のコードを実行できます。 pen_testパスワードで新しいpen_testユーザーを作成してみてください。 これを行うには、次のログインを入力します。



 '}), db.users.insert({login: 'pen_test', password: 'pen_test'}), 1 } //
      
      





まず、ログインします。 次に、データベースに新しいユーザーpen_testが登場しました。 :-)

サーバーサイドJavaScriptには大きな可能性があり、同時に多くの危険が伴います。 コードの1つの小さな間違い。攻撃者はデータベースサーバーにアクセスします。 サーバー側スクリプトを使用しないことを強くお勧めします。リクエストの85%は、スクリプトなしで作成できます。





テストアプリケーションへのアクセスが拒否されました




おわりに



結論として、NoSQLコミュニティの現在と未来をどのように見ているかについてお話したいと思います。 まず、NoSQL DBMSがまだ主流ではないことを確認しましたが、これにかなり近いです。新しい非リレーショナルDBMSとそれを使用するプロジェクトが表示されます。 近い将来、NoSQLソリューションは、負荷の高いアプリケーションの市場で比較的大きなシェアを占めるように思われます。 第二に、現代のNoSQL-DBMSのセキュリティには多くの要望が残されています。 リレーショナルデータベースの世界に1つの標準化されたクエリ言語-SQLがある場合、「非リレーショナルの世界」では、誰でも好きなようにクエリ言語を実装します:JSON、XQuery、RESTインターフェイス。 したがって、はるかに多くの潜在的な脆弱性があります。 リレーショナルデータベースを操作するときに、SQLインジェクションとその処理方法を学習するだけで十分な場合(同時に、MySQLとOracleまたはSQL Serverの両方で既存の知識を適用できます)、非リレーショナルデータベースではそれほど単純ではありません。 最初に、DBMSで使用されているクエリ言語、データへのアクセス方法、およびハッキングに使用できる追加機能(MongoDBのサーバー側JavaScriptなど)があるかどうかを把握する必要があります。 情報を収集したら、システムの潜在的な脆弱性とそれらの修正方法を見つける必要があります。



近い将来、状況が変わることを願っています。より多くの情報がパブリックドメインに表示され、NoSQL-DBMSの使用に関連する脅威から保護することは、通常のSQLインジェクションと同じくらい簡単になるでしょう。




NoSQL FAQ



Q: NoSQLという用語の由来は何ですか?

A: NoSQLは「SQLなし」(SQLなし)としてではなく、「SQLのみ」(SQLのみではない)として翻訳されます。 この用語は1998年に始まりました。それが、カルロストロッツィが非リレーショナルデータベース管理システムと呼んだものです。 2009年に、無料の分散データベースに関する会議でEric Evansが非リレーショナルDBMSとデータウェアハウスを参照するために使用したときに、彼は生まれ変わりました。 NoSQLソリューションブームの基盤を築いたのはこの会議であると推測できます。



Q: MongoDBとは何ですか?

A: MongoDBは、2007年10月から10genによって開発されたオープンソースのドキュメント管理データベースシステムです。 最初のMongoDBリリースは2009年2月にリリースされました。 DBMSは、負荷の高いプロジェクトにデータを保存するためのソリューションとして位置付けられています。 その主な利点には、高性能、優れたスケーラビリティ、フォールトトレランス、および開発者とユーザーの広範なコミュニティの存在が含まれます。 現時点では、MongoDBユーザーの中には、ディズニー、SAP、フォーブスなどの世界的に有名な会社があります。



Q:なぜNoSQLなのですか?

A: NoSQLデータベースがリレーショナルデータベースよりも優れている主な利点を見てみましょう。

  1. 生産性 :ほとんどのNoSQL開発者は、プロジェクトの最適化に多くの時間を費やしています。 MongoDBでは、1秒あたり約20,000の挿入と4800のサンプルを達成できます。
  2. データベース複製の簡単な構成 。 MongoDBを使用すると、わずかなコマンドでレプリケーションを構成できます。つまり、同じOracleよりもはるかに簡単です。
  3. プログラマーの生活を楽にする多くの「グッズ」 。 たとえば、MongoDBにはMap / Reduceおよび複雑なデータ構造のサポートが組み込まれています。
  4. スケーラビリティ 。 これは、NoSQL-DBMSの主要な切り札の1つです。 それらのほとんどは水平スケーリングをサポートしており、これは機器の大幅なコスト削減に貢献します。これは、企業サーバーにプロセッサとRAMのペアを追加するよりも、クラスター用に別の安価なサーバーを購入する方が安いためです。
  5. 彼らは安いです! ほとんどのNoSQLソリューションはオープンソースプロジェクトです。 今すぐダウンロードして、使用を開始できます。 多くのプロジェクトの周りに、大規模で緊密なコミュニティが形成されています。これは、発見したバグを常に支援し修正する準備ができています。 最終的には、自分でバグを修正したり、必要な拡張機能を記述したりできます。 さらに、非リレーショナルDBMSはリレーショナルデータベースよりもはるかに単純であり、ほとんどの場合、特別な従業員を必要としないため、データベース管理者の費用を大幅に節約できます。


Q: NoSQLは誰が使用しますか?

A:ご覧のとおり、NoSQL DBMSには多くの否定できない利点があります。 誰がそれらを使用するか考えてみましょう:





画像

ハッカーマガジン、 2月(02)157

イリヤ・ヴェルビットスキー( blog.chivavas.org



ハッカーを購読する








All Articles