のんびりやの日記

のんびり、たまに更新。

postgresのデータを盗まれた話

スポンサードリンク

はじめに

さっぶ。どうも、だーやまんです。
この記事は、本番環境でやらかしちゃった人 Advent Calendar 2019 - Qiitaの11日目の記事です。
これは、中途半端な知識でサービスを運用していた結果、タイトル通りの大失敗をしてしまったお話です。個人開発での出来事なので、業務で起きたことかと胃薬を握られていた方はご安心ください。
語るのもすごい恥ずかしいレベルですが、戒めのために晒しておきます。

この記事を読んでほしい人

  • 初めてインターネット上にサービスを公開しようとしている人
  • 喋太郎の利用者様(この場をお借りして、改めてお詫び申し上げます。本当に申し訳ございませんでした。)

背景とか

  • Discord読み上げBot 「喋太郎」にてやらかしました

www.dayaman.work

  • 利用者が約10万人
  • さくらのVPSにてAppサーバ2台、DBサーバ1台で運用
    • 各サーバの死活監視にmackerelを利用
    • 被害があったのがDBサーバ
  • 基本的にだーやまん1人で運用
    • 得意技は時空の歪み(大学3年生2周目)

問題発生

  • DBの接続処理に不具合があり、修正のためにサービスを停止させた期間があった
    • この時、DBサーバ、Appサーバ共に起動したまま
    • 修正のための停止期間は20日ほど
      • これはこれで、どでかいやらかしなのでは...?(原因はサボり)
  • 15日目あたりでmackerelからDBサーバが落ちたり直ったりと繰り返しアラート
    • しかし普通にssh接続できる
    • 色々試したところ、通信が外へ出られないようだった(pingとかタイムアウトになる)
    • サーバ自体の再起動でとりあえずは治った
    • が、しばらくすると再発する
    • メールがうるさいのでサーバをシャットダウンする
  • 修正作業が終わり、DBサーバとアプリケーションを起動
  • ところが、「テーブルが存在しない」とエラー
  • は??????と思ってDBサーバにSSHしてpsqlコマンドでDBにログイン
    • 存在していたテーブルが消え去って「a_a_warning」というテーブルが一個だけ
    • テーブルを覗こうにも、そのDBのownerで開けない
    • はて?と思ってpostgresユーザに切り替えてテーブルを見る
    • レコードが一件だけ入っており、いんぐりっしゅな文字列が入っていた
Hello. You may be surprised to see this message, but it was your bad security practices that allowed us to steal your database. 
If you want to restore your data, and continue using it, send 0.075000 Bitcoin to [おそらくBitCoinのウォレットアドレス] and go to the page using tor browser [謎のURL]. 
In return, you will get the copy we have of your database. You can download the tor browser on the official website https://www.torproject.org/download/ | [おそらくBitCoinのウォレットアドレス]  | [謎のURL]

(意訳)(悪意マシマシ)
「おっすwwwww驚いた?wwwwガバガバセキュリティのおかげでwwwwデータ盗めたわwwww返して欲しかったらwwwウェwwwここにビットコインwwww振り込みよろwwwww」

やられた

とりあえず現在進行形で踏み台にされている可能性があるので、必要と思われるログや設定ファイルをまとめてメインPCに保存(それも安全なのかっていう)。その後、DBサーバをシャットダウン。 自分だけではログの読み方もいまいちわからなかったため、詳しい友人や、先輩に調査のお願いをした。

惨劇はなぜおこってしまったのか

直接的な原因

まず、postgresの設定をどのようになっていたのか

  • 2つのホストを指定してアクセスを許可
  • インターネットを介して接続
  • Portは5432
  • postgresユーザのパスワードが「postgres」(認証はmd5)

今思うと素敵な設定してますね。玄関の鍵を閉めないタイプか?

それでは、設定ファイル(pg_hba.conf)の接続可能ホストを確認してみよう。(IPアドレスは架空のもの)

# TYPE   DATABASE    USER    ADDRESS     METHOD
[省略]
host    all         all     184.14.25.76/0  md5
host    all         all     184.14.133.122/0    md5

サブネットマスクが0になってるね。これはIPアドレスの仕組みをよく理解しておらず、なんとなくググってこのような設定を見つけたので真似した結果。(「IPアドレス 一つ 指定」みたいな検索をした気がする)

追記
サブネットマスクが0であることの何がまずいか。
IPアドレスをどのような値にしたところで、 0.0.0.0 、つまりな任意のIPアドレスという意味になる。上記の設定の場合、接続ホストを制限するどころか、あらゆるホストの接続を許可したことになる。自宅が公共施設になってしまった。
この話がよくわからないという人は、サービスの公開をする前にネットワークを勉強しような。だーやまんの二の舞になるぞ。

ガバガバのガバ。ログとかめっちゃ攻撃された足跡あった。

どうもこの隙を突いて、任意のコマンドを実行、悪意のあるスクリプトをダウンロード・実行させられたらしい。ログファイルにダウンロードの痕跡と、見覚えのないファイルが/var/lib/pgsql/11/data/以下に存在していた。

mackerelから不自然なアラートが起きたときにもすぐに対応せずに放置したのもBadポイント。

間接的な原因

そもそも上記の事項は大学の講義で履修した内容であるので、いかに適当に単位をとってきたかが伺える結果。そら留年するわ。
さくらのVPSは無料でローカルネットワークを組めると知らなかったので、サーバ同士の通信がグローバルIPアドレスを用いて行われていた。

盗難にあったデータ

  • ユーザネームとユーザID、読み上げ音声設定
  • 各ギルド*1の名前とID、Botの利用上の設定
  • ユーザ辞書
  • 利用状況の統計

メールアドレスなど、直接的に個人と結びつくような情報は保存していない(できない)ため、流出しなかった。ユーザネームやユーザ辞書に個人情報が書かれていた場合はどうしようもない...。

二度と惨劇を起こさないためにどうしたのか

行動したこと

  • 被害にあったサーバは一度爆破してOSを再インストール
  • ネットワークの教科書を読み直した
  • 教科書以外にもググって納得がいくまで学習した
  • ローカルネットワークを構築
    • postgresがlistenするポートはローカルネットに向けて開放
    • DBへのアクセスはlocalhostか、ローカルネットワークの機器にのみ許可
    • ローカルネットワークからの接続可能ユーザはDBのownerに限定
  • 友人に依頼し、ポートチェックなど、とりあえず出来そうな攻撃を試してもらう

その他反省事項

  • しかるべき機関(警察やIPAとかJPCERT/CC)に相談せずにサーバを爆破したこと
  • ユーザへの謝罪を行ったものの、情報がまとまる前に公表してしまったので、かえって混乱を招いてしまった

教訓

  • インターネットは悪人が跋扈している
  • セキュリティがガバガバでもサービスは動く
  • サービスが動くからといって物事をドンドコ進めてはいけない
  • よくわからないことは調べてから動かす
  • 周りの人を頼る
  • 授業で得た知識は大事にするべき

さもなくば、信用を失う上に友人から一生煽られることになります。

追記 2019/12/11

早速、いくつか反応をいただけたので補足いたします。

サブネットマスクの不備とかそういうのだけじゃあ、破られないよね

そうですね。postgresユーザがデフォルトパスワードのままmd5になってました。書くの忘れてました...(今は変更してます)

ファイアウォールとか使ってないの?

使ってますよ〜。被害にあった時はssh用のポート(こっちは変更していた)と、5432ポートをインターネットに向けて開いてました。

なんで/0がだめなのか書いた方がいいんじゃないかな

記事中に追記しました。

初期パスワードってランダムじゃなかったっけ

あれ〜、じゃあ自分で「postgres」にしたのかしら。DBのownerは複雑なやつにしてたから割とまじで大馬鹿案件...?

学生のうちで幸運だったね

ほんまです。就職してからじゃあ洒落にならないことになってました。

*1:Discordでは1つのコミュニティをサーバと表記するが、混乱を防ぐためにここではギルドと表記

 
 ブログバナーです  
 ご自由にお使いください

リンク先は
http://www.dayaman.work
でお願いします
プライバシーポリシー お問い合わせ