VPNログとAD認証ログの「不協和音」を見逃すな:侵害検知の最前線
現場のエンジニア諸君、お疲れ様。今日も「ログイン成功」のログを眺めて安心しているなら、その考えは今すぐ捨てたほうがいい。
多くの企業で導入されているVPN。テレワーク全盛の今、これは社内ネットワークへの「最も広大な玄関」だ。攻撃者はわざわざ難攻不落のWebサーバーを直接叩いたりしない。認証が突破できそうなVPNゲートウェイを狙い、盗んだID/PASSで「正当なユーザー」になりすまして侵入する。これが現代のサイバー攻撃の定石だ。
今回は、VPNログとActive Directory(AD)認証ログを突き合わせて、「攻撃者の足跡」を炙り出すための実践的なフォレンジック手法を伝授する。
1. なぜ「VPNログ」単体では不十分なのか
VPNのログだけを見ていると、IPアドレスの地理的情報(GeoIP)や、接続時間だけが判断基準になりがちだ。しかし、攻撃者はVPNを突破した後、社内のAD認証を使って横展開(ラテラルムーブメント)を試みる。
真の攻撃者は、VPN接続の直後に「社内リソースへの異常なアクセス」や「ADアカウントの連続的な認証失敗」を繰り返す。VPNログ(どこから入ったか)とADログ(誰が何をしようとしたか)を突き合わせることで初めて、「VPN経由で侵入した犯人が、どのアカウントを乗っ取って徘徊しているか」が見えてくるんだ。
2. 攻撃検知のための突き合わせロジック(Python実装)
SIEMツールがない環境でも、ログをCSVやJSONでエクスポートできれば、Pythonで突き合わせは可能だ。以下のスクリプトは、VPN接続ログとAD認証イベントID:4624(ログイン成功)/4625(ログイン失敗)を突き合わせ、「短時間での場所移動」や「VPN接続後の異常な認証試行」を検出する雛形だ。
import pandas as pd
from datetime import timedelta
# ログを読み込む想定のデータフレーム
# vpn_logs: ['timestamp', 'user_id', 'source_ip']
# ad_logs: ['timestamp', 'user_id', 'event_id', 'workstation']
def detect_anomaly(vpn_df, ad_df):
anomalies = []
# ユーザーごとに突き合わせ
for user in vpn_df['user_id'].unique():
user_vpn = vpn_df[vpn_df['user_id'] == user]
user_ad = ad_df[ad_df['user_id'] == user]
for _, vpn_row in user_vpn.iterrows():
# VPN接続後1時間以内に発生したADログイン失敗を抽出
threshold = vpn_row['timestamp'] + timedelta(hours=1)
suspect_ad = user_ad[(user_ad['timestamp'] > vpn_row['timestamp']) &
(user_ad['timestamp'] <= threshold) &
(user_ad['event_id'] == 4625)]
if not suspect_ad.empty:
anomalies.append({
'user': user,
'vpn_ip': vpn_row['source_ip'],
'msg': 'VPN接続直後にAD認証失敗が多発しています'
})
return anomalies
# 実際の実務ではこれをCronで回し、Slack等に通知を飛ばす設計にする
3. 【防御編】認証を突破させないための「ゼロトラスト」設定
突き合わせで異常を見つけるのは「事後」の対応だ。そもそも侵入させない、あるいは侵入しても被害を最小化する設定を入れよう。
NginxでのVPN/認証ポータル保護設定
VPNゲートウェイのフロントにWAFやリバースプロキシを置いているなら、以下の設定で「怪しい接続」を弾く準備をしておくことだ。
# /etc/nginx/conf.d/security.conf
# 特定の国以外からのVPN接続要求を遮断(GeoIPモジュール利用)
map $geoip_country_code $allowed_country {
default no;
JP yes; # 日本からのアクセスのみ許可
}
server {
location /vpn-portal/ {
if ($allowed_country = no) {
return 403; # 日本以外は門前払い
}
# 連続的な接続試行を制限(レートリミット)
limit_req zone=vpn_limit burst=5 nodelay;
proxy_pass http://vpn_backend;
}
}
PowerShellによるADアカウントロックアウトポリシー
攻撃者は「パスワードスプレー攻撃」を好む。AD側で以下の設定を徹底し、閾値を下げる。
- アカウントロックアウトのしきい値: 5回(デフォルトのままにしない)
- リセット期間: 30分(攻撃者が時間をかけて試行するのを防ぐ)
4. 最後に:エンジニアが持つべき「疑いの目」
フォレンジックとは、単なるログ分析ではない。「このログインが、本人によるものだという根拠は何か?」と常に自問自答するプロセスだ。
もし、VPN接続元のIPが東京で、その3分後に大阪のサーバーへログインしているログを見つけたらどうする? 「システムエラーかな?」と考えるのはエンジニアとして甘い。それは、VPNのセッションハイジャックか、あるいは別々の経路を使った同時進行の攻撃かもしれない。
「ログは嘘をつかないが、見方次第でどうとでも解釈できる」。この言葉を肝に銘じて、日々の監視体制を構築してほしい。何か怪しい挙動を見つけたら、まずはそのセッションを即時切断し、該当アカウントを無効化する。これが現場で最も頼られるエンジニアの初動だ。
さあ、今すぐログをエクスポートして、突き合わせを始めてみてくれ。君のシステムを守れるのは、君しかいないんだから。
コメント