複数人で使ってそうな共通パスワードリストを正規表現を使ったルールで生成してみる

はじめに

12月ももう後半。 そろそろ大掃除の時期ですね。

私も大掃除がてら自分の個人リポジトリ整理をしていたところ、過去に作ったリポジトリがいくつか発掘されました。 そんな発掘リポジトリの中に組織で共通利用されてそうなパスワード(以下、メンバー間共通パスワード)を、正規表現を使ったテンプレートでリストを生成するという少し面白そうな内容のものがあったので、供養がてら公開してみたいと思います。

https://github.com/CyberDefenseInstitute/gen_commonpw

当時のことを思い出すと、だいたい↓の2つが動機で作った…んじゃないかなぁ…(自信がない)。

  1. sre_yieldという正規表現を展開してくれるライブラリを見かけたのでなんか作ってみようと思った
  2. ちょうど同じ時期にメンバー間共通パスワードというものに興味があった

メンバー間共通パスワードとはなにか?

メンバー間共通パスワードってそもそもどういうものなの?という疑問が出てきたと思います。 これを読んでくれている皆さんの組織にあるかは不明ですが、私が見てきた多くの組織・部門ではそこに所属する社員間で共通利用するパスワードが存在していることが多くありました。

使われている背景としては、「単純に良くあるパスワード(P@ssw0rdなど)を設定するのには抵抗があるけど、人の入れ替わりが多いから全てにランダムな文字列を使うのは運用面でコストが高いな」といった場合に使われることが多いのかなと思います。 良くある特徴をあげると、以下のようなものです。

  1. 組織名や部門名、オフィスの地名が入っている(最初の1文字目だけ大文字にしてたり、一部でleetを使っているもある)
  2. システム的に設定されているパスワードルールを満たすため、数字や記号がくっついている
  3. 数字は年や日付など、部門に所属する社員など人間が覚えやすいものが付与されている
  4. 組織内でしか使わないため、世の中でよくあるパスワード ではないことからパスワードリストによる攻撃や総当り攻撃には強い

複数名で使い回すことを前提に作られていることが多いため、ランダムな英数字による文字列ではなく、ある程度意味のある文字列になっているのが特徴ですね。

世の中にはいろんな組織・いろんな現場があるため、各環境ごとにメンバー間共通パスワードは違う場合が大半です。 しかしある程度ルールは同じ、もしくは似通っている場合が多いことからパスワードの生成ルールさえわかっていれば、ある程度パスワードの候補を絞ることも可能になります。

まぁ、ようはAmaga○aki2022のようなものと考えてもらえるとわかりやすいと思います。 この場合だと、組織名の略称+Yearになりますね。

こういったパスワードに正式に名前がついているか不明(私個人の観測範囲では、あまり名前はついていなかったと記憶しています)のため、ひとまずこの記事内ではメンバー間共通パスワードと呼称しています。

つまりこのリポジトリはどういうものなの?

このリポジトリのツールでは、target.json(ターゲットとなる組織のキーワードの定義ファイル)とpattern.json(メンバー間共通パスワードのルールを変数+正規表現で定義するパターン定義ファイル)の内容を元に、メンバー間共通パスワードのリストを生成します。

…で、本来なら level, tagによる実行対象キーワードの展開制御 、また ターゲットとなる組織の情報をある程度入力しておくことで、自動的に関連情報についてもなにかしらから取得させてキーワードとする機能 などを実装したいなぁと漠然と考えていたのですが、sre_yieldを使ってナニカを作る という部分で満足して 飽きt 一時作業を中断しており、実際のリポジトリはかなり中途半端な状態になっています。

使ってみよう

それでは、実際に使ってみましょう。 pipでのインストールに対応させているので、以下のコマンドでインストールが可能です。

git clone https://github.com/CyberDefenseInstitute/gen_commonpw
cd gen_commonpw
pip install ./

target.jsonには、ターゲットとなる組織に関するキーワードを入れていきます。 このjsonで指定したkeyをpattern.jsonで変数として指定(ex. ${company})することで、配列で指定された値を差し込んでパスワードを生成します。

{
    "company": [
        "Cyber"
    ],
    "place": [
        "Shinjuku"
    ]
}

pattern.jsonには、よく使われているであろうメンバー間共通パスワードのルールを正規表現で指定します。 pattern にパスワードルールを正規表現を用いて定義することが出来ます。 sre_yieldが対応しているため、キャプチャグループ(()で囲んだ内容を\1, \2で後から指定できる記述方法)でも書けます(sre_yieldすごい)。

[
    {
        "pattern": "(${company}|${place})([0-9])\\2[!@#$]{1,2}",
        "description": "ex: 先頭に社名や地名が含まれるパスワード. ex: `Cyber11!$`, `Shinjuku22!@`"
    }
]

target.json 及び pattern.json を設定できたら、実際に動かしてみましょう。

gen_commonpw pattern.json target.json
$ gen_commonpw pattern.json target.json
CyberDefense66#$
Ochanomizu88!$
Cyber66##
Shinjuku88#$
Shinjuku55!@
Ochanomizu66$$
Cyber66$
Cyber00##
CyberDefense55$@
Cyber66!$
Cyber66@$
CyberDefense55!#
Ochanomizu99#$
Ochanomizu11!$
Cyber66$#
CyberDefense00#!
CyberDefense11$
Cyber55#@
Ochanomizu11@#
CyberDefense77#@
...

一応、-ltarget.jsonの値をleet変換して処理をする機能を雑実装しています…が、sre_yieldで正規表現の展開をする前に行っているため場合によってはエラーになってしまうし、ちゃんと開発してないのですごく遅いのでのであまり実行はおすすめしません(まぁPoCだからいいか…)。

似たような機能をもつツールはあるの?

こういったパスワードジェネレーター自体は数多く存在しておりますが、今回作ったリポジトリのようなテンプレートにワードを差し込んでいくような機能を持つものもあります。 たとえば、有名なJohn the Ripperにもルール指定機能があったりします。

さいごに

今回公開したリポジトリは中途半端なもので終わりましたが、弊社はこのようにイロイロな手法を調査・検証し日々ペネトレーションテストに活かしております。

今回あつかったようなパスワードをもし組織内で使っていた場合、おそらく機械的なスキャンでは侵入までは至らないとおもいます。 しかし組織に対してある程度理解している人間が侵入しようとした場合、パスワードを推測されて侵入されてしまうかもしれません。

そういった脅威があるかどうかを確認するため、定期的な手動でのペネトレーションテストを行うことをおすすめします。

© 2016 - 2022 DARK MATTER / Built with Hugo / Theme Stack designed by Jimmy