免責事項:私はコンピュータープログラマーであり、セキュリティアナリストやセキュリティとは関係ありません。暗号の世界での経験はありませんので、ご容赦ください。
状況:クライアントのサイトをデータホスティングサイトに統合するタスクが与えられました。その作業中に、すべてのユーザーのデータをダンプするクエリに遭遇しました。このクエリを作成するには、ユーザーは「認証」してセッションを取得し、そのセッションコードを使用してこのクエリを作成する必要があります。次に、クエリを完了して応答する前に、ユーザーが管理者権限を持っていることを確認します。
しかし、それでも...それは私にはちょっと恐ろしいようです。特にこれは、クエリが正常に実行された場合に返されるデータの一部であるためです。
"username": "[email protected]",
"firstname": "Test",
"lastname": "Name",
"userpassword": "$1$te000000$qMpAriadAHuRyDkK58YKS0"
公開するのが恐ろしいほど多くのデータが返されますが、それは私の主な関心事ではありません。
明らかに「テスト名」という名前の人はいません。「testemail.blerg」は登録ドメインではなく、「blerg」はトップレベルドメインの可能性があることは言うまでもありません。使用されていたとしても、そのアカウントはデータホスティングサイトから削除されており、ログインできません。使用されたパスワードは脆弱なテストケースのパスワードであり、誰も使用していません。
私はブルートフォース/レインボーテーブル(私は経験がありませんが、いくつかのフラッシュワード:Pを知っています)またはそれからパスワードを取得するために何かすることは可能ですか?少し(私が思うに)知っていることは、userpassword
の最初の部分がMD5ソルトであることですが、他には何も知りません。
誰でも簡単に説明できる場合は、このサイトが完全に恐ろしいことを上司に証明し、クライアントにこのデータホスティングサイトからの移行を説得することができます。
ソルティングについて知っていることは他にもあります(つまり、ソルトを取得する方法、使用している言語/関数など)が、その情報にアクセスできない人が簡単に理解できることを知りたいですアウト。うまくいけば、私が上司に行くためのもう1つのこと。
編集:法的/その他の理由により、これがどのCRMであるかを示すことを防ぐ目的で部分的に説明が曖昧になっていることに関連して、少し混乱しているようです。また、「データホスティング」と呼んでいると誤解を招く可能性があるため、残念です。うまくいけば、これは明らかにします:
私たちのチームが行っている仕事は、企業が自社製品を自慢するための基本的なウェブサイトを作成することです。 CRMとのやり取りは次のとおりです。
POST
オブジェクトとユーザーの情報をContacts
します。GET
のリストに対してDealers
を実行します。#2、GET
API呼び出しから始めましたが、Users
テーブルをクエリできることがわかりました。私はAPIを作成していません。それをリクエストしているだけです。
GET
呼び出しにはparam query=
が必要です。値はシステムのクエリ言語のSELECT
ステートメントで、SQLに変換されます(おそらくSQLI攻撃を防ぎますが、私はしません) tがSQLをどのように解釈/変換するかを知っているので、10フィートの極では触れません。クエリでSELECT * FROM Dealers;
をSELECT * FROM Users;
に変更することで、すべてのユーザーのデータを確認できました。
CRMがユーザーを処理する方法は、サイトのポータルを使用することです。ユーザーはポータルに作成され、「Is Admin」チェックボックスがあります。これは、ポータルを介していつでも編集できます。これは、APIリクエストを行うプロセスです。
ユーザーは、ユーザー名を含むCRMにトークンを要求します。
トークンはそのユーザーの「シークレット」アクセスキーと連結され、結果の文字列はMD5ハッシュされ、セッショントークンを要求するために送り返されます。
このセッショントークンは、クエリ文字列パラメーターとしてすべてのリクエストに含まれ、リクエストが「承認」されていることを「確認」します。
問題の1つは、「admin」ユーザーがUsers
テーブルのリクエストを行った場合、応答が上記の情報およびユーザーの「シークレット」アクセストークン(およびその他の情報)。そのため、パスワードを公開するだけでなく、誰かになりすまして実際にアクセスを許可することになります。
Userpassword属性のパスワード形式は、ハッシュされたパスワードを/etc/shadow
に保存するデフォルトのシステムパスワードサービスなど、さまざまなUNIXサービスで使用される標準形式に似ています。形式は基本的に次のとおりです。
$ type $ salt $ hash
あなたの例では、タイプは1で、md5ハッシュを指定します。さまざまなサイズのshaファミリハッシュ関数など、他のよく知られているタイプがあります。
Md5は非常に高速であるため、ソルトが適用されている場合でも、md5ハッシュを解読することは、今日ではほとんど簡単です。パスワードのハッシュに安全に使用できるハッシュ関数ではありません。 hashcatおよびその他のパスワードクラッカーは、文字通り数百万または数十億ものパスワード候補を毎秒ハッシュすることができます。
したがって、このデータストアサービスは、ユーザーのパスワードハッシュを送り返すため、単に恐ろしいだけでなく、実際にmd5ハッシュを使用してパスワードを格納しているため、さらに恐ろしいものになっています。
これが本当に安全ではないことを上司に証明するには、ハッシュキャットといくつかのパスワードリストをダウンロードし(オンラインで簡単に見つけることができます)、ハッシュキャットを、取得したすべてのパスワードに対して非常に強力なGPUが搭載されたコンピューターで実行します。サービス。 hashcatがクラックできるパスワードの数をメモし(パスワード自体を見ないで、パスワードを選択した人に関する個人情報が明らかになる可能性があり、実際にパスワードを知りたくない場合)、パスワードを知っている人に通知します。新しいパスワードを選択する必要があると妥協しました。住んでいる場所や仕事をしている場所によっては、これは実際には悪意のある攻撃と見なされたり、違法であったりする可能性があるため、おそらく最初にこれらすべてを行う許可を取得する必要があります。
余談:不安を表明した後でもこのサービスの使用に行き詰まっている場合は、人の介入なしで実行され、人々に通知する(電子メールを送信することによって)自動パスワードクラッカーを設定することをお勧めします)パスワードを破ることができれば、この種の悪いデザインからユーザーを保護することができます。脆弱なパスワードを取り除き、実際の攻撃者がパスワードを解読するのに必要な時間を増やすのに役立ちます。
編集:余談は一般的な慣行ではなく、リスクを評価できない人が試みるべきではないとザックは指摘しました。私はそれに完全に同意します。少なくとも、あなたがそのようなことをしたなら、あなたはそれを大丈夫にすべきです。
それでも、これを行わないことは、結果のシステムをより安全にすることにはなりません。これは、パスワードのセキュリティを改善するために実際に何かをした場合、それが逆効果になる可能性があることを恐れて、砂に頭を突っ込むのと同じです。我々は知っている人々が悪いパスワードを選ぶことを私たちは知っている md5がパスワードをハッシュする良い方法ではないことを知っています。 Ifこれら2つの事実を変更することはできず、areは弱いパスワードを排除する立場にあるので、ユーザーをより安全にするためにそれを行う必要があります。
これがあまり見られない、またはあまり考慮されていない重要な理由の1つは、通常、それを実装する立場にないことです。優れたシステムは、高速ハッシュ関数を使用してパスワードをハッシュしないため、通常、ハッシュされたパスワードデータベース全体にアクセスできません。
このパスワードハッシュは crypt()
形式を使用しているようです(この名前と一部のドキュメントでは、まさにそのマニュアルページを含めて、暗号化とはまったく関係がありません)。 ハッシュ)。 $1$
で始まる場合、これはMD5に基づくパスワードハッシュ関数であることを意味します。その正確な仕様は「glibcが行うこと」です。 ソースコード を見ると、いくつかの啓蒙的な文章が示されています。
201 /* The original implementation now does something weird: for every 1
202 bit in the key the first 0 is added to the buffer, for every 0
203 bit the first character of the key. This does not seem to be
204 what was intended but we have to follow this to be compatible. */
205 for (cnt = key_len; cnt > 0; cnt >>= 1)
206 md5_process_bytes ((cnt & 1) != 0
207 ? (const void *) alt_result : (const void *) key, 1,
208 &ctx, nss_ctx);
209
210 /* Create intermediate result. */
211 md5_finish_ctx (&ctx, nss_ctx, alt_result);
212
213 /* Now comes another weirdness. In fear of password crackers here
214 comes a quite long loop which just processes the output of the
215 previous round again. We cannot ignore this here. */
216 for (cnt = 0; cnt < 1000; ++cnt)
217 {
このことから、このハッシュ関数は十分に文書化されていないと結論付けることができます。
とにかく、パスワードハッシュ関数が進むにつれて、あまり良くありません。 saltを使用します。これは、事前計算されたテーブル(Rainbowテーブルを含む)の攻撃者による使用を防ぐ必要があるため、優れています。また、パスワードハッシュを遅くする試みとして、反復が多数(1000)あるループが含まれているため、一致が見つかるまで攻撃者が多くの潜在的なパスワードを試すことが難しくなります(「ブルートフォース」または「辞書攻撃」と呼ばれるプロセス) ")。
残念ながら、それもあまり良くありません。 MD5は高速で、1000ネストされたMD5は1000倍遅いですが、依然として高速です。基本的なゲーム指向のGPUを備えた既製のPCは、毎秒数百万のそのようなハッシュを計算できます。平均的なユーザーパスワードは長続きしません。つまり、攻撃者はハッシュされたパスワードごとに1分の計算に費やして、その半分を解読することになります。
ハッシュ化されたパスワードは別として、単にユーザーのメールアドレスを明らかにすることは、すでにかなり立派な犯罪です-私は法的に言えば。たとえば、カナダでは、これは「個人情報」として知られており、すべてのユーザーがあなたを訴える権利があります。
停止。これ以上進めないでください。書面で明示的に要求されるまで、テストやデモンストレーションなどを行わないでください。その後、頼むことで、あなたよりも多くの有資格者がいることを提案します。 audit/pentest/etc。
情報を少なくして(パスワードはなく、アクセスする必要がなく、アクセスすべきではなかった詳細だけで)同様のことをした2人の人を知っていますが、彼らはまだ対処のプロセスを行っています。 重罪料金。
この形式は、標準のUNIXスタイルのパスワードハッシュのように見えます。フィールドはドル記号で区切られます。最初はアルゴリズム、次にソルト、次に実際のハッシュです。 Linuxシステムであるとすると、$ 1 $はmd5パスワードアルゴリズムを示します(純粋なmd5よりも少し複雑です)。フィールド長は、MD5パスワードハッシュアルゴリズムとも一致します。
Linuxパスワードハッシュを攻撃するためのツールは数多くあります。これらのツールで成功するかどうかは、パスワードの強度に大きく依存します。
また、あなたのソルトにはゼロがたくさんあることにも注意してください。静的ソルトまたは比較的小さい(ユーザー数と比較して)範囲のソルトがある場合、事前計算された攻撃のオプションが開かれる可能性があります。
最後に、実際のパスワードを攻撃すると法的な問題が発生する可能性があることに注意します。
この情報はすべて、/etc/passwd
(誰でも読める)および/etc/shadow
の一般的なLinuxシステムのadminユーザーが利用できます。 (rootで読み取り可能)。標準のLinuxでは、rootユーザーが/etc/shadow
にアクセスできないようにすることは困難です。クエリは管理者権限を必要とするため、管理者アカウントが侵害されていることを考えると、それは多くを公開しているようには見えません。他の回答が述べたように、システムが実際にmd5ハッシュを使用している場合、それは問題ですが、質問とは無関係です。