皆さん、こんにちは!日々の開発やインフラの管理、本当にお疲れ様です。
システムを作ったり運用したりしていると、「PowerShell」という言葉をよく耳にすると思います。Windowsの管理にはなくてはならない便利な道具ですが、実はセキュリティの現場では、このPowerShellが「攻撃者に最も好まれる隠れ家」の一つになっていたりします。
今回は、セキュリティ初心者の方や、これからSOC(セキュリティ・オペレーション・センター)の仕事に挑戦する新人エンジニアの方向けに、攻撃者が仕掛ける「難読化された怪しいスクリプト」をどうやって見破り、解析するのかを、身近な例えを交えながら優しく紐解いていきたいと思います。一歩ずつ、一緒に学んでいきましょう!
—
1. なぜ攻撃者はPowerShellを悪用するのか?
突然ですが、皆さんのご自宅の玄関の鍵を思い浮かべてみてください。普通の鍵であれば、ピッキングするのには特別な技術や道具が必要ですよね。
しかし、もし「家の中に最初から入るためのマスターキーが備え付けられていて、しかも泥棒がそのキーを堂々と使っても、誰も怪しまない状態」だったらどうでしょう? 泥棒にとって、これほど楽なことはありませんよね。
WindowsにおけるPowerShellは、まさにこの「最初から用意された非常に強力なマスターキー」のようなものです。
攻撃者は、新しく怪しいウイルスのプログラムをわざわざ外から持ち込もうとはしません。それをしてしまうと、ウイルス対策ソフトに「怪しいファイルだ!」とすぐに見つかってしまうからです。
その代わり、Windowsの中に最初から入っている正規の道具であるPowerShellを悪用し、メモリ上で直接悪さをするコードをコソコソと動かします。これをセキュリティ業界では「Living off the Land(現地調達)」の攻撃と呼んでいます。ファイルとして痕跡が残りにくいため、非常に厄介なのです。
—
2. 攻撃者の隠れミノ:スクリプトの「難読化」
警察に見つからないように、怪しい身なりの泥棒が変装して街を歩くのと同じように、攻撃者もPowerShellのスクリプトをそのままでは使いません。セキュリティソフトや私たちアナリストに見つからないよう、コードをグチャグチャに書き換えて隠します。これが「難読化(にんどくか)」です。
例えば、次のような手法がよく使われます。
- Base64エンコード: 人間には読めない暗号のような文字列に変換してしまう。
- 文字の結合や置換: 「I」「E」「X」(実行を意味する
Invoke-Expressionの省略形など)という危険な文字を、バラバラに離して配置し、実行する直前に合体させる。
これらを目の当たりにすると、「うわ、何が書いてあるのか全然分からない……!」と頭がクラクラしてしまいますよね。でも、安心してください。私たちには、Windows自身が記録してくれる強力な「秘密の日記帳」があります。
—
3. 救世主「Script Block Logging(Event ID 4104)」とは?
ここで登場するのが、今回の主役である Script Block Logging(イベントID: 4104) です。
先ほど、攻撃者はコードを難読化して隠そうとするとお話ししました。しかし、どれだけ巧妙に変装しても、パソコンのCPUがそのプログラムを「実行」するその瞬間には、必ず「変装を解いて元の姿」に戻らなければなりません。
Script Block Loggingは、PowerShellが「実際に実行しようとした完全なスクリプトの中身」を、変装を解いた丸裸の状態でそのままログに記録してくれる機能です。
ログを有効にする設定手順
この強力なログ機能は、デフォルトでは無効になっている場合があるため、企業の環境などではグループポリシー(GPO)等で有効化しておく必要があります。
1. gpedit.msc (グループポリシーエディター)を開く。
2. 「コンピューターの構成」>「管理用テンプレート」>「Windows コンポーネント」>「Windows PowerShell」へと進む。
3. 「PowerShell スクリプト ブロックのログ記録の有効化 (Turn on PowerShell Script Block Logging)」を「有効」に設定する。
これで、怪しいスクリプトが実行された瞬間を、逃さずキャッチできるようになります!
—
4. 難読化されたスクリプトを動的に解読してみよう
それでは、実際の現場で遭遇するような、難読化されたスクリプトの解析アプローチを見ていきましょう。
例えば、イベントログ(Event ID 4104)の中に、以下のようなBase64でエンコードされた不審なコードを発見したとします。
# 【イベントログから見つかった怪しいBase64文字列の断片(例)】
$encodedText = "UwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgAG4AbwB0AGUAcABhAGQALgBlAHgAZQA="
一見すると、何のプログラムを起動しようとしているのかさっぱり分かりませんよね。しかし、これは単に文字を別の形式でオウム返しにしているだけです。
私たちアナリストは、この暗号のような文字列を安全な環境(サンドボックスなど)でデコード(解読)し、元の姿に戻します。PowerShellを使ってこれを解読するスクリプトは、次のように非常にシンプルです。
# 難読化された(Base64エンコードされた)文字列を安全にデコードするスクリプト例
$encodedText = "UwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgAG4AbwB0AGUAcABhAGQALgBlAHgAZQA="
# バイト配列に戻してから、UTF-16(Unicode)の文字列に変換します
$bytes = [System.Convert]::FromBase64String($encodedText)
$decodedScript = [System.Text.Encoding]::Unicode.GetString($bytes)
# デコードされた結果を表示する
Write-Output "--- デコード結果 ---"
Write-Output $decodedScript
上記のスクリプトを実行すると、画面には次のような「本当の姿」が浮かび上がります。
--- デコード結果 ---
Start-Process notepad.exe
「ななんだ、メモ帳を起動しているだけじゃないか」と思われるかもしれませんが、実際の攻撃では、ここからさらに外部の怪しいサーバーに接続して、もっと危険なウイルスをダウンロードするコマンド(例: Invoke-WebRequest や IEX など)が隠されていることがほとんどです。
—
5. SOCアナリストからの実務アドバイス
現場でログを分析していると、難読化のパターンは本当に多岐にわたります。何重にもエンコードされていたり、文字列が逆順になっていたりすることもあります。
そんなとき、焦って自分のパソコン上で直接そのスクリプトを実行してしまうのは絶対にNGです!それは、自宅の鍵穴に毒が塗られているかもしれないのに、素手で触ってしまうようなものです。必ず隔離された安全な検証環境(仮想マシンなど)で解析を行うようにしましょう。
また、SOCの現場では、人間が一つひとつログを目視で追うだけでなく、次のようなキーワードを自動検知のシグネチャ(アラートのルール)として設定しています。
Invoke-ExpressionやそのエイリアスであるIEXFromBase64String-encや-encodedcommand(コマンドプロンプトやPowerShellを起動する際の隠しパラメータ)
これらがログの中に頻繁に登場していないか、普段からアンテナを高くしておくことが大切です。
—
まとめ
今回は、PowerShellのScript Block Logging(Event ID 4104)を活用した難読化解除と検知の仕組みについて解説しました。
- PowerShellは攻撃者に悪用されやすい「身近なマスターキー」である。
- 攻撃者は「難読化」という変装を使って正体を隠そうとする。
- しかし、実行の瞬間を捉える Script Block Logging を使えば、変装を解いた丸裸のコードを暴くことができる。
- デコードや解析は必ず安全な環境で行う。
セキュリティの世界は一見すると難しそうに見えますが、一つひとつの仕組みを紐解いていけば、必ず「攻撃者の足跡」を見つけ出すことができます。
日々の運用や開発の中で、「あれ、この動きはちょっとおかしいぞ?」と感じる直感を大切にしながら、安全なシステム環境を守り育てていきましょう。それでは、また次回の記事でお会いしましょう!
コメント