mcpField
H
hunt-aspnet

hunt-aspnet

github.com/elementalsoulsセキュリティ5.3k271 回インストール今日更新
リポジトリ

hunt-aspnet について

hunt-aspnetは、ASP.NETアプリケーションや関連サービスを許可のもとでテストするセキュリティスキルです。フレームワークの識別に加え、ViewStateの解析問題、診断エンドポイントの公開、WCF、TelerikやSharePointの攻撃面を確認します。

主な機能

  1. 01ASP.NET技術スタックとバージョンの識別
  2. 02ViewState設定と解析差異の検査
  3. 03trace.axdとelmah.axdの公開確認
  4. 04WCFサービスとメタデータの列挙
  5. 05TelerikとSharePointの攻撃面確認

活用シーン

  1. 01WebFormsページのViewStateリスクを調査
  2. 02匿名のエラーログやトレース情報漏えいを確認
  3. 03レガシーWCFサービスとメタデータを棚卸し

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/elementalsouls/claude-bughunter --skill hunt-aspnet

インストール後、Claude Code で/hunt-aspnetを入力して読み込まれたか確認します。

詳細

最重要のターゲット

ASP.NET のデシリアライズの脆弱性は、RCE に至るとバグバウンティで最も高額な報奨金が支払われます。パッチ適用済みの場合でも、開示対象となる調査結果(署名のみの ViewState、二重パーサーの差異、リクエスト検証の癖)には、安定して Low-Medium の報奨金が支払われます。

最も価値の高いターゲット:

  • SharePoint ファーム(すべてのバージョン — 2013/2016/2019/SE)— 署名のみの ViewState + 制限の緩い ToolPane.aspx + 匿名の FormDigest により、CVE-2025-53770 ToolShell の前提条件となる一連の条件がそろいます
  • ASP.NET AJAX 用 Telerik UI — キーが漏えいした場合、Telerik.Web.UI.WebResource.axd は RCE のシンクとして文書化されています(CVE-2017-11317、CVE-2017-11357、CVE-2019-18935)
  • 従来型の ASP.NET Webforms エンタープライズアプリ — .NET Framework 4.x のまま使われている銀行ポータル、ディーラーポータル、人事システム
  • WCF サービス(*.svc?WSDL)— メインアプリより認証が緩い、忘れられた管理エンドポイントであることがよくあります
  • Sitecore CMS — ViewState と Sitecore 固有のデシリアライズチェーン(CVE-2021-42237)
  • DotNetNuke(DNN) — 過去に存在した ViewState RCE チェーン
  • Umbraco CMS — ViewState とカスタムのデシリアライズシンク

最も報奨金が高いアセットの種類: インターネットからアクセス可能な ASP.NET Webforms アプリ > WCF 管理サービス > Telerik 統合サイト > VSF を使用する従来型 ASP.NET MVC(非常にまれ)


攻撃対象領域の兆候

ASP.NET を示すレスポンスヘッダー:

X-AspNet-Version: 4.0.30319          (classic — disclosure on its own)
X-Powered-By: ASP.NET
X-AspNetMvc-Version: 5.2
Server: Microsoft-IIS/10.0
Set-Cookie: ASP.NET_SessionId=...
Set-Cookie: .ASPXAUTH=...            (Forms auth cookie)
Set-Cookie: .ASPXFORMSAUTH=...
Set-Cookie: ASP.NET_SessionId=...; SameSite=None  (suggests cross-origin embedding)

本文に現れる兆候(フォーム HTML 内):

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="..." />
<input type="hidden" name="__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="" />
                                        ↑ EMPTY = signed-only, not encrypted = exploitable if key leaks
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="..." />
<input type="hidden" name="__REQUESTDIGEST" id="__REQUESTDIGEST" value="0x...,...">
                                        ↑ SharePoint CSRF token; if anon-issued, see hunt-sharepoint

調査する URL パターン:

/trace.axd                            (per-app trace viewer; sometimes anon-accessible)
/elmah.axd                            (ELMAH error log viewer)
/elmah.axd/?id=...                    (ELMAH RCE / stack-trace leak)
/*.svc                                (WCF services)
/*.svc?wsdl                           (WCF WSDL)
/*.svc/mex                            (Metadata Exchange)
/*.asmx                               (legacy SOAP)
/*.asmx?WSDL                          (legacy SOAP description)
/*.asmx?disco                         (legacy discovery)
/Telerik.Web.UI.WebResource.axd       (Telerik AJAX components)
/ChartImg.axd                         (DataVisualization controls; historic deserialization)
/ScriptResource.axd                   (script resource handler; sometimes leaks paths)
/WebResource.axd                      (web resource handler)
/_vti_bin/*                           (SharePoint Web Service Forwarder)
/api/                                 (Web API 2.x is ASP.NET on classic framework)
/signin                               (often FedAuth / WS-Federation)

技術スタックの兆候:

  • Server: Microsoft-IIS/10.0(または /8.5、/7.5)— Windows + IIS であることが確認できます
  • X-AspNet-Version ヘッダー — 従来型の .NET Framework(4.x)です。.NET Core/5+ ではこのヘッダーは出力されません
  • ASP.NET_SessionId、.ASPXAUTH、FedAuth を含む Cookie — Forms 認証またはクレーム認証です
  • フォーム本文内の __VIEWSTATE — Webforms です(MVC、Razor Pages、Blazor ではありません)
  • MicrosoftSharePointTeamServices ヘッダー(ELB によって削除されることがありますが、start.aspx の本文から漏れる場合があります)— SharePoint です

ステップごとの調査手法

  1. フレームワークのバージョンを特定します。 なんらかの 500 エラーを発生させ(古い ViewState の POST が確実な方法です)、エラー本文内にある Version Information: Microsoft .NET Framework Version:X.X.XXXXX; ASP.NET Version:X.X.XXXX.X を探します。このバナーから、ランタイムと ASP.NET のバージョン固有のパッチレベルの両方が判明します。.NET 4.0.30319 + ASP.NET 4.8.x が、現在最も一般的な組み合わせです。

  2. __VIEWSTATE を含むすべてのフォームを特定します。 ターゲットをクロールし、name="__VIEWSTATE" を grep します。MAC / 暗号化を回避できる場合、それぞれがデシリアライズ攻撃の候補となるシンクです。

  3. __VIEWSTATEENCRYPTED の値を確認します。 空(value="")の場合、ViewState は <machineKey> による署名のみで、暗号化されていません。検証キーを復元できれば、任意のデシリアライズが可能になります。空でない(value="something")場合、ViewState は署名と暗号化の両方が施されています。偽造には両方のキーが必要です。

  4. ViewState のパーサーエラーの差異(二重パーサーのアンチパターン)をテストします。 7 種類以上の ViewState 形式を送信し、レスポンスを分類します。

    • 単純なガベージ(AAAA)→ "Validation of viewstate MAC failed"
    • 現在のページから取得した実際のプレフィックス → "Validation of viewstate MAC failed"
    • 実際の ViewState のビットを反転したもの → "Validation of viewstate MAC failed"
    • サイズ超過(A * 100000)→ "Validation of viewstate MAC failed"
    • XML 形式(<xss/>)→ "The state information is invalid for this page and might be corrupted" ← 異なるパーサーパス
    • LosFormatter 形式のプレフィックス(/wEPDwUKMTcxNzgyOTQwMmRkkz9p4lzA...)→ "The state information is invalid for this page and might be corrupted"

    この差異は、2 つの異なるデシリアライズの入口があり、そのうち 1 つは一部のペイロード形式で MAC チェックより前に処理を振り分けることを証明しています。過去には、これによって MAC チェック前にパースを回避するエクスプロイトが可能になりました。

  5. ノード間ロードバランシングによる ViewState MAC エラーを探します。 POST が 500 を返し、"Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey..." が表示される場合、ファーム内に machineKey が同期されていない複数の WFE があるか、スティッキーセッションのアフィニティがありません。運用上、正規ユーザーに支障をきたします。セキュリティ上は、ファームのトポロジーが確認できます。

  6. trace.axd と elmah.axd を調べます。 どちらかが認証なしで 200 を返す場合、重大な指摘事項です(trace はすべてのリクエスト、ヘッダー、フォームデータを漏えいし、ELMAH はスタックトレースを含むすべてのサーバーエラーを漏えいします)。

  7. WCF サービス(.svc)を列挙します。 各サービスについて、?wsdl と ?mex(メタデータ交換)を取得します。MEX エンドポイントが、管理操作を含むサービスコントラクト全体を返すことがあります。

  8. リクエストバリデーターのバイパスをテストします。 ASP.NET のリクエストバリデーターは、デフォルトでクエリ文字列内の < をブロックします。バイパスできる可能性があるパターンは次のとおりです。

    • HTML エンティティでエンコードしたペイロード(&lt;script&gt; — ただし、これらは実行されません)
    • JSON / XML の POST ボディ内にエンコード(Content-Type が異なれば、同じバリデーターが適用されるとは限りません)
    • パスセグメント内(クエリ内ではない)— バリデーターの適用範囲はフレームワークのバージョンによって異なります
    • Cookie / Referer ヘッダー内(動作は異なります)
    • WebDAV PUT 経由でアクセスした場合の <%@ ... %> ASP ディレクティブ内(まれです)
  9. customErrors モードを確認します。 500 エラーで完全なスタックトレース、フレームワークのバージョン、ファイルパス、内部メソッド名が露出する場合は、customErrors mode="Off" が設定されています。本番環境では RemoteOnly にする必要があります。

  10. Telerik コンポーネントを探します。 Telerik.Web.UI.WebResource.axd?type=rau は、過去に悪用されたアップロードから RCE につながるチェーンです(CVE-2017-11317)。dialogParametersHolder パラメータのチェーン(CVE-2019-18935)には暗号化キーが必要ですが、それ以外の条件では RCE につながります。

  11. SharePoint 固有のデシリアライズ経路 — ToolPane.aspx + 匿名 FormDigest + 暗号化されていない ViewState のチェーンについては、hunt-sharepoint スキルを参照してください。

  12. リフレクションによる SafeControl の列挙。 SharePoint の Picker.aspx?PickerDialogType=<TypeName>(および DNN 相当のエンドポイント)は、クラス名を受け取り、「型は存在するが許可リストにない」場合と「型が存在しない」場合で異なるエラーメッセージを返します。Microsoft.SharePoint.*.WebControls.* 型のワードリストを入力して SafeControl の一覧を列挙します。これは CVE-2019-0604 系の調査に役立ちます。


ペイロードと検出パターン

スタックトレースのフィンガープリント(古い ViewState を使った POST でトリガー):

curl -sk -X POST "https://target.example/page.aspx" \
  --data "__VIEWSTATE=AAAA&__VIEWSTATEGENERATOR=AAAA"
# Inspect body for:
#  - "Validation of viewstate MAC failed" → confirms signed ViewState
#  - "The state information is invalid for this page" → confirms ALTERNATE parser path
#  - "Version Information: Microsoft .NET Framework Version:X.X.XXXXX" → exact patch level
#  - "Microsoft.SharePoint.Client.ServerStub..." → SharePoint farm

ViewState パーサーエラーの差分プローブ(Python):

import requests, re, json
S = requests.Session(); S.verify = False
# Get fresh form
r = S.get("https://target.example/path/page.aspx")
real_vs = re.search(r'__VIEWSTATE" id="__VIEWSTATE" value="([^"]+)', r.text).group(1)
real_vsg = re.search(r'__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="([^"]+)', r.text).group(1)

# Test 7 payload shapes
for label, vs in [
    ("trivial",      "AAAA"),
    ("real",         real_vs),
    ("flipped-bit",  real_vs[:50] + "X" + real_vs[51:]),
    ("oversize",     "A" * 100000),
    ("base64",       "VGVzdE1hcmtlcjY3OFhZWg=="),
    ("xml-shaped",   "<xss/>"),
    ("losformatter", "/wEPDwUKMTcxNzgyOTQwMmRkkz9p4lzA" + "A"*50),
]:
    r = S.post("https://target.example/path/page.aspx",
               data={"__VIEWSTATE": vs, "__VIEWSTATEGENERATOR": real_vsg})
    title = re.search(r'<title>([^<]+)</title>', r.text)
    title = title.group(1)[:100] if title else "—"
    print(f"  [{label:14s}] {r.status_code}  {title}")

trace.axd の匿名アクセス確認:

curl -sk -o /dev/null -w "%{http_code}\n" "https://target.example/trace.axd"
# 200 = full trace dump exposed → Critical
# 403 = mod set to localhost-only → check via X-Forwarded-For: 127.0.0.1

WCF サービスの列挙:

# Find all .svc files
curl -sk "https://target.example/" -o body.html
grep -oE '/[a-zA-Z0-9/_-]+\.svc' body.html | sort -u
# For each found:
curl -sk "https://target.example/Service.svc?wsdl" | xmllint --format - | head -60

リクエストバリデーターのバイパスパターン:

# Default: <script>alert(1)</script> in ?q= → "Potentially dangerous Request.QueryString value detected"
# Bypasses that sometimes work:
?q=%3cscript%3e            (URL-encoded — depends on validator config)
?q=<svg/onload=alert(1)>  (depends on validator version)
?q=<%00script>             (NUL-byte; older validators)
?q=javascript:alert(1)     (no < at all — passes validator)
Cookie: foo=<script>       (cookie body not validated by default)
Referer: http://x.com/<script>  (referer not validated in classic ASP.NET)

Telerik のエクスプロイト条件(CVE-2019-18935 — 暗号化キーが必要):

# Fingerprint Telerik
curl -sk "https://target.example/Telerik.Web.UI.WebResource.axd?type=rau" -X POST
# If response is RadAsyncUploadHandler-style → Telerik present; try keys
# Public exploits require leaked machineKey AND telerikEncryptionKey

よくある根本原因

  1. viewStateEncryption="Auto" は、機密性の高い ViewState データがないページでは、デフォルトで署名のみになります。 多くの SharePoint ページはこのように設定されています。__VIEWSTATEENCRYPTED が空の場合、ViewState は署名のみです。validationKey を復元できれば、偽造が可能になります。

  2. Web ファームでの <machineKey> AutoGenerate。 各 WFE は初回起動時に異なるキーを生成します。ある WFE が発行した ViewState は、別の WFE では MAC 検証に失敗します。運用面では 500 エラーが発生し、セキュリティ面ではトポロジーが露呈します(エラーメッセージにクラスター名が表示されます)。

  3. 開発時の <customErrors mode="Off"> をそのまま残している。 メソッド名、ファイルパス、バージョン情報を含むスタックトレースが、匿名のインターネットユーザーに公開されます。

  4. 本番環境で trace.axd / elmah.axd を有効なままにしている。 <system.web><trace enabled="true"> ブロックに残され、忘れられていることがよくあります。

  5. 忘れられた WCF .svc 管理エンドポイント。 内部の管理ツール用に作られ、メインアプリをインターネットに公開した際にも無効化されていません。

  6. デュアルパーサーのアンチパターン:ObjectStateFormatter(レガシー)と LosFormatter(モダン)では、MAC 検証との前後関係が異なる順序でデシリアライズされます。 一部のペイロード形式では、MAC チェックより先にレガシーパーサーが実行されます。

  7. リクエストバリデーターが適用されるのは、URL エンコードされたボディとクエリ文字列のみです。 ヘッダー、Cookie、XML/JSON ボディ、multipart フィールドは、デフォルトでは検証されません。開発者はバリデーターがすべてに適用されると思いがちですが、そうではありません。

  8. <machineKey> をソースリポジトリにコミットしている。 GitHub に設定をコミットすると、validation キーや decryption キーが漏洩することがよくあります。hunt-misc によるソース偵察と組み合わせて、Telerik / SharePoint / DNN のキーを探してください。

  9. SafeControls の web.config エントリを、デシリアライズを制御する仕組みとして信頼している。 SharePoint の <SafeControl> リストは、Picker.aspx がインスタンス化できるクラスを決定します。継承チェックだけが制御手段となっている場合、バイパスが存在します(CVE-2019-0604 系)。


バイパス手法

防御策バイパス
__VIEWSTATEENCRYPTED が空でない(暗号化済み)ソースコードの漏洩/設定情報の漏洩/VS フォージプリミティブなど、いずれかの情報源から decryption キーと validation キーの両方を復元します。キーがなければ、デシリアライズは発生させられません
リクエストバリデーターがクエリ文字列内の < をブロックするペイロードを Cookie / Referer / JSON ボディ / multipart ファイル名に移します。クラシック ASP.NET では、バリデーターはこれらのコンテキストに適用されません
EnableViewStateMac="true" が強制されているweb.config の情報漏洩、または <machineKey> AutoGenerate のフィンガープリンティングで validationKey を復元します(ysoserial.net の --minify --islegacy モードでは、一部の MAC 検証の欠落を通過する ViewState が生成されます)
trace.axd がローカルホストのみに制限されているトレースモードが localOnly で、Request.UserHostAddress を使って検証している場合は、X-Forwarded-For: 127.0.0.1 を設定します(Forwarded-For を使うアプリもあります)
WCF .svc が匿名アクセスに対して 401 を返すまず ?wsdl と ?mex を試します。サービス操作に認証が必要な場合でも、メタデータは匿名で列挙できることがあります
Telerik のアップロード機能にパッチが適用済みTelerik のバージョンを確認します。2017Q1 より前(ビルド 2017.1.118 以前)は、元の RAU RCE です。CVE-2019-18935 については 2017Q3~2019Q3 を確認します
SafeControl の許可リストが適用されている継承チェック(instanceof PickerDialog)が、パッチ適用済み SP での制御手段です。バイパスするには、デシリアライズシンクを持つ SafeControl サブクラスを見つける必要があります。Picker.aspx から列挙してください
customErrors mode="On"(スタックトレースなし)無効な Content-Length や、customErrors ハンドラーより下位でパーサーレベルの例外を発生させる不正な ViewState など、別のエラーパスを強制します

ゲート 0 検証

レポートを作成する前に、以下を確認してください。

  1. 攻撃者は開示された情報を使って、今この瞬間に何を実行できるか?

    • trace.axd が 200 で完全なリクエストダンプを返す → Critical(PII / セッション Cookie / Authorization ヘッダーが露出)
    • elmah.axd が 200 でエラーログを返す → High(スタックトレース + 内部パス + 場合によっては認証情報)
    • __VIEWSTATEENCRYPTED が空 + 別の所見経由で machineKey が復元可能 → RCE への Critical なチェーン
    • __VIEWSTATEENCRYPTED が空で鍵の復元なし → Low-Medium(プリミティブは存在するが、単体では悪用不可)
    • 500 のスタックトレース → 認証情報 / 接続文字列を含まない限り Low
  2. 攻撃者が到達できるインパクトまでチェーン全体を再現したか、それともプリミティブのみか?

    • triage-validation の Pre-Severity Gate を相互参照してください。「プリミティブを確認」は、チェーンがインパクトに行き着くまで Critical ではありません。
  3. トリアージ担当者があなたのレポートから 10 分以内に再現できるか?

    • 各ステップがコピー&ペースト可能な curl / Python であること。
    • RCE チェーンの場合: 公開されているエクスプロイトツール(ysoserial.net、viewgen、telerik-revda)と、具体的なガジェットチェーンをリンクしてください。

実際のインパクトの例

シナリオ A — 署名のみの ViewState + EoL の SharePoint 2013 で寛容な ToolPane

https://target-portal.example/_layouts/15/ToolPane.aspx?DisplayMode=Edit が匿名で 200 を返します。フォームには __VIEWSTATE(署名のみ — __VIEWSTATEENCRYPTED="")が含まれており、__REQUESTDIGEST は _api/contextinfo 経由で匿名発行されます。SP2013 がサポート終了(EoL)であること(パッチが今後出荷されることはない)と組み合わせると、これは恒久的に未パッチのコードパスにおける、CVE-2025-53770「ToolShell」の典型的な前提チェーンです。報告した深刻度: Critical。デュアルパーサーテスト(方法論のセクション 4)により、XML 形式のペイロードが MAC 検証の前にレガシーな ObjectStateFormatter に到達することが確認されました — これは、完全な machineKey の復元がなくてもチェーンに到達可能である追加の証拠です(ただし、完全な RCE には両方が必要です)。

シナリオ B — レガシーな銀行ポータルで露出した Telerik RadAsyncUploadHandler

/Telerik.Web.UI.WebResource.axd?type=rau が Telerik アップロードハンドラーを返します。Telerik のバージョン(JS バンドルのメタデータで確認可能)は 2016.3.1027 です。CVE-2017-11317 が該当します — 鍵はそのバージョンの公開 Telerik DLL に埋め込まれています。アップロード → /app_data/ に aspx を書き込み → リクエスト → RCE。報告した深刻度: Critical。

シナリオ C — 企業の HR ポータルで trace.axd と elmah.axd の両方が露出

trace.axd が 200 で直近 50 件のリクエストを返し、API リクエストの Authorization: Bearer eyJ... ヘッダーが含まれています。elmah.axd が 200 で完全なエラーログを返し、例外の 1 つにデータベース接続文字列が含まれています。報告した深刻度: Critical(認証情報が平文で匿名のインターネットに露出)。


関連するスキルとチェーン

  • hunt-rce — ViewState のデシリアライズは、ASP.NET における代表的な RCE 経路です。署名のみの ViewState と漏えいした machineKey があれば、毎回 RCE につながります。チェーンのプリミティブ:ASP.NET の ViewState におけるデュアルパーサーの MAC バイパスのアンチパターン(署名されているが暗号化されていない状態、<%@ Page enableViewStateMac="true" viewStateEncryptionMode="Never" %>)を検出し、machineKey を復元(web.config の情報漏えい、elmah.axd、ソースコードの漏えい、または GitHub から) → hunt-rce の ysoserial.net TypeConfuseDelegate ガジェット → w3wp.exe ワーカープロセスの実行 ID で任意のコマンドを実行。
  • hunt-sharepoint — SharePoint ファームには、ASP.NET のアンチパターンがすべて引き継がれるほか、独自の攻撃対象領域もあります。チェーンのプリミティブ:ASP.NET のフィンガープリントから SharePoint を特定(X-SharePoint ヘッダーと /_layouts/ へのアクセスが可能) → 一般的な ViewState 攻撃の前に、hunt-sharepoint に切り替えて SharePoint 固有の RCE 経路(ToolShell、SafeControl リフレクション)を調査。
  • hunt-ntlm-info — NTLM/Negotiate を匿名で提示する IIS サイトからは、AD トポロジーが漏えいします。チェーンのプリミティブ:IIS の背後にある ASP.NET アプリで WWW-Authenticate: NTLM を確認 → hunt-ntlm-info で Type-2 チャレンジを取得 → 内部フォレスト名を特定 → m365-entra-attack の検出機能を使って Entra テナントと照合。
  • hunt-file-upload — Telerik RadAsyncUpload、Kentico、Umbraco、DotNetNuke には、過去にアップロードハンドラーを介した RCE がありました。チェーンのプリミティブ:ASP.NET CMS のフィンガープリントを特定 → hunt-file-upload のバイパスマトリックスで CMS のアップロードハンドラーを検証 → Web からアクセス可能なパスに .aspx を書き込み → リクエストを送信 → アプリケーションプールの実行 ID で RCE。
  • triage-validation — trace.axd/elmah.axd の情報漏えいが Critical となるのは、実際に有効な認証情報やトークンが漏えいしている場合に限られます。スタックトレースだけなら、通常は Low です。チェーンのプリミティブ:報告するすべての発見事項を提出前に triage-validation の 7-Question Gate に通し、レポートを作成する前に「詳細なエラー」(情報提供のみ)と「エラーログ内の有効なベアラートークン」(Critical)を区別します(redteam-report-template)。

コメント