リモートデスクトップによる不正接続の監視

はじめに

リモートワークや遠隔メンテンナンスなどのために、組織内のWindowsマシンへリモートデスクトップ(※以下「RDP」と略します)によるアクセスを許可している場合、セキュリティリスクには十分な注意が必要です。VPNやWindowsのアカウントが攻撃者に奪われた場合、Windowsマシンの完全な制御が攻撃者に渡り、機密情報の漏洩やランサムウェアの展開など重大な被害を受ける可能性があるからです。弊社でフォレンジック調査のご相談を受けるサイバー攻撃の手口でも、VPNの脆弱性などを悪用したWidowsマシンへのRDP不正接続が増加している感があります。

こうした被害を防止するには、インターネットに露出したVPNやファイアウォールなど、いわゆるアタック・サーフェスの認証制御やアクセス制限を強化することが重要です。逆に言えば、攻撃者は脆弱性スキャンやフィッシングによる認証情報窃取などのさまざまな手口を駆使し、露出ポイントからの侵入を試行しますので、万が一防ぎきれずに侵入されてしまった場合に備えた検知方法も考えておくべきでしょう。

本稿では、RDP不正接続による侵入をいち早く検知するための基礎知識や具体的な監視方法についてご紹介します。

RDP接続時に記録されるイベントログ

一般的に、Windowsのセキュリティイベントログ(Security.evtx)でRDP接続のログオンを監視する場合、ログオンイベント(ID:4624)のログオンタイプ:10(リモートインタラクティブログオン)を検知対象とします1 。ちなみに、手元にあるWindowsマシンにローカルログオンした場合は、ログオンタイプ:2(インタラティブログオン)が記録されます。次のスクリーンショットは、イベントビューアーでログオンタイプ:10のイベントログを表示したものです。

しかし、RDP接続時にもログオンタイプ:10が記録されない場合があります。これは、前回のRDP接続終了時にログアウトせず、RDP接続を切断するのみで、セッションを持続したままにしているケースです。なんらかの原因でセッション中に通信がダウンした場合や、次の画面のようにRDPウィンドウの「閉じる」ボタン(✕)をクリックし、ポップアップしたメッセージ画面で「OK」をクリックした場合などが該当します。

セッションが持続した状態で、もし攻撃者がそのセッションの認証情報を入手してRDPにより不正接続すると、Windowsのシステムでは「再接続」とみなされます。この場合は、ログオンイベントにログオンタイプ:10は記録されませんので、侵入を見逃す可能性があります。

そこで、セキュリティイベントログだけではなく、「Microsoft-Windows-TerminalServices-LocalSessionManager/Operational」(※以下「TS-LSM」と略します)として記録されるイベントログも併せて監視することを推奨します。このログには、RDPのセッション開始(ID:21)、切断(ID:40)、再接続ID:25)に関する詳細な情報が記録されており、単なるログオンイベントだけでは把握できない活動を検出することができます。次のスクリーンショットは、イベントビューアーでRDP再接続のTS-LSMイベントログを表示したものです。

このように、不正なアクセスやセッションの持続的利用を防ぐため、複数のイベントログを一貫して監視し、異常なログオンや再接続を見逃さないようにすることが重要です。とはいえ、イベントログの記録だけでは、接続元が正規利用者か攻撃者かを機械的に判断するのは難しい面もあります。判断材料になるものとして、接続元のIPアドレスやコンピューター名が記録されていますが、攻撃者はVPNの悪用やソーシャルエンジニアリング/OSINTで入手した社内ルールの流用など、検知回避のためにさまざまな偽装工作を施してきます。そこで、正規利用者自身がリアルタイムで不正接続を検知する、シンプルな方法を考えてみました。

RDP不正接続のリアルタイム検知

攻撃者が認証情報を入手してRDP不正接続したと想定し、その際に観測されるイベントを整理すると、次のようになります。

  1. 正規利用者がログアウトしている場合

    • セキュリティイベントログ(Security.evtx)に、ログオンイベント(ID:4624)でログオンタイプ:10が記録される。

    • TS-LSMイベントログに、セッション開始(ID:21)が記録される。

  2. 正規利用者がセッションを持続したままRDP切断している場合

    • セキュリティイベントログ(Security.evtx)に、ログオンイベント(ID:4624)でログオンタイプ:3が記録される(ログオンタイプ:3はネットワーク経由のログオン全般を示すもので、内部ネットワークのPCから共有フォルダへのアクセス時などにも記録されるため、ログの山に埋もれる可能性あり)。

    • TS-LSMイベントログに、再接続(ID:25)が記録される。

1と2のいずれにしても、正規利用者が当該Windowsマシンを利用していないときにログが記録されますので、TS-LSMイベントログを監視して、セッション開始(ID:21)または再接続(ID:25)の発生をメール等で通知すれば、正規利用者自身がリアルタイムでRDP不正接続に気が付くでしょう。このような監視のために、簡単なPowerShellスクリプトを書いて実装してみました。

# メール設定
$smtpServer = "(送信に使用するSMTPサーバーのホスト名)" 
$smtpFrom = "(送信元のメールアドレス)" 
$smtpTo = "(受信者のメールアドレス)"  
$smtpPort = 25  # SMTPポート番号を設定
$smtpSubject = "新しいリモートデスクトップ接続が発生しました"
$smtpBody = "新しいリモートデスクトップセッションが発生しました。詳細は以下の通りです:`n"

# メール送信関数
function Send-EmailNotification($message) {
    # SMTPサーバー情報を設定
    $smtp = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort)

    # メールメッセージを作成
    $mailMessage = New-Object System.Net.Mail.MailMessage
    $mailMessage.From = $smtpFrom  # 送信元
    $mailMessage.To.Add($smtpTo)   # 送信先
    $mailMessage.Subject = $smtpSubject  # 件名
    $mailMessage.Body = $smtpBody + $message  # 本文

    # メール送信
    $smtp.Send($mailMessage)
}

# 現在の日時を取得
$endTime = Get-Date

# 起動3分前の日時を計算(ログオン時に自動起動した際、3分前まで遡及してRDP経由のログオンイベントを取得)
# ※ 移動ユーザープロファイルを使用している場合など、ログオン処理に時間がかかる場合は時間を適宜調整する
$startTime = $endTime.AddMinutes(-3)

# TS-LSMイベントログの監視ループ
while ($true) {
    # 画面に監視対象時刻を表示
    Write-Host "リモートデスクトップセッションを監視中..."
    Write-Host "監視対象時刻範囲:"
    Write-Host "開始時刻: $startTime"
    Write-Host "終了時刻: $endTime"

    # イベントID 21(RDP経由のログオン)と 25(RDPセッションへの再接続)の監視
    Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" -FilterXPath "*[System[(EventID=21 or EventID=25)]]" | Where-Object {
        $_.TimeCreated -ge $startTime -and $_.TimeCreated -le $endTime
    } | ForEach-Object {
        $eventTime = $_.TimeCreated
        $eventUser = $_.Properties[1].Value  # 接続ユーザー
        $eventSessionID = $_.Properties[0].Value  # セッションID

        # イベントIDによってメッセージを変更
        if ($_.Id -eq 21) {
            $eventType = "接続"
        } elseif ($_.Id -eq 25) {
            $eventType = "再接続"
        }

        # メール本文に追加するメッセージ
        $message = "イベントタイプ: $eventType`n接続ユーザー: $eventUser`n接続時間: $eventTime`nセッションID: $eventSessionID"

        Write-Host "新しいセッションを検出: タイプ $eventType, ユーザー $eventUser, セッションID $eventSessionID, 接続時間 $eventTime"

        # メール通知を送信
        Send-EmailNotification $message
    }

    # 60秒間隔でループし、監視を続ける
    Start-Sleep -Seconds 60

    # 前回の監視終了時刻を次の監視開始時刻に設定
    $startTime = $endTime
    # 現在の日時を取得し、監視終了時刻に設定
    $endTime = Get-Date
}

このスクリプトには、次の機能があります。

  • 60秒毎にTS-LSMイベントログからセッション開始(ID:21)または再接続(ID:25)の発生を検知
  • 検知内容を指定メールアドレスへメール送信により通知

このスクリプトの起動については、正規利用者アカウントのスタートアップフォルダに起動用ショートカットファイルを設置しておき、正規利用者アカウントでログオンすると自動的に起動されることを想定しています。起動後は強制終了しない限り動き続けますので、RDP切断後もセッションが持続していれば監視が継続されます。ログアウトした場合には終了しますが、攻撃者が不正接続した際にまた自動起動されますので、セッション開始を検知して通知が飛ぶことになります。次のコマンド例は、ファイル名「C:\RDP_mon\rdp_monitor.ps1」に保存された上述のPowerShellスクリプトを起動するもので、スタートアップフォルダに設置するショートカットファイルのリンク先に直接指定することができます。

cmd /c powershell -ExecutionPolicy Bypass c:\RDP_mon\rdp_monitor.ps1

起動後のターミナル画面には、次のように監視中のメッセージやRDP接続の検出アラートが表示されます(ターミナル画面を非表示にしておきたい場合は、上述のコマンドに「-WindowStyle hidden」オプションを付加してください)。

リモートデスクトップセッションを監視中...
監視対象時刻範囲:
開始時刻: 09/30/2024 12:01:28
終了時刻: 09/30/2024 12:02:28
新しいセッションを検出: タイプ 再接続, ユーザー 1, セッションID IC\cditest, 接続時間 09/30/2024 12:02:16

RDP接続を検知した場合は、次のようにアラートメールが送信されます(なお、正規利用者自身がRDP接続した際にも飛んできます)。

この方法により、正規か不正かを機械的に判断することが難しいRDP接続について、正規利用者自身がリアルタイムで監視することができます。

おわりに

RDP不正接続をリアルタイム検知する方法の一例をご紹介しました。ここで紹介した方法はあくまで簡易的なもので、EDRやSIEM等のセキュリティソリューションを導入していれば、もっと安全かつ確実に監視する方法を構築できるでしょう。また、今回の検証は自分が使用するWindows 10とWindows 11の環境でのみ実施しています。OSの種類・バージョンや設定等によって異なるログの出力形式となる可能性もありますので、構築時には事前に検証していただければと思います。

実際に深夜・早朝・休日、不正接続検知のアラートメールが飛んできたら・・・と想像するとかなり怖いです。しかし業務の中では、さまざな役割のサーバーや長時間かかるタスクを実行中のPCなど、シャットダウンしておくことが難しいマシンも多いでしょう。不正接続を「知らぬが仏」で済ませるのはリスクが高すぎます。何も起きていないことを担保するただの「お守り」であってほしいですが、昨今の状況ではリアルタイム監視の必要性を感じてしまいます。

なお、セキュリティイベントログの詳細や分析方法については、弊社が無償で公開しているフォレンジック学習コンテンツ「CDIR-L CE」の13章の中でも詳しくご紹介しておりますので、興味をお持ちになりましたらぜひご一読ください。

© 2016 - 2024 DARK MATTER / Built with Hugo / テーマ StackJimmy によって設計されています。