Translated ['src/pentesting-cloud/kubernetes-security/kubernetes-pivotin

This commit is contained in:
Translator
2025-01-02 21:34:34 +00:00
parent ff7e659f3f
commit f3b043d43f
7 changed files with 181 additions and 51 deletions

View File

@@ -22,6 +22,7 @@ after = ["links"]
[preprocessor.hacktricks]
command = "python3 ./hacktricks-preprocessor.py"
env = "prod"
[output.html]
additional-css = ["theme/pagetoc.css", "theme/tabs.css"]

View File

@@ -30,14 +30,16 @@ def ref(matchobj):
href = matchobj.groups(0)[0].strip()
title = href
if href.startswith("http://") or href.startswith("https://"):
# pass
try:
raw_html = str(urlopen(Request(href, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0'})).read())
match = re.search('<title>(.*?)</title>', raw_html)
title = match.group(1) if match else href
except Exception as e:
logger.debug(f'Error opening URL {href}: {e}')
pass #nDont stop on broken link
if context['config']['preprocessor']['hacktricks']['env'] == 'dev':
pass
else:
try:
raw_html = str(urlopen(Request(href, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0'})).read())
match = re.search('<title>(.*?)</title>', raw_html)
title = match.group(1) if match else href
except Exception as e:
logger.debug(f'Error opening URL {href}: {e}')
pass #nDont stop on broken link
else:
try:
if href.endswith("/"):

View File

@@ -4,7 +4,7 @@
## GCP
Wenn Sie einen k8s-Cluster innerhalb von GCP betreiben, möchten Sie wahrscheinlich, dass eine Anwendung, die im Cluster läuft, Zugriff auf GCP hat. Es gibt 2 gängige Möglichkeiten, dies zu tun:
Wenn Sie einen k8s-Cluster innerhalb von GCP betreiben, möchten Sie wahrscheinlich, dass eine Anwendung, die innerhalb des Clusters läuft, Zugriff auf GCP hat. Es gibt 2 gängige Möglichkeiten, dies zu tun:
### GCP-SA-Schlüssel als Geheimnis einbinden
@@ -14,7 +14,7 @@ Eine gängige Methode, um **Zugriff auf eine Kubernetes-Anwendung zu GCP** zu ge
- Binden Sie die gewünschten Berechtigungen daran
- Laden Sie einen JSON-Schlüssel des erstellten SA herunter
- Binden Sie es als Geheimnis innerhalb des Pods ein
- Setzen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS, die auf den Pfad zeigt, wo die JSON-Datei gespeichert ist.
- Setzen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS, die auf den Pfad verweist, an dem sich die JSON-Datei befindet.
> [!WARNING]
> Daher sollten Sie als **Angreifer**, wenn Sie einen Container innerhalb eines Pods kompromittieren, nach dieser **env** **Variable** und **json** **Dateien** mit GCP-Anmeldeinformationen suchen.
@@ -46,9 +46,9 @@ iam.gke.io/gcp-service-account=<gcp-service-account-email>
Mit Workload Identity können wir ein[ Kubernetes-Dienstkonto](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) so konfigurieren, dass es als[ Google-Dienstkonto](https://cloud.google.com/iam/docs/understanding-service-accounts) fungiert. Pods, die mit dem Kubernetes-Dienstkonto ausgeführt werden, authentifizieren sich automatisch als das Google-Dienstkonto, wenn sie auf Google Cloud APIs zugreifen.
Die **erste Reihe von Schritten**, um dieses Verhalten zu aktivieren, besteht darin, **Workload Identity in GCP zu aktivieren** ([**Schritte**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)) und das GCP-SA zu erstellen, das k8s nachahmen soll.
Die **erste Reihe von Schritten**, um dieses Verhalten zu aktivieren, besteht darin, **Workload Identity in GCP zu aktivieren** ([**Schritte**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)) und das GCP SA zu erstellen, das k8s nachahmen soll.
- **Aktivieren Sie Workload Identity** in einem neuen Cluster
- **Aktivieren Sie Workload Identity** auf einem neuen Cluster
```bash
gcloud container clusters update <cluster_name> \
--region=us-central1 \
@@ -59,7 +59,7 @@ gcloud container clusters update <cluster_name> \
# You could update instead of create
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
```
- Erstellen Sie das **GCP-Dienstkonto zur Impersonation** von K8s mit GCP-Berechtigungen:
- Erstellen Sie das **GCP-Dienstkonto zur Nachahmung** von K8s mit GCP-Berechtigungen:
```bash
# Create SA called "gsa2ksa"
gcloud iam service-accounts create gsa2ksa --project=<project-id>
@@ -92,7 +92,7 @@ kubectl annotate serviceaccount ksa2gcp \
--namespace testing \
iam.gke.io/gcp-service-account=gsa2ksa@security-devbox.iam.gserviceaccount.com
```
- Führen Sie ein **pod** mit der **KSA** aus und überprüfen Sie den **Zugriff** auf die **GSA:**
- Führen Sie ein **pod** mit dem **KSA** aus und überprüfen Sie den **Zugriff** auf **GSA:**
```bash
# If using Autopilot remove the nodeSelector stuff!
echo "apiVersion: v1
@@ -124,7 +124,7 @@ gcloud auth activate-service-account --key-file=/var/run/secrets/google/service-
```
> [!WARNING]
> Als Angreifer innerhalb von K8s sollten Sie **nach SAs suchen**, die die **`iam.gke.io/gcp-service-account` Annotation** haben, da dies darauf hinweist, dass der SA auf etwas in GCP zugreifen kann. Eine weitere Möglichkeit wäre, zu versuchen, jede KSA im Cluster auszunutzen und zu überprüfen, ob sie Zugriff hat.\
> Von GCP aus ist es immer interessant, die Bindungen aufzulisten und zu wissen, **welchen Zugriff Sie SAs innerhalb von Kubernetes gewähren**.
> Von GCP aus ist es immer interessant, die Bindungen zu enumerieren und zu wissen, **welchen Zugriff Sie SAs innerhalb von Kubernetes gewähren**.
Dies ist ein Skript, um einfach **über alle Pod**-Definitionen **zu iterieren** und nach dieser **Annotation** zu suchen:
```bash
@@ -221,12 +221,12 @@ Um **aws mit dem Token** von `/var/run/secrets/eks.amazonaws.com/serviceaccount/
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/EKSOIDCTesting --role-session-name something --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token
```
> [!WARNING]
> Als Angreifer, wenn Sie einen K8s-Cluster auflisten können, überprüfen Sie **Servicekonten mit dieser Annotation**, um sich **zu AWS zu eskalieren**. Dazu erstellen Sie einfach einen **Pod** mit einem der IAM **privilegierten Servicekonten** und stehlen das Token.
> Als Angreifer, wenn Sie einen K8s-Cluster auflisten können, überprüfen Sie **Servicekonten mit dieser Annotation**, um sich **zu AWS zu eskalieren**. Dazu müssen Sie einfach **exec/create** einen **Pod** mit einem der IAM **privilegierten Servicekonten** erstellen und das Token stehlen.
>
> Darüber hinaus, wenn Sie sich in einem Pod befinden, überprüfen Sie Umgebungsvariablen wie **AWS_ROLE_ARN** und **AWS_WEB_IDENTITY_TOKEN.**
> [!CAUTION]
> Manchmal könnte die **Trust Policy einer Rolle** **schlecht konfiguriert** sein und anstatt den AssumeRole-Zugriff auf das erwartete Servicekonto zu gewähren, gewährt sie ihn **allen Servicekonten**. Daher, wenn Sie in der Lage sind, eine Annotation auf einem kontrollierten Servicekonto zu schreiben, können Sie auf die Rolle zugreifen.
> Manchmal könnte die **Trust Policy einer Rolle** **schlecht konfiguriert** sein und anstatt AssumeRole-Zugriff auf das erwartete Servicekonto zu gewähren, gewährt sie ihn **allen Servicekonten**. Daher, wenn Sie in der Lage sind, eine Annotation auf einem kontrollierten Servicekonto zu schreiben, können Sie auf die Rolle zugreifen.
>
> Überprüfen Sie die **folgende Seite für weitere Informationen**:
@@ -236,7 +236,7 @@ aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/
### Finden Sie Pods und SAs mit IAM-Rollen im Cluster
Dies ist ein Skript, um einfach **über alle Pods und SAs** Definitionen **zu iterieren**, die nach dieser **Annotation** suchen:
Dies ist ein Skript, um einfach **über alle Pods und SAs**-Definitionen **zu iterieren** und nach dieser **Annotation** zu suchen:
```bash
for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
@@ -255,7 +255,7 @@ done | grep -B 1 "amazonaws.com"
```
### Node IAM Rolle
Der vorherige Abschnitt handelte davon, wie man IAM-Rollen mit Pods stiehlt, aber beachten Sie, dass ein **Node des** K8s-Clusters eine **Instanz in der Cloud** sein wird. Das bedeutet, dass der Node höchstwahrscheinlich **eine neue IAM-Rolle haben wird, die Sie stehlen können** (_beachten Sie, dass normalerweise alle Nodes eines K8s-Clusters die gleiche IAM-Rolle haben, sodass es möglicherweise nicht wert ist, zu versuchen, jeden Node zu überprüfen_).
Der vorherige Abschnitt handelte davon, wie man IAM-Rollen mit Pods stiehlt, aber beachten Sie, dass ein **Node des** K8s-Clusters eine **Instanz in der Cloud** sein wird. Das bedeutet, dass der Node höchstwahrscheinlich **eine neue IAM-Rolle haben wird, die Sie stehlen können** (_beachten Sie, dass normalerweise alle Nodes eines K8s-Clusters die gleiche IAM-Rolle haben, sodass es möglicherweise nicht sinnvoll ist, jeden Node zu überprüfen_).
Es gibt jedoch eine wichtige Voraussetzung, um auf den Metadaten-Endpunkt vom Node zuzugreifen: Sie müssen sich im Node befinden (SSH-Sitzung?) oder zumindest dasselbe Netzwerk haben:
```bash
@@ -265,7 +265,7 @@ kubectl run NodeIAMStealer --restart=Never -ti --rm --image lol --overrides '{"s
Zuvor haben wir besprochen, wie man **IAM-Rollen an Pods anheftet** oder sogar wie man **zum Knoten entkommt, um die IAM-Rolle zu stehlen**, die der Instanz zugeordnet ist.
Sie können das folgende Skript verwenden, um Ihre neu erarbeiteten **IAM-Rollenanmeldeinformationen** zu **stehlen**:
Sie können das folgende Skript verwenden, um Ihre neu erarbeiteten **IAM-Rollen-Anmeldeinformationen** zu **stehlen**:
```bash
IAM_ROLE_NAME=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null || wget http://169.254.169.254/latest/meta-data/iam/security-credentials/ -O - 2>/dev/null)
if [ "$IAM_ROLE_NAME" ]; then

View File

@@ -590,6 +590,62 @@ function playground_text(playground, hidden = true) {
});
})();
(function menubarLanguage() {
var menubarLanguageToggleButton = document.getElementById('menubar-languages-toggle');
var menubarLanguagePopup = document.getElementById('menubar-languages-popup');
var languageButtons = menubarLanguagePopup.querySelectorAll('.menu-bar-link');
function showLanguage() {
menubarLanguagePopup.style.display = 'flex';
menubarLanguageToggleButton.setAttribute('aria-expanded', true);
}
function hideLanguage() {
menubarLanguagePopup.style.display = 'none';
menubarLanguageToggleButton.setAttribute('aria-expanded', false);
menubarLanguageToggleButton.focus();
}
menubarLanguageToggleButton.addEventListener('click', function () {
if (menubarLanguagePopup.style.display === 'flex') {
hideLanguage();
} else {
showLanguage();
}
});
menubarLanguagePopup.addEventListener('focusout', function(e) {
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
if (!!e.relatedTarget && !menubarLanguageToggleButton.contains(e.relatedTarget) && !menubarLanguagePopup.contains(e.relatedTarget)) {
hideLanguage();
}
});
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
document.addEventListener('click', function(e) {
if (menubarLanguagePopup.style.display === 'block' && !menubarLanguageToggleButton.contains(e.target) && !menubarLanguagePopup.contains(e.target)) {
hideLanguage();
}
});
languageButtons.forEach((btn) => {
btn.addEventListener('click', function(e) {
const regex = /(?:(?:\/)+(?<lang>[a-z]{2}(?=\/|$)))?(?<path>(?:\/)*.*)?/g
var match = regex.exec(window.location.pathname)
var path = match.groups.path
console.log(`Path: ${path} ${typeof path}`)
const lang = match.groups.lang
console.log(`Lang: ${lang}`)
window.location = `/${e.target.id}${path}${window.location.hash}`
});
})
})();
(function chapterNavigation() {
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }

View File

@@ -83,6 +83,13 @@ body.sidebar-visible #menu-bar {
}
}
.right-buttons .icons {
display: flex;
flex-direction: row;
flex-wrap: wrap;
column-gap: 0.5rem;
}
.icon-button {
border: none;
background: var(--bg);
@@ -138,11 +145,13 @@ body.sidebar-visible #menu-bar {
}
/* Collapse Menu Popup */
#menubar-collapse-toggle {
position: relative;
}
#menubar-collapse-popup {
position: absolute;
right: 30px;
top: var(--menu-bar-height);
right: 0px;
top: 35px;
z-index: 105;
border-radius: 5px;
font-size: 14px;
@@ -172,6 +181,44 @@ body.sidebar-visible #menu-bar {
background-color: var(--theme-hover);
}
/* Languages Menu Popup */
#menubar-languages-toggle {
position: relative;
}
#menubar-languages-popup {
position: absolute;
right: 0px;
top: 35px;
z-index: 105;
border-radius: 5px;
font-size: 14px;
color: var(--fg);
background: var(--bg);
border: 1px solid var(--table-border-color);
margin: 0;
padding: 0px;
display: none;
flex-direction: column;
max-height: 300px;
width: 150px;
overflow: scroll;
}
#menubar-languages-popup .menu-bar-link {
border: 0;
margin: 0;
padding: 8px 20px;
line-height: 25px;
white-space: nowrap;
text-align: start;
cursor: pointer;
color: inherit;
background: inherit;
font-size: inherit;
}
#menubar-languages-popup .menu-bar-link:hover {
background-color: var(--theme-hover);
}
.left-buttons {
display: flex;

View File

@@ -144,34 +144,60 @@
<div class="right-buttons">
<div id="menubar-collapse">
<a class="menu-bar-link" href="https://training.hacktricks.xyz" target="_blank">
Hacktricks Training
</a>
<a class="menu-bar-link" href="https://twitter.com/hacktricks_live" target="_blank">
Twitter
</a>
<a class="menu-bar-link" href="https://www.linkedin.com/company/hacktricks" target="_blank">
Linkedin
</a>
<a class="menu-bar-link" href="https://github.com/sponsors/carlospolop" target="_blank">
Sponsor
</a>
</div>
<button id="menubar-collapse-toggle" class="icon-button" type="button" title="Toggle menu bar" aria-label="Toggle Menu bar" aria-expanded="false" aria-controls="collapse">
<i class="fa fa-ellipsis-h"></i>
</button>
<div id="menubar-collapse-popup" class="menubar-collapse-popup" aria-label="Menu" role="menu">
<a href="https://training.hacktricks.xyz" target="_blank" role="menuitem" class="menu-bar-link">Hacktricks Training</a>
<a href="https://twitter.com/hacktricks_live" target="_blank" role="menuitem" class="menu-bar-link">Twitter</a>
<a href="https://www.linkedin.com/company/hacktricks" target="_blank" role="menuitem" class="menu-bar-link">Linkedin</a>
<a href="https://github.com/sponsors/carlospolop" target="_blank" role="menuitem" class="menu-bar-link">Sponsor</a>
<a class="menu-bar-link" href="https://training.hacktricks.xyz" target="_blank">
Hacktricks Training
</a>
<a class="menu-bar-link" href="https://twitter.com/hacktricks_live" target="_blank">
Twitter
</a>
<a class="menu-bar-link" href="https://www.linkedin.com/company/hacktricks" target="_blank">
Linkedin
</a>
<a class="menu-bar-link" href="https://github.com/sponsors/carlospolop" target="_blank">
Sponsor
</a>
</div>
<div class="icons">
<div id="menubar-collapse-toggle" class="icon-button" type="button" title="Toggle menu bar" aria-label="Toggle Menu bar" aria-expanded="false" aria-controls="collapse">
<i class="fa fa-ellipsis-h"></i>
<div id="menubar-collapse-popup" class="menubar-collapse-popup" aria-label="Menu" role="menu">
<a href="https://training.hacktricks.xyz" target="_blank" role="menuitem" class="menu-bar-link">Hacktricks Training</a>
<a href="https://twitter.com/hacktricks_live" target="_blank" role="menuitem" class="menu-bar-link">Twitter</a>
<a href="https://www.linkedin.com/company/hacktricks" target="_blank" role="menuitem" class="menu-bar-link">Linkedin</a>
<a href="https://github.com/sponsors/carlospolop" target="_blank" role="menuitem" class="menu-bar-link">Sponsor</a>
</div>
</div>
{{#if search_enabled}}
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
{{/if}}
{{#if search_enabled}}
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
{{/if}}
<div id="menubar-languages-toggle" class="icon-button" type="button" title="Translations" aria-label="Toggle Tanslations" aria-expanded="false" aria-controls="translations">
<i class="fa fa-globe"></i>
<div id="menubar-languages-popup" class="menubar-languages-popup" aria-label="Language menu" role="language menu">
<button id="en" role="menuitem" class="menu-bar-link">English</button>
<button id="es" role="menuitem" class="menu-bar-link">Spanish</button>
<button id="fr" role="menuitem" class="menu-bar-link">French</button>
<button id="de" role="menuitem" class="menu-bar-link">German</button>
<button id="el" role="menuitem" class="menu-bar-link">Greek</button>
<button id="hi" role="menuitem" class="menu-bar-link">Hindi</button>
<button id="it" role="menuitem" class="menu-bar-link">Italian</button>
<button id="ja" role="menuitem" class="menu-bar-link">Japanese</button>
<button id="ko" role="menuitem" class="menu-bar-link">Korean</button>
<button id="pl" role="menuitem" class="menu-bar-link">Polish</button>
<button id="pt" role="menuitem" class="menu-bar-link">Portuguese</button>
<button id="sr" role="menuitem" class="menu-bar-link">Serbian</button>
<button id="sw" role="menuitem" class="menu-bar-link">Swahili</button>
<button id="tr" role="menuitem" class="menu-bar-link">Turkish</button>
<button id="uk" role="menuitem" class="menu-bar-link">Ukrainian</button>
<button id="af" role="menuitem" class="menu-bar-link">Afrikaans</button>
<button id="zh" role="menuitem" class="menu-bar-link">Chinese</button>
</div>
</div>
</div>
{{#if print_enable}}
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">

View File

@@ -19,13 +19,11 @@
try {
const response = await fetch(url, { method: "GET" })
if (!response.ok) {
console.log(response)
throw new Error(`Response status: ${response.status}`)
}
const json = await response.json()
var sponsor = json.sponsor
console.log("boop", sponsor)
sponsorImg.src = sponsor.image_url
sponsorTitle.textContent = sponsor.name
sponsorDescription.innerHTML = sponsor.description