Pool Partyという攻撃手法を通じてWindowsの深淵を覗いた7日間(インターンシップ体験記)

はじめに

はじめまして、今回ドコモグループの現場受け入れ型インターンシップに参加させていただいた上野です。大学院ではコンテナセキュリティなどについて研究しています。

この記事では、インターンシップ体験記として以下の内容を紹介します。

  • 私のインターンシップの参加経緯や取り組み
    • NTTコミュニケーションズの業務やインターンシップについて知りたい就活生向け
  • Process InjectionとPool Partyの概要
    • Pool Partyについて日本語で概要を知りたいセキュリティエンジニア向け

目次

RedTeam プロジェクト(RedTeam PJ)

私が配属されたポストは、NTTコミュニケーションズ イノベーションセンターのRedTeam PJです。RedTeam PJ は攻撃者の目線からセキュリティについて研究開発をしているチームで、ドコモグループやNTTグループに対するRedTeamの案件支援や攻撃手法の研究開発を行なっています。

RedTeam PJの活動については以下の記事や資料でも紹介しています。

インターンシップ参加の経緯

私はサイバーセキュリティに興味があり、これまでにセキュリティ関連のインターンシップへの参加や、セキュリティに関わる研究を行なってきました。その過程で、攻撃者目線でセキュリティを考えるオフェンシブセキュリティに魅力を感じ、将来はRedTeam関連の職業に就きたいと考えるようになりました。そのような中で、RedTeamの業務体験ができるこのインターンシップを発見し、応募することにしました。

私が今回応募したポストであれば、オフェンシブセキュリティの研究に近い業務も行えそうだなと思ったこともきっかけの1つです。脆弱性診断をするセキュリティ業務のインターンシップなどは多く存在しますが、新しい攻撃手法の開発や攻撃の根本的な原理の調査などを行うものは少ないと感じています。

インターンシップ概要

今回のインターンシップでは、BlackHat Europe2023で発表されたPool Party1という攻撃手法の検証業務を担当しました。最終的にはこの攻撃手法を、NTTコミュニケーションズのRedTeamが内製している独自ツールに組み込むことが検証の目的です。残念ながら今回のインターンシップではツールの組み込みまではできず、PoolPartyの調査結果をRedTeam PJメンバーに共有するところまで体験しました。

インターンシップとしては2024年2月5日〜16日のスケジュールでしたが、オリエンテーションや土日祝日、最終日の成果報告会を除くと、実質的には7日間の日程でした。この7日間は以下の3つのテーマをそれぞれ2〜3日ずつ使いながら順番に業務を進めました。

  • 基礎となる攻撃技術の習熟
    • C22やProcess Injcetion、検証環境や各種ツール(攻撃、開発、解析)に関する座学
    • CreateRemoteThread InjectionによりC2感染させるPoC検体の開発と動的解析
  • Process Injection手法の調査・検証
    • APC3を悪用する2つの攻撃テクニックの理解と比較、およびPoC検体の開発と動的解析
      • APC Queue Code Injection4
      • Early Bird Injection5
  • Pool Partyの調査・検証
    • 発表者のブログ6を読み解きPool Partyの原理を理解
    • (少しだけ)GitHub7で公開されているPool PartyのPoCコードの動作検証とコードリーディング

本記事では、インターンシップで私が調査をしたProcess InjectionとPool Partyの概要について紹介します。

T1055 - Process Injection

Process Injection8とは、任意のコードを別プロセスのアドレス空間で実行する方法です。攻撃者は、セキュリティ製品の検知回避や権限昇格を目的として、悪意のあるプロセスから正規のプロセスに対してProcess Injectionを行うことがあります。

基本的にProcess Injectionは次の4つのステップから成り立ちます。

  • Step 1 : プロセスハンドルの取得
  • Step 2 : メモリの割り当て
  • Step 3 : メモリへの書き込み
  • Step 4 : スレッドの実行

Process Injection(参考文献1から引用)

EDRのようなプロセスの振る舞いを監視するセキュリティ製品は、同一プロセス上で実行される「メモリ割り当て/メモリへの書き込み/スレッド実行」の相関を監視しProcess Injectionを検知します。そのため、上記のステップを単純に実行するだけでは、攻撃が検知されます。これに対してセキュリティ研究者や攻撃者は、検知されずに攻撃可能なさまざまなProcess Injectionのテクニックを開発しています。今回のインターンシップで検証をしたPool PartyやAPC Queue Code Injection, Early Bird Injectionもそれぞれそのテクニックの1つです。

Pool Party

Pool Partyは2023年12月に発表されたProcess Injectionの手法で、WindowsのThread Poolという仕組みを悪用する手法です。Pool Partyは「メモリの割り当て」と「メモリへの書き込み」のみでProcess Injectionを実現します。「スレッドの実行」を攻撃者が行わずに、Windowsの一般的な並列処理の仕組みによってスレッド実行を引き起こすことで検知回避をしています。

Thread Pool

Thread Pool9とは、プロセスを非同期処理や並列処理を効率的に実行するためのWindowsの機構です。Worker Threadというタスクの実行単位の集まり、およびそれらを管理して並列に処理する仕組みをThread Poolと呼びます。発表者によると、デフォルトでWindowsプロセスはThread Poolを持つため、PoolPartyはすべてのプロセスに対して適用可能であるとのことです。

Thread Pool(参考文献1から引用)

また、Thread PoolにはWorker Factoryと呼ばれるWorker Threadを管理するオブジェクトが存在します。Worker Factoryは、Thread PoolのWorker Threadを監視し、監視結果に基づいてWorker Threadを作成・削除します。

Worker Factory(参考文献1から引用)

Pool Party Variants

Pool PartyにはVariantと呼ばれる8つの手法が存在し、これらのVariantsを総称してPool Partyという名前が付けられています。

  1. Work Factory Start Routine Overwrite
  2. TP_WORK Insertion
  3. TP_WAIT Insertion
  4. TP_IO Insertion
  5. TP_ALPC Insertion
  6. TP_JOB Insertion
  7. TP_DIRECT Insertion
  8. TP_TIMER Insertion

Variant 1はThread PoolにおけるWorker Factory、Variant 2~8はThread Poolにおける3つのキュー(Task Queue, Timer Queue, I/O CompletionQueue)およびキューに挿入されるワークアイテムを使用する攻撃です。本記事ではVariant 1に限定して紹介をします。

Variant 1: Worker Factory Start Routine Overwrite

Variant 1はWorker Factoryを悪用する手法です。StartRoutineと呼ばれるWorker Threadのエントリーポイントをシェルコードに書き換えることによって、Worker Threadが作成されるタイミングなどで任意のコードを実行させることができます。

以下に攻撃の流れを記載します。

  1. ターゲットプロセスのプロセスハンドルを取得する
  2. NtQueryInformationProcessを使用して、ターゲットプロセス内のオブジェクトハンドルを取得する
  3. ターゲットプロセス内のオブジェクトハンドルからWorker Factoryのハンドルを探索する
  4. DupilicateHandleを使用して、Worker Factoryのハンドルを複製する
  5. NtQueryInformationWorkerFactoryを使用して、Worker Factoryの情報を取得する
  6. Worker Factoryの情報からStartRoutineのアドレスを取得する
  7. WriteProcessMemoryを使用して、StartRoutineをシェルコードで上書きする

NtSetInformationWorkerFactoryを使用して、任意のタイミングで攻撃をトリガーさせることも可能です。WorkerFactoryThreadMinimum(最小限実行されるべきThreadの数)を「現在動いているThreadの数+1」に変更すると新たなWorker Threadが作成され、StartRoutineの実行、つまりシェルコードが実行されます。

Worker Factory Start Routine Overwrite(参考文献1から引用)

おわりに

私は普段ほとんどUbuntuしか使わず、Windowsの操作もままならない状態からのスタートでした。トレーナーの久保さんに丁寧に検証ツールの使い方などを教えてもらいながら、一歩一歩Process Injection について理解していき、最終的にはチーム内でPool Partyについて発表するというところまで達成できました。知識ゼロの状態からのスタートだったので、インテンシブで大変ではあったのですが、その分成長も感じられた2週間でした。 このようなインターンシップの機会を作っていただいたRedTeam PJの皆さま、ありがとうございました。特にトレーナーの久保さんにはNeWorkやSlack等で親身になってサポートしていただき、とてもお世話になりました。

参考文献

  1. https://www.safebreach.com/blog/process-injection-using-windows-thread-pools/
© NTT Communications Corporation All Rights Reserved.