本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。

最新情報

2021.02.19

プロセス情報をデタラメにする攻撃「Process Herpaderping」の内部構造を紐解く

早速ですが、まずは以下の図1をご覧ください。
真ん中にメッセージボックスが表示されていますが、このメッセージボックスを表示するプロセスがどこから起動しているのか、つまり、実体EXEファイルの場所がこの図からわかるでしょうか?

20210219_01.png

図 1 プロセス情報がデタラメになっている様子

図1では、Process ExplorerやProcess Hackerで見る限り、プロセス名は「こんばんは!★」(拡張子なし)となっています。各ツールで表示されたプロセスのプロパティ情報を見ると、Process Explorerでは実体の場所がExplorer.exeであるかのように見えてしまっています。
一方でProcess Hackerでは、メッセージボックスのプロセスがMicrosoftの有効なデジタル署名を持っているかのように見えており、実体の場所が「こんばんは!★」を指しているように見えます。
では該当の「こんばんは!★」のファイルの中身は何でしょうか。実際に「こんばんは!★」のファイルの中身をバイナリエディタなどで見ても正規のsvchost.exeと同じバイナリが並んでおり、そこにメッセージボックスを表示させるコードは結局のところ存在しません。
答えと言ってしまうと、このプロセスの実体は、実は図1の紫で囲ったファイルのうちの一つである「MsgBox1.exe」なのですが、こうしてプロセスが持つ情報をいくら調べてもこの答えにたどり着く術はありません。
今回解説する手口を悪用すれば、この図が示したとおり、プロセスから得られる情報はもはや無意味となり、何が真実かを判断することはできなくなってしまいます。

これはProcess Herpaderping(プロセスハーパダーピング)と呼ばれるテクニックを応用しており、本記事では以降で冒頭の攻撃手法がどのようにして成立しているのかを詳しく解説していきます。

今のところ、Process Herpaderpingを深く理解するために役立つ情報は(発明者以外のサイトでは)世界的にもほぼ存在しておらず、本記事がこうした脅威を理解する手助けになれば幸いです。

記事の後半では、本件に関連してデジタル署名を悪用する手口の解説や対策、記事の末尾には動画(YouTube)も掲載していますので、併せて是非ご覧ください。

Process Herpaderpingの概要

Process Herpaderping はセキュリティ研究者であるJohnny Shaw氏(@jxy__s)が発明し2020年に一般公開した攻撃手法です。Johnny Shaw氏はこの問題をMicrosoftへ報告していますが、本問題の修正は最終的に直近では実施されないという結論となったようです。
「Derp」や「Herp Derp」という言い回しは、インターネットで使用されてきた英語のスラングであり、”マヌケ”や”バカバカしい”という意味で使用されています。つまり、「Process Herpaderping」とは、"プロセスを無意味でマヌケ(=デタラメ)な状態にする"という意味が込められています。
(この命名の由来については、Johnny Shaw氏に直接その意図を確かめました)

Process Herpaderpingの流れ

Process Herpaderpingに関する技術詳細は当然本家のサイトに掲載されてはいるのですが、幾分本技術が非常に難解であり、また一部省略され記載されていない情報も存在するため、ここではそうした情報を盛り込みながら、より噛み砕いて解説していきます。

Process Herpaderpingには、以下の図の通りZ.exe、A.exe、B.exe、C.exeという登場人物が初めに登場します。Z.exeはProcess Herpaderpingを行うプロセス、A.exeは実際に実行したいEXEファイル(つまりマルウェアなどが該当)、B.exeは処理の中で一時的に使用するために作成されるファイル、C.exeは最終的に見せかけたいEXEファイル(正規ファイルなどが該当)です。

では以降で、Process Herpaderpingの処理の順を追って解説していきましょう。

まず、Z.exeがA.exeとB.exeのファイルハンドルを取得し(下図①②)、A.exeをB.exeに上書き(コピー)します(下図③)。
この時点でB.exeの中身はA.exeになっています。

20210219_02.png

図 2 Process Herpaderping 第1段階

続いて、Z.exeのプロセス内にB.exeを「イメージセクションオブジェクト」として作成します(下図⑤⑥)。(「イメージセクションオブジェクト」というものが一体何なのか、その詳細については後述しますが、ここではB.exeを指すポインターのような概念で捉えておきます。)

20210219_03.png

図 3 Process Herpaderping第2段階

そして、作成したイメージセクションオブジェクトから「プロセスオブジェクトα」を作成します(下図⑦)。ここでポイントなのは、B.exeから作成するのではなく、B.exeから作成した「イメージセクションオブジェクト」を使って作成するという点です。B.exeの中身はA.exeでしたので、この時点でプロセスオブジェクトαの中身はAのプログラムコードが含まれている状態になっています。

20210219_04.png

図 4 Process Herpaderping第3段階

次に、ここで少しPEファイルにおけるAddressOfEntryPointの位置関係をおさらいしましょう。
PEファイルではIMAGE_OPTIONAL_HEADERの構造体内にAddressOfEntryPointと呼ばれるメンバを持っています。これはモジュールの先頭から見たエントリーポイントの仮想アドレス(RVA)となります(下図参照)。

20210219_05.png

図 5 AddressOfEntryPointの位置関係

Z.exeはB.exeのAddressOfEntryPointを取得したのち(これは後で使用)、C.exeの内容をB.exeにバイト単位で上書き(コピー)します。この時点で、B.exeの中身はC.exeとなります(下図)。
ここで非常に重要なポイントは、B.exeをC.exeで上書きできるという点です。一般的にB.exeのプロセスが起動中は実体を書き換えられないという暗黙の思い込みがありますが、それが可能であるということです(詳細は後述)。

また下図の通り、この時点でプロセスオブジェクトαはB.exeから生成されているものの、プロセスオブジェクトαの中身はA.exeであり、B.exeの実体ファイルの中身はC.exeというデタラメな状態にすでになっていることがわかります。
ただし、この時点でまだプロセスオブジェクトαはプロセスとして動き出していません。以降で、プロセスとして動かすための仕上げに入ります。

20210219_06.png

図 6 Process Herpaderping第4段階

ここで再び、プロセスにおけるImageBaseAddressの場所をおさらいしましょう。プロセスにおけるImageBaseAddressとはメインモジュールの先頭アドレスを指しますが、ImageBaseAddress を取得するためには、PROCESS_BASIC_IMFORMATION構造体内のPebBaseAddressからPEB(Process Environment Block)の場所を取得した後、該当場所にあるPEB構造体の中のImageBaseAddressというメンバを参照することで取得できます。

20210219_07.png

図 7 ImageBaseAddressの位置関係

再び話を戻しましょう。
Z.exeはプロセスオブジェクトαのImageBaseAddress、つまり、メインモジュールの先頭アドレスを取得します(下図⑫⑬)。

20210219_08.png

図 8 Process Herpaderping第5段階

続いて、プロセスパラメータの調整を行った後(下図⑭)、プロセスオブジェクトのエントリポイントのアドレスを計算します。プロセスオブジェクトのエントリポイントのアドレスは、先程までに取得してきた、ImageBaseAddressとAddressOfEntryPointを足し合わせることで算出できます(下図⑮)。

そして最後に、プロセスオブジェクトのエントリポイントのアドレスを指定してリモートスレッドを作成することで、プロセスとして開始させます(下図⑯)。

20210219_09.png

図 9 Process Herpaderping第6段階

その結果、どのような状態になるでしょうか。
プロセスαのイメージパス(実体場所)はB.exeを指しており、プロセスαの中身はA.exeのプログラムコード、実体ファイルであるB.exeの中身はC.exeのバイナリになっているという、”プロセスと実体ファイルの整合性が取れない奇妙な状態”が作り出されたことがわかります(下図)。

下図は、A.exeがMsgBox1.exe、B.exeがtmp.exe、C.exeがMsgBox2.exeに対応した状況下での実際の様子ですが、画面中央にはA.exe(中身がMsgBox1.exeのコード)のプロセスが起動しており、プロセスの実体パスはB.exe(tmp.exe)を指し、B.exeの中身はC.exe(MsgBox2.exe)のデータとなっています。つまり、プロセスの中身のプログラムの実体(A.exe)がどこに存在するのかが不明瞭になっていることがわかります。

20210219_10.png

図 10 Process Herpaderpingの結果

Process Herpaderpingの応用

以上がProcess Herpaderpingの基本的な流れですが、本記事においては、さらにそれに加えてプロセスパラメーターを改ざんすることでより応用したPoCを作成しました。
それが冒頭にも掲載した下図です。

※下図の各ファイルを、これまでのABCに対応付けて説明すると、A.exeが「MsgBox1.exe」、B.exeが「こんばんは!★」、C.exeが「svchost.exe」(MSの正規プログラムのコピー)となります。なお、プロセスを作成する際に拡張子は不要のため、「こんばんは!★」という特殊なプロセスが生成できていますが、これはWindowsの仕様です。

NtCreateProcessExで生成した際のプロセスは、イメージパス情報(実体パス)やコマンドライン情報、カレントディレクトリ情報、ウィンドウタイトル情報などを、RtlCreateProcessParametersExというAPIを使用することで偽装することが可能です。
つまり、ただでさえデタラメになっているProcess Herpaderpingで作成したプロセスにおいて、さらにイメージパスやコマンドライン情報までデタラメにすることが可能ということです。

SysinternalsのProcess Explorerは純粋にRtlCreateProcessParametersExで指定したプロセス情報をもとにプロパティ情報を表示するため、特にこの手口に騙されやすいと言えます。
以下の図はイメージパス情報として「C:¥Windows¥explorer.exe」という文字列を埋め込んで改ざんしたプロセスを使用していますが、Process Explorerはその情報に騙され、本物のExplorer.exe側を参照してアイコンやデジタル署名情報を取得してしまっています。
一方で、Process HackerはRtlCreateProcessParametersExで指定されたプロセス内のイメージパス情報を参照しないため、Process Explorerよりは本物に近い実体(B.exe=「こんばんは!★」というファイル)を表示できています。ただし、Process Hackerが表示したB.exe(=「こんばんは!★」というファイル)についても中身がC.exe(ここでは正規のsvchost.exe)となっているため、結局ProcessHackerも正規のSvchost.exeのデジタル署名をプロセスに表示してしまっており、いずれにしてもMsgBox1.exeの実体にはたどり着けません。つまり、メッセージボックスを表示しているプロセスの実体を特定することはもはや不可能であると言えます。

20210219_11.png

図 11 プロセスパラメーターの改ざんを加えたProcess Herpaderpingの結果

また、プロセスパラメーターを改ざんできるという問題とProcess Herpaderpingをうまく組み合わせることで、更に次のような状況も作り出せます。
上記の図ではB.exeを「こんばんは!★」という適当なファイル名にしていましたが、B.exeを「explorer.exe」というファイル名にすればどうなるでしょうか?
下の図の通り、Process Explorerは実体も本物のエクスプローラーを参照してしまっているため、Process Explorerではもはや正規のエクスプローラーのプロセスとの違いが表面的な情報からはほとんど判別できなくなります。
この辺りは本家のサイトでは触れられていませんが、脅威となる応用方法といえるでしょう。

20210219_12.png

図 12 プロセスパラメーターの改ざんをより巧妙にした結果

Process Herpaderpingがデジタル署名を有効に保つ仕組み

これまでに紹介したProcess HerpaderpingではC.exeがデジタル署名を持つファイルであった場合、B.exeを上書きすることでファイルサイズが変わってもデジタル署名を有効な状態に当たり前のように保てていましたが、本来ファイルサイズが変わるとデジタル署名は無効になるはずです。
実はここにデジタル署名の仕様を悪用したテクニックが併用されています。この点についても本家のサイトでは触れられていませんので、詳しく解説していきます。

では、どのようにしてファイルサイズが変化したファイルでデジタル署名を有効に保たせているのでしょうか。まずはPEファイルで使用されるデジタル署名の仕様を見ていきましょう。

PEファイルの末尾にはデジタル署名のデータが記録されていますが、それは「属性証明書テーブル」という入れ物に入っています。
そして、デジタル署名の仕様には以下の図にあげる2つの重要なポイントがあります。
1つ目のポイントは、PEファイルのヘッダにある証明書テーブル(Certificate Table)フィールドに、「属性証明書テーブル」のサイズが記録されています。具体的には、証明書テーブルフィールドは8バイトの構造を持っており、その中の後半4バイトにサイズ情報が含まれています。
そして2つ目のポイントは、属性証明書テーブルはデジタル署名のハッシュ計算によるバイナリの整合性チェックから除外されているということです。

20210219_13.png

図 13 PEファイルにおけるデジタル署名の仕様

つまり、元のファイルよりもファイルサイズが大きい状態=元のファイルの末尾に追記された領域を持つファイルになっている場合、デジタル署名を有効にするためには、証明書テーブルフィールドのサイズ情報をその差分のサイズ分だけ加算してあげればよいのです。そうすることにより、属性証明書テーブルの範囲が拡大されて解釈されるようになり、追加されたデータの領域はデジタル署名のハッシュ計算の整合性チェックから除外されるようになります。この調整により、デジタル署名を持つファイルの末尾にどのようなデータが追加されサイズが変化しても、デジタル署名を有効に保たせることが可能となります。

20210219_14.png

図 14 属性証明書テーブルのサイズ拡張による改ざん

より理解するために実際の図で具体的に見ていきましょう。
下図の左側は正規のsvchost.exeのEXEファイルであり、当然デジタル署名のタブをプロパティ情報から確認することができます。その正規のsvchost.exeの末尾に16バイト適当なデータを追記したものが下図右側のsvchost_after.exeです。ファイルが変化したため、当然ファイルのプロパティ情報からデジタル署名のタブが表示されなくなりました。

20210219_15.png

図 15 デジタル署名が認識されなくなる様子

そこで、svchost_after.exeのOptional Headerにある証明書テーブルフィールドのサイズ(下図ではSecurity Directory Size)を見てみると、0x2410(バイナリの並びでは10 24 00 00)となっています。

さきほどsvchost.exeの末尾に16バイト追加したので、同じく16(0x10)バイト増やしてみましょう。0x2410+0x10=0x2420ですので、svchost_after.exeの証明書テーブルフィールドのサイズ箇所を0x2420に変更します。リトルエンディアンのため、10 24 00 00を20 24 00 00に書き換えることになります。

20210219_16.png

図 16 証明書テーブルフィールドを手動で修正する様子

その結果、svchost_after.exeのファイルプロパティを見てみると、デジタル署名のタブが出現しました。さらにデジタル署名は有効のままであることがわかります(下図)。
つまり、ファイルの末尾に任意のデータを追加してデジタル署名が認識されなくなった後でも、証明書テーブルフィールドのサイズを修正すれば、デジタル署名を復元し有効に保たせることが可能であることがわかります。

20210219_17.png

図 17 デジタル署名のタブが復元された様子

ではProcess Herpaderpingでこのデジタル署名の仕様がどのように悪用されているのでしょうか。
これまで説明したとおり、Process Herpaderpingの処理の過程では、後半でB.exeをC.exeで上書きする処理が存在します。その際、C.exeがデジタル署名を持つプログラムであった場合、B.exeがC.exeよりもファイルサイズが小さい場合は単純に上書きすればよいですが、B.exeがC.exeよりもファイルサイズが大きい場合は、そのままではファイルがはみ出してしまいます。そのため、差分のサイズ分、証明書テーブルフィールドのサイズを調整すれば、B.exeがC.exeよりも大きいファイルであっても、デジタル署名を有効に保たせることが可能となります。
マルウェアのインシデント調査や、セキュリティ製品においてはプロセス情報をもとにデジタル署名を参照することがしばしばあるため、Process Herpaderpingにおいてデジタル署名を有効に保たせることはさらにそれらを翻弄させやすくする重要な意味を持ちます。

20210219_18.png

図 18 Process Herpaderpingで悪用されるデジタル署名の仕様

では、実際にB.exeがC.exeよりもファイルサイズが大きいケースにおいて、Process Herpaderpingを行った後のファイル差異を確認してみましょう。以下の図の通り、B.exeとC.exeのファイル差分(1,051,120バイト)分、証明書テーブルフィールドのサイズが加算されていることがわかります。

20210219_19.png

図 19 Process Herpaderping後の実際のファイル差異

(補足情報)デジタル署名の仕様の悪用

話の流れでデジタル署名の仕様に言及したため、この仕様を狙って悪用する手口にも触れておきます。お気づきの方もいらっしゃるかと思いますが、この仕様を悪用すれば、デジタル署名を有効に保ったファイルの末尾に任意のデータを含ませることができます。
つまり、デジタル署名を有効に保ったまま”任意の正規プログラム”の末尾に”任意のデータ”を隠蔽することが可能であるということです。もちろん、改ざんされたEXEファイルはその状態でも実行すると正常に正規プログラムとして機能します。

20210219_20.png

図 20 任意のデータを埋め込ませた状態でデジタル署名を有効に保たせることができる

これも具体例を見てみましょう。
例えば、以下は正規のsvchost.exeのデジタル署名を保たせたまま、svchost.exeの末尾にマルウェアのC2設定情報(を想定したデータ)を書き込んだ様子です。別のプロセスとして動作するマルウェアがこのように不正コードや設定情報を正規ファイルの内部に隠蔽することで、様々な検知や調査を逃れることが可能となります。
なお、すでにこの手口を悪用した実攻撃も確認されていますが、上で記載したとおり、有効なデジタル署名がつけられた正規ファイルはインシデント調査やセキュリティ製品のスキャン対象から除外される可能性が高くなるため、マルウェアにとって不正コードや設定データを隠蔽するのに格好の場所であるといえ、こうした仕様がある以上、現実に悪用されることは想像に難くありません。

20210219_21.png

図 21 正規ファイルにC2情報(と想定したデータ)を埋め込んだ様子

なお、この仕様をつく攻撃アイデアについては2016年の時点でBlackHat USAにて広く公表されましたが、すでに2009年時点では少なくとも一部で知られていました。

また、この問題に関してMicrosoftからは2013年にセキュリティアドバイザリ(2915720)が出ており、関連するセキュリティ情報:MS13-098に含められた「Windows Authenticode 署名検証の機能」で対処されてはいますが、その後2014年に既定で有効化しない形に変更されています。
つまり、現状のWindowsにおいてはデフォルトで無効になっており、ユーザーが手動で有効にする必要があります。以下にその機能を有効にする手順を補足情報としてご紹介しましょう。

【※ご注意※】この対処機能がWindowsにおいて既定で有効にしないことになった経緯としては、Microsoftは「既存のソフトウェアへの影響が大きい可能性があると判断した」と説明していることから、以降に掲載する有効化手順は各自の環境における影響を確認した上で判断し実施有無を選択してください。

「Windows Authenticode 署名検証の機能」は、以下のレジストリ場所にEnableCertPaddingCheckという項目を設定しPCを再起動させることで有効になり、それ以降デジタル署名が厳密にチェックされるようになります。

レジストリ場所:HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Wintrust\Config
(及び:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config)
レジストリ値:"EnableCertPaddingCheck"="1"

設定は以下のようにRegファイルを作成すると楽に導入できるでしょう。

20210219_22.png

図 22 EnableCertPaddingCheckというレジストリ項目を作成するRegファイル

上記レジストリを設定してPCを再起動した後、先の検証で作成していた証明書テーブルフィールドのサイズを改ざんしたファイルを見てみると、設定前はデジタル署名タブが表示されていたものが、設定後は表示されなくなったことがわかります。つまり、デジタル署名がより厳密にチェックされることで、こうした偽装に対する対策となっていることがわかります。

20210219_23.png

図 23 EnableCertPaddingCheckにより改変した署名が無効となる様子

※なお、この設定を元に戻すには、レジストリ値を0にするのではなく作成したレジストリ値を削除する必要がある点に注意してください。

Process Herpaderpingをさらに深堀して理解する

Process Herpaderpingの処理の流れやそれによって実現する脅威はこれまでに解説してきましたが、ではそもそもどういう原理でこうした不思議な問題が発生するのでしょうか。
更に深堀してみましょう。

ユーザーモードではオブジェクトの扱いにHandleというものを使用しますが、Handleはユーザーモードの深部となるカーネルモードに配置されたカーネルオブジェクトへの表面上の窓口となっています。つまり、図3の概念図で「イメージセクションオブジェクト」と記載していたものは、より具体的にはカーネル仮想アドレス空間にカーネルオブジェクトとしてマッピングされています(下図)。

20210219_24.png

図 24 イメージセクションオブジェクトについて

そして、Process Herpaderpingを理解する上で1つ目に重要なポイントが、Windowsには実行ファイルの実体がカーネル仮想アドレス空間にキャッシュされる仕組みがあるということです。上記までに解説してきたProcess Herpaderpingの手順に沿って述べれば、NtCreateSectionが呼び出された時点でキャッシュが作成されます(下図)。

20210219_25.png

図 25 実行ファイルの実体はカーネル仮想アドレス空間にキャッシュされる

では具体的にどのような形でキャッシュされるのか、実際に調べてみましょう。
NtCreateSectionが呼ばれた(つまりキャッシュが作成された)後の環境で、キャッシュがどこに存在するのかを確認していきますが、ここからはカーネル空間の作業となるため、WinDbgによる作業が必要となります。

なお、以降の説明は実体ファイル名が「B.exe」である際の例としています。
まずは親プロセスである「Process Herpaderping.exe」が開いている「B.exe」のファイルハンドルをWinDbgで確認します(下図)。下図の通り、[!handle]コマンドにより「B.exe」のファイルハンドルが見つかり、そのハンドルがファイルオブジェクトを指しているという事実と、そのオブジェクトアドレスが見つかりました。

20210219_26.png

図 26 カーネル空間にキャッシュされている様子を確認する

では続いて、そのファイルオブジェクトの内容を掘り下げていきます。
ファイルオブジェクトはFILE_OBJECT構造体として定義されているため、[dt nt!_FILE_OBJECT]コマンドでFILE_OBJECT構造体の型を明示的に指定してファイルオブジェクトの内部を確認してみましょう(下図)。
その結果、FILE_OBJECT構造体のメンバが表示されましたが、その中にある「SectionObjectPointer」というメンバに着目していきます。このメンバは特定のFILE_OBJECTを仮想メモリ制御構造に接続するデータ構造であり、要はファイルの内容がメモリ内にあるときに追跡できる値となります。

20210219_27.png

図 27 ファイルオブジェクトの内容を掘り下げる

該当のSectionObjectPointerはSECTION_OBJECT_POINTERS構造体として定義されているため、SECTION_OBJECT_POINTERS型を明示的に指定して表示させます(下図)。
その結果SectionObjectPointerのメンバが表示されますが、その中にある[SharedCacheMap]というメンバに着目します。このメンバがnullでない場合はキャッシュされていることを意味します。

20210219_28.png

図 28セクションオブジェクトポインタの内容を掘り下げる

SharedCacheMapというメンバはSHARED_CACHE_MAP構造体として定義されているため、同様にSHARED_CACHE_MAP構造体の型を明示的に指定して表示させます(下図)。その結果、複数のメンバが表示されますが、その中の[Vacbs]というメンバに着目します。VacbsはVACBという構造体で定義されたメンバですが、VACBは「View Access Control Block」の略であり、キャッシュへのビューのベースアドレスが記録されています。(この点は次の図30で実際に見ると理解しやすいでしょう。)

20210219_29.png

図 29 SharedCacheMapの内容を掘り下げる

では、Vacbsのメンバアドレス先をVACB構造体の型を[dt nt!_VACB]コマンドにより明示的に指定して表示させます(下図)。その結果、複数の構造体メンバが表示されますが、その中で[BaseAddress]というメンバに着目します。
BaseAddressが指すメモリ内容を[db]コマンドによりダンプして表示させると、以下の通り、お馴染みのMZヘッダが出現します。これがまさに「B.exe」のキャッシュそのものとなります。
つまり、「B.exe」のファイルハンドルを引数に渡しNtCreateSectionを呼び出した時点で、カーネル仮想アドレス空間に指定した実体ファイルのキャッシュが作成されていることがこの結果からわかるわけです。

20210219_30.png

図 30 Vacbsの内容を掘り下げると見えたキャッシュの内容

以上で確認した流れを一つの図にしてみるとよりわかりやすくなります。
次の図の通りカーネルモードでは複数の構造体が連結しており、SharedCacheMapの深部にキャッシュされたEXEのバイナリデータが存在することになります。これまでの解説で使用していた概念図で対応させると、以下図左の赤い「キャッシュ」と記載しているものが実際にはSharedCacheMapに該当するということです。

20210219_31.png

図 31 カーネル配下の構造体関連図とキャッシュの位置

加えて、プロセスが生成される際、SECTION_OBJECT_POINTERS構造体のメンバの一つであるImageSectionObjectが参照されますが、ImageSectionObjectは内部的にループ構造となっており、最終的に同じ構造体メンバであるSharedCacheMapにつながるようになっています。

つまりこの事実から、その後呼び出されるNtCreateProcessExで作成されるプロセスは、プロセスの生成時に実体ではなくメモリ上のキャッシュが利用されているということであり、ImageSectionObjectをマッピングすることで間接的にSharedCacheMapを再利用していると考えられます(下図)。
これがProcess Herpaderpingを理解する上で重要なポイントの1つ目となります。

20210219_32.png

図 32 Process Herpaderpingを理解する上で重要なポイント①

なお補足情報ですが、これは1つ目のEXEのみでなく、それ以降のプロセスにも適用されます。
つまり、起動中のあるプロセスがあった場合、そのプロセスの実体ファイルをダブルクリックし2つ3つと起動させていくと、それらは全て実体ファイルがすでに参照されておらず、全てカーネル仮想空間上のキャッシュが参照されているということです(下図)。この点は実際にWinDbgで同様に調査することで確かめることができ、2つ目3つ目のプロセスは全て同一のImageSectionObjectを参照していることが確認できます。そして、上で解説したとおりImageSectionObjectは内部的に同じ構造体メンバであるSharedCacheMap(=キャッシュ)につながっています。

20210219_33.png

図 33 2つ目以降もキャッシュが利用される概念図

そして、Process Herpaderpingを理解する上でもう一つ重要なのが、プロセスが実行される直前、つまりスレッドとして開始される直前(下図③)に、ファイルの実体を書き換えることができるという点です。下図の③で書き換えた実体ファイルの内容は、プロセスには反映されないため、④におけるプロセスとしての開始には影響を及ぼさす、結果的に書き換え前の実体をもとにしたプロセスが開始されます。
つまり、上で解説したキャッシュが利用されるという1つ目のポイントの前提に加え、プロセスの開始直前にファイルを書き換えることができるという2つ目のポイントが組み合わせられることでProcess Herpaderpingが成立することになります。
(なお補足となりますが、書き込み権限を持つ実体ファイルへのハンドルを持っているプロセスであれば、その実体ファイルをもとにしたプロセスが起動した後であっても、実体ファイルの内容を書き換えることが可能です。)

20210219_34.png

図 34 Process Herpaderpingを理解する上で重要なポイント②

まとめ

以上でProcess Herpaderpingの仕組みと背景を深く解説してきました。
冒頭に掲載した図1で感じて頂いた通り、この脅威には以下の2つのポイントがあります。
まず、プロセスの実体が特定できなくなるという問題です。プロセスの実体がどこに存在するのかわからない状態となるため、調査者や調査ツール、セキュリティ製品で実体を特定できないという状況が生まれます。これがプロセスを"デタラメ"にするというProcess Herpaderpingの本質です。
そして2つ目は、プロセスから得られるデジタル署名が信頼できなくなるという別の問題にあります。プロセスの実体であるファイルのデジタル署名情報を改変しても有効に保たせる手口を併用することで、調査者や調査ツール、セキュリティ製品を翻弄させることができます。
この2つが組み合わせられることでプロセスの状態がさらに曖昧になり、この手口が利用されるともはやプロセスの情報は何も信頼できない状況となってしまいます。
そして、このProcess Herpaderpingを行うために管理者権限は不要である点も最後に触れておきましょう。ここまで解説したProcess Herpaderpingの処理は全てユーザー権限の範囲で実現が可能です。

20210219_35.png

図 35 脅威のまとめ

Process Herpaderpingをあぶり出す方法

ではどのようにして我々はProcess Herpaderpingを見破ればよいのでしょうか。
現在誰もが手に入れられるフリーツールで見つける方法を2つご紹介しましょう。

まずは「Sysmon」です。こちらは一時Web上でメディアにも取り上げられたため、ご存じの方もいらっしゃるかと思いますが、Sysmonのv13ではProcess Herpaderpingを検知可能です。

検出機能を有効にするには「ProcessTampering」オプションを構成ファイルで追加する必要があります。

まず、次の設定情報をtampering.xmlなどの任意のファイル名で保存します。


<sysmon schemaversion="4.50">
  <eventfiltering>
    <rulegroup name="" grouprelation="or">
      <processtampering onmatch="exclude">
      </processtampering>
    </rulegroup>
  </eventfiltering>
</sysmon> 

そして、以下のコマンドで作成した設定ファイルをSysmonに追加します。

20210219_36.png

図 36  Sysmonを利用したProcess Herpaderpingの検知

その結果、次の図のように、イベントID 25でProcess Herpaderpingを検知できるようになります。

20210219_37.png

図 37  SysmonでProcess Herpaderpingが検知された様子

もう一つ、あまり知られていない方法もご紹介しましょう。
Process HackerはVer.2.39が通常のリリースビルドですが、公式サイトで公開されているNightly BuildsのリンクからはVer.3.x系が入手可能です。
Ver.3.x系は様々な機能追加がアグレッシブに行われており、日々更新されていますが、Process Herpaderpingに対する対策も機能追加されています。

以下の図は、Process Hacker のVer.2.39とVer.3.x系を並べて表示させた様子ですが、Ver.2.39ではProcess Herpaderpingが行われたプロセスを見ても通常のプロセスと違いがわかりませんが、Ver3.x系ではプロセスと実体の整合性の割合を認識できるようになっており、整合性が低いプロセスは紫色でハイライトされるようになっています。また、プロセスにカーソルを合わせると、ポップアップ内でプロセスの整合性の割合を%で表示できるように改善されています。
プロセスの実体がどこにあるのかという命題には答えられませんが、Process Herpaderpingで作成された不審なプロセスをあぶり出すという観点においては非常に有用でしょう。

20210219_38.png

図 38 Process Hacker Ver3.x系を使用してProcess Herpaderpingを見分ける

なお、プロセスの実体がどこにあるのかという点については、ここまで解説してきた手順で示した通り、必ずProcess Herpaderpingを構成する全てのファイルのファイルハンドルが取得される必要があるため、プロセスが過去にアクセスしたファイルを追うことで見つけ出すことができます。

Tips

ここからは、本文では触れなかったTipsをいくつかご紹介しましょう。

以上の解説で述べたセクションオブジェクトのカーネルオブジェクトアドレスはProcess Hackerを用いることで参照できます。ただし、Ver.2.39では以下の通りオブジェクトアドレスが表示できますが、Ver.3.x系では空になっておりそのままでは参照できません(下図)。

20210219_39.png

図 39 Process Hackerを用いたカーネルオブジェクトアドレスの参照

Process Hacker Ver.3.x系では、ハンドル列挙のパフォーマンスが優先されたため、オブジェクトアドレスがデフォルトで表示されない仕様となっています(開発者に仕様である点を直接確認済)。
その背景として、Process Hacker Ver.3.x系ではWindows8以降で搭載されたハンドルスナップショットと呼ばれる新機能を活用しパフォーマンス改善を行っています。
そのため、オブジェクトアドレスを表示させるためには、以下の1)2)の順で設定し、ハンドルスナップショット機能を無効にする必要があります(下図)。この設定により、Ver.3.x系でもカーネルオブジェクトアドレスが参照できるようになります。

20210219_40.png

図 40 Process Hacker Ver.3.x系のオブジェクトアドレスに関わる設定

Process Hackerで取得したカーネルオブジェクトアドレスはWinDbgで以下のようにアクセスすることが可能です。

20210219_41.png

図 41 WinDbgとの連携

また、Windowsでは整合性レベルが中以上であれば、次のような処理を用いて、ユーザーモードプロセスから全てのプロセスのハンドルオブジェクトのカーネルアドレス情報にアクセスすることが可能です。

20210219_42.png

図 42 ユーザーモードプロセスからカーネルオブジェクトアドレスを参照できる様子

最後のTipsとして、これまで解説したとおり、通常のProcess Herpaderpingの手順ではNtCreateThreadExの直前でB.exeをC.exeで上書きしますが、上書きせずにB.exeを削除するとどうなるでしょうか。
つまり、下図における③のタイミングでプロセスが起動する直前に実体を削除してみます。

20210219_43.png

図 43 プロセスを書き換える前に削除する概念図

結果は以下となります。まず通常削除では、プロセスの実体パスはゴミ箱(Recycle.Bin)の中に移動した状態でプロセスが開始されることがわかります。

20210219_44.png

図 44 通常削除した場合の結果

次に、完全削除(Shift+Delete)ではどうでしょうか。
下図の通り、完全削除では、プロセスの実体パスがメタファイル「C:¥$Extend¥Deleted¥・・・」を示した状態でプロセスが開始されることがわかります。フォレンジックの世界ではお馴染みのメタファイルはNTFSを編成する特殊なファイルであり、通常はシステム権限プロセスからもアクセスすることは不可能です。
この結果は、深堀していくことでまた興味深い要素に繋がる可能性が言えそうですが、長くなったので本記事はここまでにしておきましょう。

20210219_45.png

図 45 完全削除した場合の結果

動画

最後になりましたが、本ブログで解説した内容の一部をわかりやすく動画にまとめましたので、ぜひご覧ください。本記事で扱った脅威をより直感的に理解していただけると思います。

コンサルティングサービス事業本部
サイバーインテリジェンスグループ
吉川孝志