2014年、どこかから漏れた大量のIDとパスワードのリストにより、 Web業界を大規模に巻き込んだリスト型攻撃が流行した。 なお、いまだにお漏らしした犯人は(公式には)明らかになっていない。
リスト型攻撃とは、どこかで手に入れたログインIDとパスワードのリスト を使って、Webサービスにログインを試みる攻撃である。 流出元がそのサービスであったり、同じIDとパスワードを使いまわしている場合などはログインが成功してしまう。
6月中旬から下旬にかけて、国内の有名Webサービスが軒並み大規模なリスト型攻撃を受けた。 ログイン試行回数はそれぞれのサービスで最低でも200万回と、 相当に大きなパスワードリストが流通しているものと想像された。 多い場合には試行の10%が成功したようだ。
リスト型攻撃は検出が難しい。 ひとつのログインIDに対して何度もログイン試行する攻撃の場合は、何回か失敗したらアカウントをロックすればよい。 しかし、リスト型攻撃の場合、ひとつのログインIDには基本的にひとつのパスワードしか無い。 複数のサービスから流出したものをマージしたリストならばその限りではないが、 そもそもお漏らしするサービスは多くはないので高々2-3種類だろう。 一般的なログイン失敗回数の制限内に収まる。
ひとつのIPアドレスから短期間で複数のログイン試行がある場合、 リスト型攻撃を行っている可能性が濃厚だ。 しかし、今やIPアドレスを無限に切り替えながら攻撃することなど容易にできてしまう。 今回の事件はどうやら、ひとつのIPアドレスから攻撃されていたため、リスト型攻撃に気づいたようだ。 もし犯人が本気で攻撃するつもりであれば、そもそも攻撃があったことに気づけなかった可能性が高い。
まず自分のサーバがパスワードリストをお漏らしするのは言語道断である。 口を酸っぱくして言われていることだが、パスワードをデータベースに保存する場合、一方向ハッシュをかけなくてはならない。 しかし、単純にハッシュをかけただけでは、データベースの中身が漏れた場合、復元されてしまう可能性がある。 すでに世の中には、よくあるパスワードとそのハッシュ値の対応表が出回っている。 単純なハッシュでは、よくあるパスワードを使ってしまうユーザのハッシュ化されたパスワードは、一瞬で元のパスワードが分かってしまう。 また、自分のハッシュ化されたパスワードと一致するユーザが見つかれば、そのユーザは自分と同じパスワードだということが分かってしまう。 そうでなくても無限の時間をかければどんな複雑なパスワードでも一致するハッシュが見つかってしまう。
パスワードを安全に保存するためにはSALTが必須だ。 SALTとは、元のパスワード文字列に追加する任意の文字列で、 同じパスワードでもSALTが違えば全く別のハッシュ値になる。 SALTが付くことで、対応表に乗っているパスワードを使っても、ハッシュ値は違う値になり、対応表を使ったパスワードの復元が不可能になる。 ユーザごとに別のSALTを使えば、偶然同じパスワードのユーザが2人いても、ハッシュ化されたパスワードは違うものになり、ハッシュ値の一致から他人のパスワードを知ることはできない。 システム全体のSALTとユーザごとのSALTをパスワードに付加してからハッシュ化すると、ハッシュ値はだいぶ強固になる。 この場合、ユーザごとのSALTをデータベースのカラムに持っても構わない。
さらに、ハッシュを何回も繰り返しかけることも強度を上げる。 ソースコードを取得し、どのハッシュを何回かけるか完全に把握しない限り、パスワードとハッシュの対応表を見つけることは不可能だろう。
ちなみに、heartbleedとかで通信内容が丸見えの場合、 どれだけ完璧にパスワードをハッシュ化しても全く無駄である。
他サービスから流出したリストによる攻撃を受けた場合、サービス側ができることはあまり多くない。 巧妙に準備された攻撃の場合、気づくことすら難しいかもしれない。 対策としては、そもそもIDとパスワードを自前で持たずにOAuthにしたり、 2段階認証の仕組みを用意するのが効果的だろう。 実際にこの攻撃のあと、2段階認証を導入したサービスは多い。 だが難しいのは、いくら安全だからといってもユーザはこれらの仕組みを使ってくれないのである。
リスト型攻撃を防御する唯一の方法は、攻撃される前にリストを取得することである。 リストを取得し、ユーザIDと自分たちのハッシュ化を施したパスワードの組を作り、 一致するアカウントをロックするなり、パスワードを強制変更していくのである。 ただしこれは何かしらの法に抵触する可能性があるかもしれない。 海外のとあるサービスで、
そのパスワードは他で使われているから危険です
と警告を出していたのを見たが、 他で使われていることをどうやって確認しているのか非常に謎だ。
ユーザが取れる対策は、とにかく単純でパスワードを使いまわさないことである。 パスワードを使いまわさなければ、どこがお漏らししたところで他のサービスには絶対ログインできない。 複数のパスワードを使いこなすのは何も難しいことではなく、 パスワード管理ソフトを使ってランダム生成すればよいだけだ。 もうパスワードを覚えようなどと思ってはいけない。 もう誰も電話番号を記憶する人はいないように、パスワードも記憶するものではなくなった。 この機会にパスワード管理ソフトを導入しよう。 ただし、パスワード管理ソフトの管理はしっかり考えなくてはならない。
筆者はLastPassを使っている。 ブラウザの拡張機能として提供され、ほとんどのブラウザでパスワード管理が可能だ。 ブラウザベースなのでプラットフォームも柔軟であり、モバイルアプリも完備されているが、 ネイティブで動くアプリケーションのパスワード管理は難しいという欠点もある。 過去に一度やらかしたことがあるらしいが、逆に2度目の失敗の可能性は低いということでもある。
ユーザは今すぐパスワード管理ソフトを導入し、 すべてのパスワードをランダム生成したものに置き換えるべきだ。 サービスが2段階認証を用意しているなら使ったほうがいい。 2段階認証は手間が増えるが安全性は格段に上がる。
しかし、サービス提供者は、ユーザがパスワードを使いまわさないことを期待してはいけないし、強制してもいけないし、使いまわす人を責めることもできない。 せっかく用意した2段階認証もほとんどの人は使ってくれないだろう。 パスワードというものが存在する以上、リスト型攻撃からは逃れられない。
あと何の関係があるか(公式には)全くわからないけど2つリンクをおいておきますね。