Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
prometheus-unix-socket-dial — Prometheus v3.15.0 - 高危 - 远程 - SSRF - http_sd __unix_socket__ 未清理的 Dial 遗留 UDS 抓取 | Kitploit
工具/GitHubGitHub/abraxas/prometheus-unix-socket-dial
漏洞分析漏洞利用Web应用程序漏洞利用信息收集渗透测试实验室与实践
GitHubabraxas/prometheus-unix-socket-dial

prometheus-unix-socket-dial

Prometheus v3.15.0 - 高危 - 远程 - SSRF - http_sd __unix_socket__ 未清理的 Dial 遗留 UDS 抓取

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
查看仓库
19天前尚未审核
分享

Abraxas Labs - prometheus-unix-socket-dial

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  prometheus-unix-socket-dial

技术分析文章:https://abraxaslabs.tech/research/prometheus-unix-socket-dial

prometheus-unix-socket-dial

类别: SSRF 可达性: 远程

Prometheus v3.15.0 (5241a27) - CNCF / Prometheus

v3.15.0 新增了 Unix 域套接字抓取功能(#12024 / #18091)。该路径来自目标标签 __unix_socket__,而非运维人员配置的允许列表。http_sd 和 file_sd 会将该标签原样复制。PopulateLabels 从不校验它。随后 newUnixSocketScrapeClient 调用 DialContext(ctx, "unix", socketPath),既没有 filepath.Clean,也没有允许列表,也不拒绝 ../ 或 Linux 抽象 @ 名称。

TCP 抓取无法做到这一点。 CheckTargetAddress 仍会丢弃包含 / 的 __address__ 值,因此将 unix:///var/run/docker.sock 作为地址会被拒绝。新增的标签才是漏洞所在。

默认配置不会设置该标签。对 Prometheus 的未认证 HTTP 请求无法添加作业。此漏洞受 SD 门控。

ID暂无 CVE
类别SSRF(来自 SD 标签的未净化 unix Dial)
可达性远程(受 SD 门控:http_sd / file_sd 的写入者)
CWECWE-918、CWE-22
CVSS高危:8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
产品Prometheus
受影响版本v3.15.0 (5241a27fe3c6983549fccc32f6e65917408c63cd),镜像 prom/prometheus:v3.15.0
认证受 SD 门控:http_sd / file_sd 标签的写入者(或将不可信元数据复制到 __unix_socket__ 的重标记配置)
许可证GNU Affero GPL v3.0
实验环境仅 127.0.0.1

攻击者能做什么

控制 http_sd JSON(或可写的 file_sd)就足够了。SD URL 属于运维配置。遗留问题在于,组 labels 可以设置 __unix_socket__,而 Prometheus 会对其发起 Dial。

权限方法 / 汇聚点实验验证或推断
连接到 Prometheus UID 可打开的宿主机 unix socket从 __unix_socket__ 调用 clientForTarget -> DialContext(ctx, "unix", socketPath)实验验证。来自 http_sd 的路径 /sockets/jail/../oracle.sock;抓取健康状态为 up
在该路径中跟随 ../没有 filepath.Clean / 没有拒绝 ..实验验证。内核将路径遍历解析为 /sockets/oracle.sock
拨号 Linux 抽象 socket对 @name 执行相同的 Dial实验验证。__unix_socket__=@prom-lab-oracle;抓取健康状态为 up
以 Prometheus UID 在该 socket 上发起 HTTP GET抓取为 GET;__metrics_path__ 即请求路径实验验证。GET /fs-traversal 和 /abstract;User-Agent 为 Prometheus/;lab_witness 被摄取
访问 TCP 抓取无法命名的 socketCheckTargetAddress 拒绝 __address__ 中的 /实验验证。将 unix:///var/run/docker.sock 作为 __address__ 时记录 is not a valid hostname;不是活动目标;prometheus_target_sync_failed_total=1
若这些 socket 在范围内,则 GET Docker Engine / kubelet HTTP API__unix_socket__=/var/run/docker.sock 加上 Docker API 路径推断。相同的未净化 Dial。本实验未挂载真实引擎 socket。JSON API 通常无法通过 exposition 解析,因此高危点是连接/GET,而非对 Docker JSON 的 TSDB 数据外泄
修改 Docker(创建容器、写入)抓取动词已排除。抓取仅限 GET
通过未认证的 Prometheus HTTP 添加抓取任务/-/reload、admin API已排除。两个标志默认关闭;reload 没有请求体
在默认示例配置上使用此方法__unix_socket__ 未设置;示例通过 TCP 抓取 localhost:9090已排除。树内 k8s/consul/docker SD 仅发出 __meta_*;这些前缀在 relabel 后被删除

厂商安全模型已允许 SD 选择 TCP 抓取目标。新的原语是 __address__ 无法命名的宿主机 IPC。

我是如何发现的

在 3.15 的 UDS 抓取 FEATURE 行之后,我固定了 prometheus/prometheus v3.15.0。此固定版本上的默认 OSS 关闭了 admin API、lifecycle HTTP、remote-write receiver 和 OTLP receiver。PopulateDiscoveredLabels 会复制每个 http_sd 组标签。__unix_socket__ 不是 __meta_*,因此它在元数据清除后仍然保留。PopulateLabels 仅检查 __address__。

func (sp *scrapePool) clientForTarget(t *Target) *http.Client {
	socketPath := t.labels.Get(UnixSocketLabel)
	if socketPath == "" {
		return sp.client
	}
	client, err := newUnixSocketScrapeClient(socketPath, ...)
func newUnixSocketScrapeClient(socketPath string, ...) (*http.Client, error) {
	optFuncs = append([]config_util.HTTPClientOption{config_util.WithDialContextFunc(
		func(ctx context.Context, _, _ string) (net.Conn, error) {
			return (&net.Dialer{}).DialContext(ctx, "unix", socketPath)
		},
	)}, optFuncs...)

CheckTargetAddress 仍然会拒绝 address 中的 /。URL() 会从 __scheme__ / __address__ / __metrics_path__ 保留 scheme/host/path;socket 仅用于拨号。

已记录的误判:将其评为模型内 NONE,因为 SD 已经选择 TCP 目标(新原语是主机 IPC);将 unix:///var/run/docker.sock 作为 __address__ 视为漏洞(它会被拒绝);声称默认示例配置就是这种遗留问题。表演:反向 shell。判定标准是 SD JSON 所命名 socket 上的抓取健康状态 up。

实验环境

python3 prometheus-unix-socket-dial-Abraxas-Labs.py

或

cd lab
./run.sh

prom/prometheus:v3.15.0 与一个 Python sidecar 共享同一个 netns。该 sidecar 在 127.0.0.1:8080/targets.json 提供 http_sd,并提供两个 unix HTTP oracle:文件系统 /sockets/oracle.sock 和抽象 @prom-lab-oracle。Prometheus 发布在 127.0.0.1:19390。Admin API 和生命周期保持关闭。

SUCCESS prometheus-unix-socket-dial sd=http_sd fs-traversal=yes abstract=yes tcp-slash-rejected=yes how=sd-labels PROMETHEUS-UNIX-SOCKET-DIAL-WITNESS

IOC:scrapeUrl=http://localhost:1/fs-traversal 和 /abstract,两者的健康状态均为 up。TCP slash 从未成为活动目标。

修复方案

在 __unix_socket__ 成为经过清理的绝对文件系统路径之前,不要从 SD 中 Dial 它。拒绝空值、NUL、Linux 抽象 @ 名称、相对路径,以及 filepath.Clean 之后仍存在的任何 ..。来自 scrape YAML 的前缀允许列表更为可靠。除非标签来自操作员配置,否则从 PopulateDiscoveredLabels 中丢弃该标签,也能封堵 SD 注入。

参考资料

  • github.com/prometheus/prometheus 标签 v3.15.0(5241a27fe3c6983549fccc32f6e65917408c63cd)
  • scrape/scrape.go · scrape/target.go · config/config.go
  • UDS 抓取 #18091
  • CWE-918 · CWE-22

许可证

GNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。不提供任何担保。

下载工具