文章总结: 本文详细阐述了SpringBootActuator配置错误的实战利用技巧。核心要点包括利用非标准路径与特殊HTTP头绕过访问限制,通过mappings、metrics及httptrace端点泄露路由信息与会话数据,以及分析heapdump提取敏感凭证。文章强调了组合多种绕过技术的重要性,并给出了禁用非必要端点、设置IP白名单等具体防御建议,指出Actuator仍是高价值攻击目标。 综合评分: 90 文章分类: 渗透测试,WEB安全,实战经验,SRC活动,漏洞分析
Spring Boot Actuator 配置错误利用实战:路径探测、绕过技巧与敏感端点攻击
Damian Strobel Damian Strobel
securitainment
2026年3月1日 22:20 中国香港
| 原文链接 | 作者 | | — | — | | https://www.dsecured.com/en/articles/spring-boot-actuator-using-misconfig-to-your-advantage-paths-bypasses-techniques | Damian Strobel |
本文介绍了 Spring Boot Actuator 端点在配置不当时,如何在渗透测试或漏洞赏金项目中被利用。内容涵盖 /actuator/ 路径之外的发现方法、特殊 HTTP 头 (如 X-Forwarded-For) 的运用、路径遍历与分号绕过技巧,以及 mappings、metrics、httptrace、heapdump 等关键端点的访问方式。文中通过真实案例说明攻击者如何借助这些方法获取敏感信息乃至接管用户会话。同时也表明,只要有针对性地探测,Actuator 至今仍是高价值目标。对管理员和开发者而言,这意味着必须持续加固 Actuator 端点、仅启用必要接口,并建立完善的日志与监控机制。
引言
Spring Boot 是一个广泛使用的 Java 框架,主要用于构建 API 和 Web 应用。它在企业级开发中尤为普及,Salesforce、AT&T、Amazon、Porsche、Daimler、Zoom 以及大量其他公司都在其工具和软件中采用了这一框架。
对于渗透测试人员、红队成员或漏洞赏金猎人而言,Spring Boot 的有趣之处在于它内置了一个名为 Actuator 的模块。简单来说,Actuator 提供了一系列监控与管理端点,可能暴露调试信息。如果你想了解 Actuator 的基础知识,网上已有大量资料可供参考。本文将专注于 Spring Boot Actuator 本身,探讨它在存在的情况下如何在渗透测试或漏洞赏金活动中被利用。
总体来看,在漏洞赏金/渗透测试场景中,Actuator 的出现频率相对较低:如今它们更难被发现,新版本的 Spring Boot 默认安全配置已相当完善,而且很多资产都受到 WAF 的保护 (在此特别”感谢” Akamai 和 Cloudflare 持续让我的工作变得更加困难 ;))。
最近我收到了不少消息,都在问我是怎么还能找到这么多 Actuator。由于这类问题接连不断,加上我一直想写点东西帮助大家,于是决定:整理一篇文章出来。
其他资源与文章
长期以来,已有不少文章从各自角度讨论 Spring Boot 及其子模块,下面列出的每一篇都值得一读。
Actuator 与配置错误的综合介绍:wiz.io
Spring Boot Jolokia 模块的攻击面:blog.wss.sh
网上还有更多值得一读的好文章。其中 WIZ 的文章尤为推荐,因为它解释了若干基础概念,这些内容我在本文中不会重复——我会尝试更深入地探讨。如果你打算阅读本文,请确保你已对 Actuator 有基本了解!
发现 Actuator——路径与变体
大多数人只在 /actuator/路径下寻找 Actuator。以下几点需要特别注意:
- 相关端点 (
env、mappings、heapdump等) 不一定挂载在 “/actuator/” 路径下 - “
/actuator/” 路径不可访问,并不代表 “/actuator/env” 等具体端点也不可访问 - 以上两种情况可能同时存在
关于第 1 点:
系统管理员可能将端点直接暴露在站点根目录下:
GET /env HTTP/2
Actuator 也可能存在于子目录中:
GET /att-admin/env HTTP/2
GET /att-admin/actuator/env HTTP/2
GET /att-admin/info/env HTTP/2
从中可以得出什么结论?Fuzzing 必不可少。但我不建议用 SecLists 进行盲目爆破——等你找到目标时,很可能早已被封禁多次。应该先查看 HTML 源码、检查 JavaScript 文件,并结合域名/子域名进行分析。例如:
假设有这样一个子域名:vadt.management.domain.com——Actuator 就藏在 “vadt” 路径下。某些情况下 “management” 也值得尝试。
除此之外,充分发挥你的创造力。积累几年经验后,你自然会培养出测试哪些路径的敏锐直觉,并记得将每次成功发现的路径加入自己的字典。
关于第 2 点:
很多时候,Actuator 的索引页面因被屏蔽或其他原因无法访问。因此直接探测内部端点往往更加高效。一个实用的策略是先查询 health而不是 env或 heapdump。当然你也可以尝试 env,但如果该端点被屏蔽,你可能会因此完全错过 Actuator 的存在——因为你根本无从察觉它。
关于第 3 点:
当第 1 点和第 2 点两种情况同时出现时,事情就变得棘手了:
Actuator 所在路径并不常规,而 env端点也无法访问。不过,HTTP 404 错误其实暗示了 Actuator 的存在。你可能要等到实际请求 health端点时,才会意识到应当进一步深入调查:
通过特殊 HTTP 头访问 Actuator
如果常规请求无法找到 Actuator,不妨尝试使用特殊 HTTP 头来获取访问权限。以下两个请求头的成功率尤其高:
X-Forwarded-For: 127.0.0.1
X-Original-URL: /actuator/env
下面是一个来自漏洞赏金项目的真实案例:
你看到了什么?仅仅加上 X-Forwarded-For: 127.0.0.1就足以成功访问 Actuator。还有什么值得注意的?Actuator 并不在 “actuator/” 路径下,而是在 “api/” 下。另外,这次我用的既不是 health也不是 env——建议你也尝试 configprops。
另一个请求头 X-Original-URL虽然不太常见,但偶尔也值得一试。其工作原理已有相当完善的文档说明,此处不再赘述。
补充说明:还有其他一些请求头值得测试,具体是哪些就留给你自己去发现了。
访问 mappings 端点
如前所述,由于外部因素 (WAF、服务器规则等) 的影响,发现 Actuator 可能颇为困难。有时你找到了 Actuator 却无法访问 env或 heapdump,网关技巧和其他方法也不奏效。此时应检查 mappings端点是否可访问:
GET /actuator/mappings HTTP/2
如果可以访问,你至少能够从攻击者的角度了解应用的路由结构,进而构造有意义且具有影响力的攻击。mappings端点本质上列出了应用中所有已注册的端点及其参数。一个典型的 HTTP 响应如下所示:
具体来说,你可能发现类似这样的内容:
接下来只需调用暴露的路由即可,例如 adminDashBoard/getUsers。运气好的话,你将获取到——顾名思义——所有用户信息。在上面的示例中,确实如此。
最差的情况是路由需要认证而你无法继续。最好的情况是你收到 404、403、400 或 500 HTTP 状态码——这时就值得对参数进行 Fuzz 测试,例如:
GET /adminDashBoard/getUsers?FUZZ=a HTTP/2
有趣的是,如果没有 mappings的信息,你几乎不可能发现这个路由。这些通常是字典中不存在的词汇。在这个具体案例中,路由还区分大小写。
没有 mappings?用 metrics 作为替代
如果 mappings不可用,可以检查 metrics端点:
GET /actuator/metrics HTTP/2
它会返回可在后续请求中查询的指标名称列表:
{"names":["application.ready.time","application.started.time","disk.free","disk.total","executor.active","executor.completed","executor.pool.core","executor.pool.max","executor.pool.size","executor.queue.remaining","executor.queued","http.client.requests","http.client.requests.active","http.server.requests","http.server.requests.active","jvm.buffer.count","jvm.buffer.memory.used","jvm.buffer.total.capacity","jvm.classes.loaded","jvm.classes.unloaded","jvm.compilation.time","jvm.gc.live.data.size","jvm.gc.max.data.size","jvm.gc.memory.allocated","jvm.gc.memory.promoted","jvm.gc.overhead","jvm.gc.pause","jvm.info","jvm.memory.committed","jvm.memory.max","jvm.memory.usage.after.gc","jvm.memory.used","jvm.threads.daemon","jvm.threads.live","jvm.threads.peak","jvm.threads.started","jvm.threads.states","logback.events","process.cpu.time","process.cpu.usage","process.files.max","process.files.open","process.start.time","process.uptime","spring.cloud.gateway.requests","spring.cloud.gateway.routes.count","system.cpu.count","system.cpu.usage","system.load.average.1m"]}
其中大部分是普通的元数据。
值得关注的有:
spring.cloud.gateway.requests
http.server.requests
http.client.requests
使用方法如下:
GET /actuator/metrics/{metric-name} HTTP/2
查询后 (精简输出) 可以揭示服务器或客户端最近发送或接收的请求。
spring.cloud.gateway.requests
利用这些值尝试 vhost Fuzz 可能会有收获。这些主机名在 SSRF 场景中也非常有价值。
http.server.requests
这本质上是 mappings的低精度替代——信息量较少但仍然有用。从这里开始测试发现的路由即可。
http.client.requests
WIZ 在前文引用的文章中已有介绍——其含义与其他 metrics 类似。这些指标提供了有用的信息,能间接引导你继续深入。
当一切方法都失败时——路径遍历与绕过
一般来说,简单和双重 URL 编码有时能帮助访问”被屏蔽”的 Actuator 端点。说实话,我从未在实战中见过这种方法奏效。混合编码、UTF-8 超长编码及其他特殊编码也同样如此。我很乐意被证明是错的,也很想看到有人在实战中演示 Actuator + 编码的组合。
对我而言真正有用的是:
路径遍历
我反复使用的两个字符串模式,也是我工具箱的一部分 (不仅限于 Actuator——提示!!):..;和 ..
技术细节暂且不表——Orange Tsai 多年前就描述过这些技术:
https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf
必读!网上还能找到更多相关资源。
在 Actuator 端点的实战中,这通常是什么样的?例如:
GET /..;/actuator/env HTTP/2
GET /static../actuator/env HTTP/2
GET /actuator/health/..;/env HTTP/2
下面是前述技术与路径遍历的一些组合案例:
替代方案:使用 “;” 绕过
简单但往往有效:在关键词后添加分号——需要实际测试。成功的原因通常是不良的重写规则、黑名单或配置错误的规则。
GET /;/actuator/env HTTP/2
GET /actuator;/env HTTP/2
GET /actuator/env; HTTP/2
这种方法确实在漏洞赏金项目中被发现过——而且相当频繁。
实战中我还遇到过以下情况 (与之前列出的某些变体不同,这个确实有效):
GET /actuator/env;.. HTTP/2
路径遍历与这些简单绕过往往可以很好地组合使用——但不进行 Fuzz 测试是走不远的。以下是一个来自知名漏洞赏金项目的示例:
通过 httptrace 端点实现会话接管
httptrace端点在存在时可能非常有价值:
GET /actuator/httptrace HTTP/2
存在用户会话、包含有效值的请求头以及 Cookie 被泄露的风险:
在我的案例中,我成功接管了管理员会话,从而访问了数百万用户的 PII。如果没有管理员会话,你通常也能捕获普通用户的会话,进而访问该用户的数据/PII。为了展示影响力,构建一个小工具会很有帮助——每隔几秒轮询该端点、存储会话/Cookie/请求头,并利用它们提取 PII——前提是这在项目或客户的授权范围内。在此温馨提示:务必仔细阅读项目的政策规定。
其他有用的端点:logfile 与 gateway
Actuator 经常暴露 gateway/routes端点。如果你有写权限,SSRF 是现实可行的;在旧版 Spring Boot 中甚至可能导致 RCE。详情请参见前文引用的 WIZ 文章。
另一个值得关注的端点:logfile
此端点需要由管理员启用,它返回特定事件的日志。我在这方面很少有收获,因为我几乎从未获得过写权限来修改调试级别并强制更频繁的日志写入。通用文档请参阅这里。关于运行时更改日志级别,请参阅这篇文章。
附加内容:CVE-2022-22978
2022 年发布了一个 CVE,允许绕过认证。我已经多年没有发现过它——在此仅作记录提及,因为在更新严重滞后的内部网络中它可能仍然有用。利用该漏洞的请求大致如下,可能允许访问 Actuator:
GET /actuator/%0Aenv HTTP/1.1
下载了 Heapdump——然后呢?
如果你成功下载了 heapdump,情况就变得尤为有趣。通常通过以下方式获取:
GET /actuator/heapdump HTTP/2
这个话题在多篇文章中已有讨论。我的简短建议是:使用 VisualVM 打开并分析 heapdump。大约 90% 的情况下,你会发现密码和 PII 很容易获取。
OQL 可以更快地找到这些内容——下面是我使用的一个简短示例:
select {o: s,val:s.value.toString()} from java.lang.String s
where
/secret|passwd|password|token|api|key|auth|AWS_|kube|redis|kubernetes|k8s|grafana|jira|docker|app_|ssh|credential|confluence|elastic|solr|beats|logstash|slack|Basic |Bearer |django|jdbc|ftp|sftp|odbc|mysql|couchdb|neo4j|leveldb/.test(s.value.toString())
如果你处理过 heapdump,你可能会说:”遗憾的是这经常返回空结果。”确实如此——原因在于 String 内部通常以 byte[]而非 char[]形式存储,这使得简单的字符串搜索无效。OQL 仍然能够提供帮助,例如:
select {
object: s,
value: (function(){
var bytes = s.value;
var coder = s.coder;
var chars = [];
if (coder == 0) {
for (var i = 0; i < bytes.length; i++) chars.push(String.fromCharCode(bytes[i]&0xff));
} else if (coder == 1) {
for (var i = 0; i < bytes.length; i+=2) chars.push(String.fromCharCode((bytes[i]<<8&0xff00)|(bytes[i+1]&0xff)));
} else {
return "";
}
return chars.join('');
})()
}
from java.lang.String s
where (function(){
var bytes = s.value;
var coder = s.coder;
var chars = [];
if (coder == 0) {
for (var i = 0; i < bytes.length; i++) chars.push(String.fromCharCode(bytes[i]&0xff));
} else if (coder == 1) {
for (var i = 0; i < bytes.length; i+=2) chars.push(String.fromCharCode((bytes[i]<<8&0xff00)|(bytes[i+1]&0xff)));
} else {
return false;
}
return /SUPERSECRET/.test(chars.join(''));
})()
修复建议
了解攻击者能做什么固然有用,但如果不附带具体的缓解措施,这些知识对系统管理员来说意义不大。以下是一些建议,帮助你避免与像我这样的人打交道:
- 禁用所有不必要的 Actuator 端点——尽管这可能不太实际,但在生产环境中务必执行,在条件允许的情况下测试/开发环境也应如此。如果无法禁用,请在端点前设置适当的认证 (如 htaccess),并进行充分测试 (或委托他人测试)。
- 使用
management.endpoints.web.exposure.include/exclude仅暴露绝对必要的端点 (例如仅暴露health端点)。 - 严格的 IP 白名单也有帮助。
- 避免在服务器或 WAF 层面使用复杂的正则表达式来阻止端点访问——除非你对自己的操作非常有信心。
结语
我写这篇文章是因为有人告诉我 Actuator 现在很难找到而且越来越少见。我想通过这篇文章表达不同意见:它们仍然存在——只是你需要多花一些功夫。
本文介绍了多种方法,但并非所有可能的技术。你不应该孤立地测试这些方法,而应将它们组合使用,这样才能揭示你要找的东西。最终,创造力才是关键!
话已至此:
GET /;/bye/..;/actuator/heapdump;.. HTTP/2
Host: dsecured.com
X-Forwarded-For: 127.0.0.1
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:securitainment Damian Strobel Damian Strobel《Spring Boot Actuator 配置错误利用实战:路径探测、绕过技巧与敏感端点攻击》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论