ぶるーたるごぶりん

UI, UX, セキュリティとか😘

GitHub に漏れ出た内部コードを探す ~ 上場企業 3900社編 ~

全1回、このシリーズは今回で最後です!

TL;DR

  • 上場企業 3900 社程に対して、すごく大雑把な「内部コード等の漏洩調査」を GitHub 上で行った
  • 結果としては、重要度の高いものから低いものまで 10社ほどで漏洩が確認された
  • 重要度の高いものとして、社外秘っぽそうなスプレッドシート、社員のハッシュ化パスワード(BCrypt)、 AWS Credential 等
  • 「大雑把な」調査を行ったが、より精度の高い方法等について記事内にて触れていく
  • 脅威インテルとか DLP みたいなエリアとかも、外部企業とかに頼るだけじゃなく「自分たちでも」頑張ってみるのがいいんだと思います
  • GitHub Code Search ... すげえぜ!
  • Google Dorks ならぬ、 GitHub Dorks + GitHub Code Search でまだまだいろいろできるはず。

はじめに

チャオ!

今回は「内部資料を誤って公開している人 / 会社って結構いるよね」という前提をベースに 「GitHub 上に内部コード(またはその他の機微情報等)を上げてる社員 / 会社がいるんじゃないか?」という観点で、漏洩してしまっている会社を探してみようと思います。

調査の切っ掛けとしては以下です。

  1. GitHub API を使って、大量のリポジトリから「脆弱性をもつコード」を探すという研究記事があった

  2. GitHub の新しい Code Search 機能を活かしたかった

  3. 脅威インテリジェンスの記事などでは、コンピューターを中心としたリスクがメインになりがちだけど「人間的なリスクの評価も大切だよね」って思い続けていた
    • 脅威インテリジェンスなどの記事では「会社としてリスクを適切に認識しようね」と言った言及は普通にされている
    • ただ MITRE ATT&CK みたいなのを活用する話が 99% になっており、「内部の脅威をしっかり分析しよう」みたいなのは1ページで終わるみたいなやつ
    • 内部の脅威なんてのは記事にしにくいから当たり前ではあるのだが...
    • MITRE ATT&CK : https://attack.mitre.org/
    • ちょっと別視点(人間的なリスク)で一回考えてみようかな?と思って今回の調査手法を閃いた
  4. このあと登場する調査手法を記事にしているところは多分ないのでやってみようと思った

内容自体はひどく簡単で、 Google Dorks みたいなものを GitHub でやってみるというものです。
このあたりの GitHub Dorks のパターンも、 Bug Bounty とかで成熟してきています。 ただ、新しい GitHub Code Search を活用した GitHub Dorks は、まだまだ発展途上だと思うので、今回チャレンジしてみます。

Google Dorks って?

Google検索エンジンのパワーを使って、漏洩情報等を検索しよう」みたいな手法です。

例えば、 filetype:pdf 社外秘 等で調べることで、 PDF でファイル内に"社外秘"が入っているファイルを検索できるみたいな感じです。 Google Dorks に関しては、調べればいっぱい出てくると思います。
気になる方は各自で調べてみてください。

調査手法と想定

あくまで今回の研究の関心事は「GitHub 上に内部コード(またはその他の機微情報等)を上げてる社員 / 会社がいるんじゃないか?」という仮説をもと、

  • 考案した手法でそれらを引っ掛けられるか(通用するか)
  • 上場企業でもどのくらいの企業が"シンプルに"漏洩しているのか
  • GitHub Code Search を使って何かできないか

これらを調べるという点になります。 そのため、過度に複雑だったり高度である必要はないかなと思っています。 あくまで新しいおもちゃ (Code Search) で何かできないかというのがモチベーションの源泉です。

では、どういった「人物・企業」が漏洩させているのでしょうか? こういったセキュリティの検知では、脅威モデリングと同様に、脅威や資産の分析とシナリオの仮定が重要です。

そこで、今回の研究では、以下のペルソナ / シナリオをターゲットとしました。

  • GitHub を使いたてで、Public / Private などの公開範囲を知らずに公開している会社・個人
  • GitHub を使いたてで、社内のソースコードをコピーしてきて個人アカウントに(勉強とかで)アップロードしている個人
  • 何かしらの社内リソースをそのままプライベートで利用したり、バックアップだったりで Public に挙げているケース 要するに「内部のコードを外部に公開している気持ちはなく、無邪気に公開している」という感じです。

ちなみに、調査対象として上場企業を選んだ理由としては、セキュリティへの一定の投資があるにもかかわらず、 こういった初歩的な問題を孕んでいる会社がどの程度いるのかという部分にも興味があったためです。


ターゲットが定まったら次は検知手法です。
今回のターゲット(漏洩しているリポジトリ)は、おそらく以下のような特徴があるはずです。

  • 内部コードを漏洩しているリポジトリは、[ Star | Fork | Watch ] の数が 0-1 件程度であるはず

    • 内部の人間が GitHub にそのままコピーしたダウンロードファイル(内部コードなど)をアップロードしているケース
      • この場合、スター数などは極端に少ないはず
    • 内部のプロジェクトをそのまま誤って公開しているケースはあるかもしれないが、OSS と判別しにくいので無視
      • この場合、スター数などは 0,1 以上はあるはず
  • 「内部のコード」を動的に、そして静的に判断するためには、企業特有の情報を利用できそう

    • 一番良い方法としては「内部 Wiki の URL」や「チケット管理システムの固有 ID」とか
      • これらは、内部でしか利用しない(外部には公開しない)ことが多いため、検索のキーワードとしては圧倒的に有用
      • しかしながら、外部の人間が対象の企業の内部Wikiドメインなどを把握できるケースは稀(OSINT / Recon がいる)
    • 推測しやすいものとしては、精度は落ちそうだが 社員用の Email がある
      • 例えば Author に Email を記載しているかも
      • アプリケーション内で何かの連絡先としてメールアドレスをハードコードしているかも
    • ドメインだけの場合、スクレイピングやIRなどの情報ばかりが誤検知で引っかかりそう

そこで思いついたのが以下の横断的な調査手法になります。

  1. 上場企業の URL リストを生成する
  2. そこから雑に Email を推測し、リストを生成する
  3. (2) で作成した Email を GitHub Code Search API を検索する
  4. (3) の結果を元に、対象のリポジトリのメタ情報を取得し、(スター数等で)フィルターする
  5. (4) の結果を元に、筆者がリポジトリを全て確認していく

ステップを見ていただければわかりますが、やっていることはとてもシンプルで、面白みはないかもしれません。 しかし、これ系の漏洩を調査記事の多くは AWS Key の漏洩などがメインです。 AWS Key などであれば、 AKIA... みたいな文字検索で事足りるため、 GitHub Code Search のパワーを試せません。 なので、こういったニッチな観点で検索してみます。

漏洩調査

上場企業の URL 一覧を作成する

では、検索するために Email を集めていきます。

... その前に、検索キーワードに「Email」を利用する理由をしっかりと説明していなかったので、Email を利用する意図を記載します。

検索キーワードで Doamin ではなく、Email を用いる理由

Email で検索する理由としては、Email が「会社に帰属するデータであることを示すトレードマーク的な役割」と、「検索のキーとなる情報(過剰な誤検知が抑えられるキーワード)」として利用できそうと思ったためです。これは、「ただのドメイン」にはない特徴です。

「トレードマーク的な役割」は外部から調査をする場合、非常に重要です。 検知したリポジトリが、本当にその会社の内部ソースなのかを判断するには、何かしらの材料が必要です。
例えば、 notify@example.com みたいなものが引っかかってきた場合、「内部で利用しているメールアドレスっぽそう」と判断できます。

また、「ただのドメイン」と比べて、 Email の方が誤検知が低い印象があります。 「ただのドメイン」の場合、誰かのクローリングの結果や、(上場企業の場合)IR 情報などが引っかかってくる可能性があり、後半に行う人間の目によるフィルターが大変になります。 そのため、Email を(当てずっぽうでも良いので)検知し、それを元にフィルターする形式をとっているわけです。

逆に「社内リソース」と判断できるキーワードがわかるのであれば、それを利用した方が安定します。それが先程触れた「内部 Wiki の URL」などです。
これらは基本的に OSS プロジェクトには記載されにくい情報です。ドメインなどを特定するのが難しいという欠点を無視すれば、精度が良そうなキーワードだと思います。

そのため、「社内の漏洩をチェックしたい」といったケースにおいては、内部ドメインなどでテストしてみると良いとはずです。 もちろん、Email でしか検知できないといった場合もあるため、思いつく限り色々試すのが一番良いとは思います。

Note: 検索キーワードのアイデア

仮に外部から Email 以外のキーワードで、それなりの過剰検知を抑えた検索をする場合、ドメインwiki., confluence. とかを付けて検知する方法がありそうです。 他にも CT Log などからドメインサーチをし、 Wiki 関連のキーワードを引っ張ってくるといったアプローチや、Linkdin などから Email を抜き出したり、対象の会社のサービス一覧(ドメイン一覧)を取得して検索するといったアプローチもあるかもしれません。

Email のリストを作成する

さて、話を戻しましょう。まずは上場企業の Email のリスト作成です。

今回は特定が容易(当たる確率がそれなり)というメリットのみで、対象企業のホームページのドメインから Email を推測する方法をとります。 つまり、 https://www.examle.com みたいなURLから https://, www を外し、 @ を先頭につけるだけというゴリ押し形式です。

URLリストについては、どこかの方がきっとまとめてくださっているでしょう!
・・・すると、以下のブログで CSV をまとめて公開されている方がいらっしゃいました。感謝!

上場企業 URL 一覧データまとめ(CSVファイルあり)-tachitechi blog(たちてちブログ)

この CSV の URL を元に Email のリストを生成します。

Email を GitHub Code Search API を検索する

お次は GitHub Code Search API を利用して検索をします。

GitHub Code Search は昨年末くらい?に登場し、現在もベータ機能で公開されている「強力な GitHub のコード検索機能」です。

GitHub.com

この機能では、これまでできなかった「Regex によるコード検索」を「リポジトリを横断して」実行することができる最高の機能です。 少し前までは有効化しても順番待ち状態で、なかなか使えなかったのですが、現在は上記 URL から Try it now をクリックして有効化することで、即座に利用可能です。

今回の研究では、この機能を有効化することで、Email の完全マッチによる検索を行っていきます。 例えば、以下のような URL で (Code Search が有効なら) Email を検索することができます。

https://GitHub.com/search?q=%2F%40example.com%2F&type=code

では API Doc を探してみましょう。
どういったリクエストで送って、どういったレスポンスが返ってくるか。

・・・が、残念なことに Code Search API は Document が書かれてるようなレベルでは整備されていないようです。ベータ版なので仕方がないですね。
なので今回は、Code Search のページで叩かれている API がいい感じの JSON を返してくれることを祈りながら、レスポンスデータを見てみます。

そこで、画面から叩かれる API をみたところ、流用できそうな API がありました。

今回はこの API をブラウザの行うリクエストと同じようにして (行儀よく)直接 Call し、リサーチを進めてみようと思います。

対象のリポジトリのメタ情報を取得し、それを元にフィルターする

さて、 Code Search で対象のキーワードにマッチしたコードを抽出することができました! あとは Star 数を元にそのままフィルターして終わりです。

っと思いましたが、どうやら Code Search API のレスポンスには Repository の情報が含まれていませんでした。

そこで、以下のステップに分解し、結果をまとめていく方針にします。

  1. Code Search で対象のリポジトリ名を取得
  2. Repository API を元に、スター数などのメタ情報を取得
  3. 無名なリポジトリのみにフィルターしていく

Repository API からメタ情報を取得する

Code Search API で、キーワードにヒットしたリポジトリの名前はわかりました。 お次は先ほど見つかった「スター数などの情報」を取得するために、GitHub の 別の API を叩きます。

今回は以下の API を利用しました。

リポジトリ - GitHub Docs

リクエストには GitHub の Personal Token が必要なため、GitHub 上で発行しておきます。

https://github.com/settings/tokens

Repository フィルターを実装する

フィルター自体は記事中盤の手法の部分に書いたので前提等は省きますが、今回の研究では以下のフィルターを行いました。

  • Fork されたリポジトリは無視 (Private --> Public があり得るのかは知らないが、大凡検知しないと判断)
  • Fork / Watch / Star が 2 以上は無視 (1 くらいはありそうだが、 2 以上はプロジェクト化しているようなものの可能性があり、会社公認のものが紛れてきそうと推測)

また、研究を終えた時にいくつか思いついたフィルターがあるので、それは最後に記載します。

人間静的コード解析器となり、漏洩を探す(結果)

上記のアルゴリズムを元に、3900社程度の検索の結果を csv で吐き出しました。
残るは、全てのリポジトリを己の眼(まなこ)で grep するだけです。

吐き出されたファイル数(該当するものがあった会社数)は、 240程度でした。
また、リポジトリの数としては、多分 500 程度が引っかかりました(ちゃんと数えてないです)。

そこから、内部のコードっぽいものを探したところ、10個の内部コード / PDF / クレデンシャル等が発見できました。 この文字だけみると、結構クリティカルな感じに見えますが、内訳としては「重要な情報」は 2つのみでした。
その二つというのは、1つが AWS Credential、もう1つが内部資料(スプレッドシートURL)、内部社員のハッシュ化パスワード(BCrypt)でした。

他のデータは以下のようなものばかりでした。

  • 公開データ(を移行するためにバックアップとして GitHub にあげてるケース)
  • かなり古い(2-10年前) のサービスの内部コード

中にはサービス終了していそうなものなども含まれているという状態です。
うーん、渋い。

クリティカルな AWS Credential の方も、アップロードして数日経っていれば侵入されていると思うので、(数年前のものだったので)既に Expire されているか、ハニーポットなのかなと思いました。

※検知した 10リポジトリについては、全て JPCERT さま経由で通報しました。また、一番危険度が高いと思っていたリポジトリの他、数個のリポジトリは削除されたのを確認済みです。

考察

結果自体は書いてしまったので、ここからはいくつか考察や、調査を進める中で思ったことをまとめてみようと思います。


まず、検索キーワードについてです。 今回調査して思ったこととしては、以下の検索は(今回実施していませんが)、結構パンチのある結果が出せるかもなーと思いました。

  1. Google Spread Sheet などの URL ( + Email などの何かしらのトレードマーク)
  2. BCrypt のような、独自のフォーマットの検索

(1) Google Spread Sheet などについては、(そもそも「会社の Google Spread Sheet であるかを判定する」のが難しいかもしれませんが) 何かと合わせれば内部資料に辿り着ける可能性があります。
ただ、これ単品で検索すると誤検知が異常なレベルで発生すると思うため、単品では厳しいかもしれません。

(2) BCrypt です。
これまでは $ などの文字を GitHub で検索しても、うまく検索できませんでした。 しかしながら、 GitHub Code Search のおかげで、 $ などの検索もすることができるようになりました。 つまり、 BCrypt などの検索や、 UUID などの特殊なフォーマット(で、且つ秘匿性が高いもの)をうまく引っ掛けられる可能性があります。

いずれにしても、発想次第で何かの検索に利用できると思うので、GitHub Dorks はここから一気に発展していく気がします。


次はフィルターについてです。

今回はかなり素朴なフィルターをしましたが、調査を進める中でいくつかのフィルターを思いつきました。

例えば、以下のようなものです。

  1. pom.xml, や package.json などに記載がある "author": "example.com" みたいなものは無視する
  2. Java などのディレクトリ構成 ( src/com/example/hogehoge/Main.java ) などのものは優先的に表示する
  3. 特定の拡張子は無視する
  4. リポジトリサイズが過度に小さいものは無視する

(1) については、今回検知したもののかなり多くがこれで検知していたため、どうにかフィルターしたいと思ったためです。 Email を検知のフックとしてしまったために起こった問題ではありますが、あまりにも多くの人が(会社のメールアドレスを使って)OSS 活動をしていたりします。 いい事なんです。いい事なんですが...今回の研究においては誤検知になるものばかりで大変でした。

(2) のようなものの場合、ソースコード内部に明確に Email などが記載されているケースがあり、これらは結構精度いいんじゃないかなと思いました。 しっかりとしたディレクトリ構成をしていて、その中に Email が混じっているのは悪くないマッチング方法だと思いました。

(3) については書いてあるままですね。今回は利用しなかっただけです。

(4) についても同様で、今回はフィルターに使いませんでしたが、悪くないフィルターだと思います。
一方で、今回クリティカルな問題として検知できたもの (AWS の認証情報が書かれていたリポジトリ) は、とても小さな Terafform ファイルだったため、 Size のフィルターを過信して行うと、見つけたいものを取り逃す可能性がありそうでした。


感想

感想の一つとして、「すごく古い内部のソースコードがそのまま公開され続けている」のが結構検知できたことが意外でした。
2年前のものから10年前のものまで大小様々なサービスの内部コードがそのままアップロードされ続けており、残り続けている / 誰にも触れられずに置かれているのをみると、なんとも言えない感情が湧いてきてきました。まるで倉庫を漁り続けているような気持ちです。

また、人間の目で見るというのは大変なので、この研究はもうしたくないです。ヘロヘロです。

実務的な視点での感想としては、「色々な観点で、とにかく色々頑張る」しかないんだなーと改めて思える研究結果でした。
例えば MITRE ATT&CK みたいな「コンピュターセキュリティにおける明確な脅威」は、仕事をする上で常に頭の片隅にある一方で、(悪意の有無に関わらず)内部犯行によって内部情報が漏洩したりするケースは、アセットとして認識したり、それらの情報フローをもとにリスク評価をするしかなく、とにかく努力・根性が必要だなと。

次に、おそらく読者の人が思うであろう感想についても少し書いておきます。 おそらく、今回の記事を読んだ読者の中には「ダサい会社もあるもんだなー」とか思われる方もいると思います。
しかし、あなたの会社も探してみたら普通に内部コードをミスって上げてる元社員とかが出てくると思います。全くもって対岸の火事ではないです。
もしかしたら、もっとろくでもない漏洩をあなたの会社や、下請けの会社がやっている可能性は十分あります。

なので、この記事を読んだ読者の方は、是非この後にでも「自分の会社のドメイン / Email / サービスのドメイン」等で検索してみてください。 以下の手順で 2分以内に開始できます。

  1. Code Search を ON にする (Try it now をクリック) GitHub code search · GitHub
  2. 以下の検索画面で、 /@example.com/ とかで検索する https://github.com/search?q=%2Fexample.com%2F&type=code
  3. ヒットしたものを "目 grep" する

一応作ったコードも貼っておきます。 https://gist.github.com/motoyasu-saburi/7a2a8ef9e3405a90016fcb26a70d012a

研究時間:
- APIの調査とかコードの調査: 2日 - 人間静的コード解析器になった時間: 14h くらい

ブログ文字数:
約 1万文字 (当初の予定では 3000文字くらいだったのに・・・)

また、クリティカルなものは全て削除いただいているのと、JPCERT さんへの通報から 1ヶ月程度たったので、記事を公開してみます。

最後に、最近出た最高のプログレメタルの EP 貼っておきます。

www.youtube.com