【入門編】 ログの完全性保護:WORMストレージとデジタル署名の活用 – インシデントレスポンス & フォレンジック(DFIR)防御ガイド

こんにちは!インシデントレスポンスの世界へようこそ。SOC(セキュリティオペレーションセンター)で日々、サイバー攻撃の痕跡を追いかけているアナリストの私です。

「ログの完全性保護」なんて言われると、なんだかすごく難しそうですよね。でも、安心してください。一歩ずつ、身近な例えから紐解いていきましょう!

皆さんは、自宅の玄関に鍵をかけたり、大切な通帳を金庫にしまったりしますよね。それはなぜでしょうか? もし空き巣に入られたとき、「何が盗まれたのか」「いつ侵入されたのか」を正確に知りたいからですし、警察や保険会社に被害を証明するためでもありますよね。

実は、これと全く同じことが、私たちの管理するサーバーやクラウドの世界でも起きています。システムに侵入した攻撃者は、自分の足跡(=ログ)を消そうと必死になります。せっかくセキュリティの警報が鳴り響いても、その記録が書き換えられてしまっていたら……? 私たちは「何が起きたのか」を永遠に知ることができなくなってしまいます。

今回は、そんな最悪の事態を防ぐための技術、「WORMストレージ」と「デジタル署名」について、現場の泥臭い知見も交えながら、優しく丁寧に解説していきますね!

—

1. なぜ攻撃者はログを消そうとするのか?

システムが乗っ取られるとき、サイバー攻撃者は必ず「痕跡(証拠)」を残します。
例えば、不正なログインの記録、こっそり実行された怪しいコマンド、外部へデータを持ち出した通信の履歴などです。これらはすべて、私たちディフェンダー(防御側)にとっての「決定的な証拠」になります。

もし攻撃者が管理者権限(rootやAdministrator)を奪ってしまうと、彼らはやりたい放題です。
よくある手口として、サーバーの中にあるログファイルを開いて、自分たちのIPアドレスが含まれる行をごっそり削除したり、ログファイル自体を空っぽにしてしまうというものがあります。

家の鍵を壊されただけでなく、防犯カメラの映像ごと盗まれてしまうようなものですね。これでは警察(インシデントレスポンスチーム)を呼んでも、捜査のしようがありません。

だからこそ、「誰も(たとえ管理者であっても)あとから書き換えることができないログの保管場所」が必要になるのです。

—

2. WORMストレージでログを「コンクリート漬け」にする

ここで登場するのが、WORM(Write Once, Read Many)という技術です。
日本語に訳すと「一度書いたら、二度と書き換えられない(何度も読み取ることはできる)」という意味になります。

身近な例えで言うと、タイムカプセルや、重要な契約書に押す「朱肉の印鑑」、あるいはコンクリートに刻まれた足跡のようなものです。一度固まってしまえば、後からこっそり形を変えることはできませんよね。

クラウドの世界では、AWSの 「S3 Object Lock(オブジェクトロック)」 という機能を使うことで、このWORMストレージを簡単に実現できます。

S3 Object Lockの仕組みと設定イメージ

S3 Object Lockには、主に2つのモードがあります。

1. ガバナンスモード: 通常のユーザーは削除や上書きができませんが、特別な権限を持つ管理者であれば(いざという時に)解除できるモード。
2. コンプライアンスモード: 【最強のモード】。設定した期間内は、AWSの最高権限を持つルートユーザーであっても、削除や上書きが絶対にできないモード。

インシデントレスポンスの現場では、証拠の信頼性を担保するために、このコンプライアンスモードがよく使われます。

実際にAWSでログを保存するバケットを作る際の設定イメージ(Terraformコード例)を見てみましょう。難しく考えず、コメントを読んで雰囲気を掴んでみてくださいね。

# ログを安全に保存するためのS3バケットを作成します
resource "aws_s3_bucket" "secure_audit_logs" {
  bucket = "my-company-ultra-secure-audit-logs"
}

# バケットに対して「オブジェクトロック」を有効化します
resource "aws_s3_bucket_object_lock_configuration" "audit_lock" {
  bucket = aws_s3_bucket.secure_audit_logs.id

  rule {
    default_retention {
      mode  = "COMPLIANCE" # 絶対に書き換えられないコンプライアンスモードを指定
      days   = 90           # 90日間は誰もこのログに手を加えられないように保護
    }
  }
}

この設定をしておけば、万が一サーバーが攻撃者に完全に支配され、ログを消去しようと「aws s3 rm」のようなコマンドを実行されても、AWS側が「いや、それはルール違反です!」と拒絶してくれます。ログの完全性がガッチリ守られるわけですね。

—

3. 「デジタル署名」で改ざんを完全に見抜く

WORMストレージで「物理的(システム的)に書き換えられないようにする」のと同時に、もう一つ重要な防御策があります。それが「デジタル署名」です。

たとえストレージに保存されたログであっても、巧妙な攻撃者がストレージの隙間を突いて、1文字だけデータを書き換えたとします。そんなとき、「おや、このログ、どこか怪しいぞ」と見抜くための仕組みがデジタル署名です。

身近な例えでは、「封筒の閉じ口に押された、本人のサイン入り割り印(シーリングワックス)」をイメージしてください。
手紙の中身が1文字でも書き換えられていたら、封を開けたときにワックスの印が割れたり、サインが一致しなくなったりして、「あ、誰かに開封・改ざんされたな!」と一目で分かりますよね。

デジタル署名もこれと全く同じ原理です。

ログ署名のシンプルな仕組み

1. ログファイルが出力されるたびに、システムがその内容を元に「ハッシュ値(データの指紋のようなもの)」を計算します。
2. そのハッシュ値を、外部の安全な秘密鍵を使って暗号化し、「署名」としてログに添えます。
3. あとから検証するときに、「現在のログから計算したハッシュ値」と「添えられた署名を復元した値」を比較します。

  • ピッタリ一致すれば:「改ざんされていません!本物の証拠です!」
  • 一致しければ:「おっと、誰かがデータをいじりましたね!」

それでは、Pythonを使って、簡単なログの改ざん検知(署名と検証)のイメージをコードで見てみましょう。

import hashlib
import hmac

# 秘密の合言葉(実際には安全な秘密鍵管理システムで保管します)
SECRET_KEY = b"super-secret-key-for-soc"

def create_signed_log(log_message: str) -> dict:
    """ログメッセージにデジタル署名を付与する関数"""
    # 1. ログのメッセージをバイト列に変換
    message_bytes = log_message.encode('utf-8')
    
    # 2. 秘密鍵を使ってHMAC(デジタル署名の一種)を生成
    signature = hmac.new(SECRET_KEY, message_bytes, hashlib.sha256).hexdigest()
    
    # 3. ログ本体と署名をセットにして返す
    return {
        "log": log_message,
        "signature": signature
    }

def verify_log(signed_data: dict) -> bool:
    """ログが改ざんされていないか検証する関数"""
    log_message = signed_data["log"]
    received_signature = signed_data["signature"]
    
    # もう一度同じ方法で署名を計算し直す
    expected_signature = hmac.new(
        SECRET_KEY, 
        log_message.encode('utf-8'), 
        hashlib.sha256
    ).hexdigest()
    
    # 計算し直した署名と、受け取った署名が完全に一致するか比較
    return hmac.compare_digest(expected_signature, received_signature)

# --- 実験してみましょう ---
# 正常なログを作成
original_log = create_signed_log("2023-10-25 10:00:00 - User 'admin' logged in successfully.")
print("正常なログの検証結果:", verify_log(original_log)) # True (改ざんなし)

# 攻撃者がこっそりログの文字を書き換えたと仮定
tampered_log = {
    "log": "2023-10-25 10:00:00 - User 'hacker' logged in successfully.", # 悪意ある書き換え
    "signature": original_log["signature"] # 古い署名のまま
}
print("改ざんされたログの検証結果:", verify_log(tampered_log)) # False (改ざん検知!)

このように、コードレベルやログ転送のパイプライン(FluentdやLogstashなど)の段階でデジタル署名を組み込んでおけば、万が一ストレージの防壁をすり抜けてデータが書き換えられても、検証時に一発で嘘を見破ることができます。

—

4. まとめ:インシデントに備える第一歩

いかがでしたでしょうか?
「ログの完全性保護」というと、何やら分厚い専門書に出てくる難解な理論のように聞こえますが、本質はとてもシンプルです。

  • WORMストレージ(S3 Object Lockなど)で、物理的・システム的にログを消せない・書き換えられない「金庫」に入れる。
  • デジタル署名で、たとえ書き換えられても「誰かがいじった証拠」を数学的にすぐに見抜けるようにする。

この2つを組み合わせることで、私たちはインシデントが発生した際にも、揺るぎない証拠(フォレンジックデータ)を手にすることができます。

セキュリティの対策に「100パーセント安全」はありません。だからこそ、「万が一侵入された最悪のシナリオ」を想定し、「証拠だけでも絶対に守り抜く」という気構えが、私たちエンジニアやIT担当者には求められます。

難しく考えず、まずは小さくクラウドの設定を見直したり、ログの出力方式にハッシュを取り入れてみたりすることから、一歩ずつ対策を学んでいきましょう!あなたのその地道な積み重ねが、組織のセキュリティを確実に守る盾となりますよ。

コメント

タイトルとURLをコピーしました