今年多写文章,先把去年的清理一下

1.Prometheus

云原生的开源监控告警解决方案的一款产品

架构图

image-20220926171326026

Prometheus server 服务端,用于抓取和存储时间序列数据
client libraries 客户端库,用于检测应用程序代码
push gateway 在不支持pull 拉取监控数据的场景中,可通过部署Pushgateway的方式,由监控源主动上报到Promtehus
exporters 监控客户端,用于收集各类监控数据,不同的监控需求由不同的exporter处理,如node-exporter、mysql-exporter、blackbox-exporter等。
alertmanager 独立组件,用于处理告警信息
various support tools 其他各种支持工具
PromQL 官方提供的用于数据查询的功能性查询语言

2.历史漏洞

1. CVE-2019-3826

这是一个存储型 XSS 漏洞, 影响版本为: 2.7.1 之前。

这个利用有个前提条件: 需要开启enable query history,也就是记录查询历史需要开启

image-20220927165327558

这个前端就可以开启,而且默认启用。

之后攻击者构造一条特殊的查询语句,test{test="<script>alert(/xss/)</script>"},执行一下,

之后在查询中输入一个可以让这条记录出现的单词才能触发,比如说t

image-20220927180430311

各位看官看到这里,接下来可能会想怎么组合利用了。但是啊,凡是都有个但是,这个XSS漏洞触发原因是**因为开启history后,之后的查询输入会高亮提示 **,问题就出现在这里,存储和渲染时未做任何过滤 web/ui/static/js/graph/index.js

image-20220927180843214

然后再说说为啥会是存储型,因为这个查询历史存储在了浏览器的 Local Storage,这你让我弹谁???因吹斯汀

image-20220927181006925

2. CVE-2021-29622

这是一个重定向漏洞,官方描述

在 2.23.0 中,Prometheus 将其默认 UI 更改为 New ui。为确保无缝转换,URL 以 /new 为前缀重定向到 /。由于代码中的错误,攻击者有可能在 /new 端点中制作一个可以重定向到任何其他 URL 的 URL。如果用户使用特制地址访问 prometheus 服务器,他们可以被重定向到任意 URL。

该问题已在 2.26.1 和 2.27.1 版本中修复。在 2.28.0 中,/new 端点将被完全删除。修补方案是通过 Prometheus 前面的反向代理禁用对 /new 的访问。

git checkout v2.24.0,切换有漏洞的分支,看代码 web/web.go

image-20220927162146823

emmmm,没啥好说的,当 url 为 http://127.0.0.1:19090/new/newhttps://www.baidu.com 这种时,p就等于 /newhttps://www.baidu.com,然后去除/new前缀,使用 path 包组合成 url 进行重定向。

CodeQL 分析

官方 codeql 中关于go的规则中没有重定向测试用例,只有写好的库(lib/semmle/go/security/OpenUrlRedirect.qll这个调用运行跑不出该漏洞,只能跑出后两个),其他语言存在相关的测试用例,模仿python 的重定向测试写一个。

UrlRedirectQuery.qll 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import go

import semmle.go.security.UrlConcatenation

import semmle.go.security.OpenUrlRedirectCustomizations::OpenUrlRedirect
abstract class Sanitizer extends DataFlow::Node { }
abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { }

/**
* A data-flow configuration for reasoning about unvalidated URL redirections.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "UrlRedirect" }

override predicate isSource(DataFlow::Node source) { source instanceof Source }

override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }

override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }

deprecated override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof SanitizerGuard
}
}

UrlRedirect.ql 内容如下

1
2
3
4
5
6
7
8
9
10
import go /* 每个查询都以一个或多个import语句开始。 */
import UrlRedirectQuery /* 引用刚才的库文件/

/* DataFlow 模块 负责实现代码的数据流跟踪功能,即实现整个的调用栈分析。 */
/* 定义变量 */
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink

where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink,"Untrusted URL redirection due to $@.", source.getNode(),
"user-provided value"

结果如下:

image-20221013145923377

第一个就是我们刚才分析的漏洞,另外两个 subpath 虽然可控,但分析过后确认为误报

3.metrics

Metrics是一款监控指标的度量类库,提供了许多工具帮助开发者来完成各项数据的监控。

Prometheus Server 默认会从 /metrics api 中拉取数据,指标数据样本示例:

image-20220926171326026

第一个# 是指标的说明介绍,

第二个# 代表指标的类型,此为必须项且格式固定,TYPE+指标名称+类型

go_gc_duration_seconds 为指标名称,{}里面为标签,它标明了当前指标样本的特征和维度,最后面的数值则是该样本的具体值

4.攻击利用

Prometheus 的各种服务在 2.24.0 版本之前都是允许任何人访问的,官方认为 Prometheus 抓取的各种指标数字不是敏感数据,比如描述 CPU 负载或发送到服务的请求数量等值,对于攻击者来说完全无用,因此Prometheus整体只专注于开发和监控相关的功能。

2.24.0 才出现认证相关的功能,但公网上许多使用了Prometheus的组织还未启用这些功能,还是存在大量的未授权的Prometheus服务。

1.可利用接口

下面列举一些可能存在利用的点

  • /api/v1/status/config

    这里会泄露告警/数据获取服务的地址,访问用户名等。令人不爽的是,Prometheus 会使用 占位符替换掉密码等一些敏感信息。image-20221010163836969

    ps: 这里的 只会替换一些官方定义好的字段,如果配置人员将密码信息等写在了 url 中

    image-20221017112811908

    Prometheus并不会对这些进行处理,虽然概率有点小,但找到就是赚。

    如果监控了 k8s 服务,config 中会显示 k8s 认证的相关信息

    image-20221017111516349

    这里直接告诉我们 k8s认证 token 和证书的位置,如果能打下这台机器,后续横向就很简单了。

  • **/api/v1/targets **

    监控的各种服务,通过这个 api 我们可以获取目标的其他资产机器地址,标签等

    image-20221010165510417

    image-20221010165554239

    ​ 比如这个,直接为我们提供了 178 个服务的信息,为后期的内网横向提供非常不错的帮助,而且还不用扫描,安全隐蔽。如果运气够好,也许还能找到 k8s 的用户名、密码信息、环境变量等。

    ​ 基于 GCE 服务发现时,可能会泄露机器的用户名、ssh公钥,这里可以尝试发送钓鱼邮件,进一步利用。image-20221018154630440

    ​ 基于AWS EC2的服务发现,我们可以很轻松的拿到机器使用的系统镜像、运行实例的地区、aws 账户 id、实例的网络地址等等信息

    image-20221018155931705

  • 管理员接口

访问 /api/v1/status/flags,如果 web.enable-lifecycle 为 true,那么我们就可以关闭 Prometheus服务,web.enable-admin-api开启则可以删除监控的数据。

2.PromQL

Prometheus 提供了一种称为 PromQL(Prometheus Query Language)的功能性查询语言,让用户可以实时选择和聚合时间序列数据。

下面是从网络上收集的一些查询语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 提供有关每个Kubernetes 节点的信息: 云供应商的名称、产品名称
node_dmi_info

# 提供网络相关信息
node_network_info{device=~'eth.+'}

# k8s 每个组件的版本信息,git提交和构建日期
kubernetes_build_info

# k8s 集群的负载均衡器信息
kube_service_info * on (service) group_left group by (service,type) (kube_service_spec_type{type="LoadBalancer"})

# k8s 节点信息
kube_node_info

# k8s 中入口控制器的 URL 路径和相关服务的信息等
kube_ingress_info

# k8s pods 信息
kube_pod_info
# pods 信息与工作负载关联
kube_pod_info * on(namespace,pod) group_left(owner_name) kube_pod_owner
# pods 中的容器信息
kube_pod_container_info

# k8s 集群的命名空间、节点和Secret名称
kube_secret_info
# 获取SecreS中注解相关信息,可能存在一些敏感信息
kube_secret_annotations{kubectl_kubernetes_io_last_applied_configuration != ""}

3.总结

攻防中最重要的一步就是尽可能多地收集与目标有关的信息,虽然 Prometheus 本身没有可以利用的点,但我们却可以从它所监控的服务信息中获取一些可能有用数据。这些数据不仅仅可以作为后渗透横向使用,还可以用来伪造信息进行钓鱼。

5.参考

https://jfrog.com/blog/dont-let-prometheus-steal-your-fire/

https://sysdig.com/blog/exposed-prometheus-exploit-kubernetes-kubeconeu/