管理者権限で実行されているプロセス (マルウェアなど) の検出法

サイバー攻撃者が Windows コンピュータで実行したいことの1つは、管理者権限を獲得することです。管理者権限が取得できれば、組織内のPCを自由に使用できます。

このような潜在的なサイバー攻撃者の先手を取って防御するには、組織の管理者アカウントで実行されているプロセスを把握する必要があります。PowerShell を使用すると、費用をかけずにこれを行うことができます。

ネットワーク上のコンピュータの検出

潜在的に危険なネットワーク上のプロセスを発見するために最初に必要なのは、ネットワーク上のすべてのコンピュータを見つけることです。Active DirectoryAD)がある場合(たいていの場合はそのはずです)は、Active Directory PowerShell モジュールの Get-AdComputer コマンドレットを使用できます。

このコマンドは、ADからすべてのコンピュータ名を返します。アウトプットが $adComputers に割り当てられます。以降のスクリプトでは、この変数に格納されているコンピュータ名を使用します。

$adComputers = Get-AdComputer -Filter * | Select-Object -ExpandProperty Name

あるいは、WhatsUp Gold などのネットワーク監視ツールを使用すると、ネットワーク上のすべてのデバイスが自動的に検出され、マッピングされます。

プロセスの列挙

次に、コンピュータにプロセスをクエリして、どのコンピュータがそのプロセスを実行しているかをチェックする必要があります。そのための1つの方法は、PowerShell リモート処理と Get-Process コマンドを使用することです。普通はそれで問題ないのですが、Get-Process はプロセスの所有者を返しません。プロセスの所有者は後で必要になるので、WMI にクエリを実行してプロセスリストを取得します。

次の例では、フィルタを使って、返されるプロセスを単一のプロセス(malware.exe)に制限しています。Filter パラメータを外せば、すべてのプロセスが列挙されます。

Get-CimInstance -ComputerName WEBSRV1 -ClassName Win32_Process -Filter "Name = 'malware.exe'"
ProcessId Name HandleCount WorkingSetSize VirtualSize PSComputerName
--------- ---- ----------- -------------- ----------- --------------
1864 malware.exe 158 6524928 41701376 WEBSRV1

プロセスの所有者を検出

プロセスが見つかったら、そのプロセスを実行しているユーザーを特定する必要があります。そのためには、返された各プロセスオブジェクトで GetOwner() CIMメソッドを呼び出します。

下の例の $p Get-CimInstance から返されたプロセスの1つを表します。User プロパティを調べると、この特定のプロセスの所有者が NETWORK SERVICE であることがわかります。

(Invoke-CimMethod -InputObject $p -MethodName GetOwner).User
NETWORK SERVICE

管理者グループのメンバーを検出

プロセスがコンピュータ上で実行されており、そのプロセスの所有者が確認できたら、次に、そのコンピュータ上の Administrators グループのメンバーであるすべてのローカルユーザーを収集します。

下のコードは、ADSI を使用して、まず Administrators グループにクエリを行います。次に、Invoke() メソッドを使用して、そのグループの各メンバーを列挙します。メンバーが見つかると、各メンバーの名前を返します。

$group = [ADSI]"WinNT://[computer name]/Administrators"
@($group.Invoke('Members')) | foreach {
    $_.GetType().Invokemember('Name','GetProperty',$null,$_,$null)
}

スクリプトの作成

必要な処理を行う各コードがそろったので、すべてをスクリプトにまとめる準備ができました。下のスクリプトは、malware.com プロセスが実行されている Active Directory 内のすべてのコンピュータを検出し、そのプロセスの所有者がローカル管理者のグループのメンバーであれば、「このコンピュータは管理者権限でマルウェアを実行しています!」というメッセージを赤で表示します。

$adComputers = Get-AdComputer -Filter * | Select-Object -ExpandProperty Name
foreach ($computer in $adComputers) {
    if ($malwareProcs = Get-CimInstance -ComputerName $_ -ClassName Win32_Process -Filter "Name = 'malware.exe'") {
        $adminGroup = [ADSI]"WinNT://$_/Administrators"
        $adminMembers = @($adminGroup.Invoke('Members')) | foreach { $_.GetType().Invokemember('Name','GetProperty',$null,$_,$null) }
        $malwareProcs | foreach {
        if ((Invoke-CimMethod -InputObject $_ -MethodName GetOwner).User -in $adminMembers) {
            Write-Host "The computer [$($computer)] has malware running under admin privileges!!" -ForegroundColor Red
        }
    }
}

まとめ

PowerShell を使用して、ネットワーク上の複数のコンピュータに管理者権限で実行されているプロセスがあるかどうかを確認することができる例を説明しました。ネットワーク上のセキュリティインシデントとの戦いにお役立ていただければ幸いです。

Tags