diff --git a/book.toml b/book.toml index e3330d5e6..f20e2d2a2 100644 --- a/book.toml +++ b/book.toml @@ -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"] diff --git a/hacktricks-preprocessor.py b/hacktricks-preprocessor.py index 37f549101..8e67ab77b 100644 --- a/hacktricks-preprocessor.py +++ b/hacktricks-preprocessor.py @@ -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('(.*?)', 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('(.*?)', 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("/"): diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md b/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md index 790d103dd..ef618abf6 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md @@ -4,26 +4,11 @@ ## GCP -如果您在 GCP 内运行 k8s 集群,您可能希望集群内的某些应用程序能够访问 GCP。有两种常见的方法可以实现这一点: +如果您在 GCP 内运行 k8s 集群,您可能希望集群内的某个应用程序能够访问 GCP。有两种常见的方法可以实现这一点: ### 将 GCP-SA 密钥挂载为秘密 -给予 **kubernetes 应用程序访问 GCP** 的一种常见方法是: - -- 创建一个 GCP 服务账户 -- 绑定所需的权限 -- 下载创建的 SA 的 json 密钥 -- 将其作为秘密挂载到 pod 内 -- 设置指向 json 文件路径的 GOOGLE_APPLICATION_CREDENTIALS 环境变量。 - -> [!WARNING] -> 因此,作为 **攻击者**,如果您攻陷了 pod 内的一个容器,您应该检查该 **env** **变量** 和 **json** **文件**,以获取 GCP 凭据。 - -### 将 GSA json 与 KSA 秘密关联 - -将 GSA 访问权限授予 GKE 集群的一种方法是通过以下方式绑定它们: - -- 在与您的 GKE 集群相同的命名空间中创建一个 Kubernetes 服务账户,使用以下命令: +给予 **kubernetes 应用程序访问 GCP** 的一种 ```bash Copy codekubectl create serviceaccount ``` @@ -40,15 +25,15 @@ Copy codekubectl annotate serviceaccount \ iam.gke.io/gcp-service-account= ``` > [!WARNING] -> 在**第二步**中,将**GSA的凭据设置为KSA的秘密**。然后,如果您可以**从GKE集群内部读取该秘密**,您可以**升级到该GCP服务账户**。 +> 在**第二步**中,将**GSA的凭据设置为KSA的秘密**。然后,如果您可以从**GKE**集群的**内部**读取该秘密,您可以**升级到该GCP服务账户**。 ### GKE Workload Identity 通过Workload Identity,我们可以配置一个[ Kubernetes service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 作为一个[ Google service account](https://cloud.google.com/iam/docs/understanding-service-accounts)。使用Kubernetes服务账户运行的Pods在访问Google Cloud API时将自动作为Google服务账户进行身份验证。 -启用此行为的**第一系列步骤**是**在GCP中启用Workload Identity** ([**步骤**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)) 并创建您希望k8s模拟的GCP SA。 +启用此行为的**第一系列步骤**是**在GCP中启用Workload Identity**([**步骤**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c))并创建您希望k8s模拟的GCP SA。 -- **在新集群上启用Workload Identity** +- 在新集群上**启用Workload Identity** ```bash gcloud container clusters update \ --region=us-central1 \ @@ -92,7 +77,7 @@ kubectl annotate serviceaccount ksa2gcp \ --namespace testing \ iam.gke.io/gcp-service-account=gsa2ksa@security-devbox.iam.gserviceaccount.com ``` -- 使用 **KSA** 运行一个 **pod** 并检查对 **GSA** 的 **访问**: +- 运行一个 **pod** 使用 **KSA** 并检查对 **GSA** 的 **访问**: ```bash # If using Autopilot remove the nodeSelector stuff! echo "apiVersion: v1 @@ -141,7 +126,7 @@ done | grep -B 1 "gcp-service-account" ### Kiam & Kube2IAM (IAM角色用于Pods) -一种(过时的)将IAM角色赋予Pods的方法是使用一个[**Kiam**](https://github.com/uswitch/kiam)或一个[**Kube2IAM**](https://github.com/jtblin/kube2iam) **服务器。** 基本上,您需要在集群中运行一个带有**特权IAM角色**的**守护进程集**。这个守护进程集将为需要的Pods提供IAM角色的访问权限。 +一种(过时的)为Pods提供IAM角色的方法是使用一个[**Kiam**](https://github.com/uswitch/kiam)或一个[**Kube2IAM**](https://github.com/jtblin/kube2iam) **服务器。** 基本上,您需要在集群中运行一个带有**特权IAM角色**的**守护进程集**。这个守护进程集将为需要的Pods提供IAM角色的访问权限。 首先,您需要配置**哪些角色可以在命名空间内访问**,您可以通过在命名空间对象内添加注释来实现: ```yaml:Kiam @@ -171,7 +156,7 @@ annotations: iam.amazonaws.com/role: reportingdb-reader ``` > [!WARNING] -> 作为攻击者,如果您在 pods 或 namespaces 中发现这些注释,或者运行中的 kiam/kube2iam 服务器(可能在 kube-system 中),您可以 **冒充每个已经被 pods 使用的角色**,以及更多(如果您有访问 AWS 账户的权限,可以枚举角色)。 +> 作为攻击者,如果您在 pods 或 namespaces 中发现这些注释,或者运行中的 kiam/kube2iam 服务器(可能在 kube-system 中),您可以 **冒充每个已经被 pods 使用的角色**,以及更多(如果您有访问 AWS 账户的权限,请枚举角色)。 #### 创建带有 IAM 角色的 Pod @@ -199,7 +184,7 @@ args: ["-c", "sleep 100000"]' | kubectl apply -f - 1. 首先,您需要 [为集群创建一个 OIDC 提供者](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)。 2. 然后,您创建一个具有 SA 所需权限的 IAM 角色。 3. 创建一个 [IAM 角色与 SA 之间的信任关系](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html) 名称(或命名空间,允许角色访问命名空间中所有 SA)。 _信任关系主要检查 OIDC 提供者名称、命名空间名称和 SA 名称_。 -4. 最后,**创建一个带有注释指示角色 ARN 的 SA**,运行该 SA 的 pods 将具有 **访问角色的令牌**。**令牌**被 **写入** 文件中,路径在 **`AWS_WEB_IDENTITY_TOKEN_FILE`** 中指定(默认:`/var/run/secrets/eks.amazonaws.com/serviceaccount/token`) +4. 最后,**创建一个带有注释指示角色 ARN 的 SA**,运行该 SA 的 pods 将具有 **访问角色的令牌**。**令牌**被 **写入** 文件中,路径在 **`AWS_WEB_IDENTITY_TOKEN_FILE`** 中指定(默认:`/var/run/secrets/eks.amazonaws.com/serviceaccount/token`)。 ```bash # Create a service account with a role cat >my-service-account.yaml < 此外,如果您在 pod 内,请检查环境变量,如 **AWS_ROLE_ARN** 和 **AWS_WEB_IDENTITY_TOKEN**。 > [!CAUTION] -> 有时,角色的 **信任策略** 可能配置不当,而不是将 AssumeRole 访问权限授予预期的服务帐户,而是授予 **所有服务帐户**。因此,如果您能够在受控服务帐户上写入注释,则可以访问该角色。 +> 有时,角色的 **信任策略** 可能配置不当,而不是将 AssumeRole 访问权限授予预期的服务帐户,而是授予 **所有服务帐户**。因此,如果您能够在受控服务帐户上写入注释,您可以访问该角色。 > > 请查看 **以下页面以获取更多信息**: @@ -255,7 +240,7 @@ done | grep -B 1 "amazonaws.com" ``` ### Node IAM Role -前一节讨论了如何通过 pods 盗取 IAM 角色,但请注意,K8s 集群的 **节点将是云中的一个实例**。这意味着该节点很可能会 **拥有一个你可以盗取的新 IAM 角色**(_请注意,通常 K8s 集群的所有节点将具有相同的 IAM 角色,因此可能不值得尝试检查每个节点_)。 +前一节讨论了如何通过 pods 盗取 IAM 角色,但请注意,K8s 集群的 **节点将是云中的一个实例**。这意味着该节点很可能会 **拥有一个新的 IAM 角色供你盗取**(_请注意,通常 K8s 集群的所有节点将具有相同的 IAM 角色,因此可能不值得尝试检查每个节点_)。 然而,要访问节点的元数据端点,有一个重要的要求,你需要在节点上(ssh 会话?)或至少在同一网络中: ```bash diff --git a/theme/book.js b/theme/book.js index 1c8d77287..b11674b5a 100644 --- a/theme/book.js +++ b/theme/book.js @@ -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 = /(?:(?:\/)+(?[a-z]{2}(?=\/|$)))?(?(?:\/)*.*)?/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; } diff --git a/theme/css/chrome.css b/theme/css/chrome.css index 8cbda7c69..17e541163 100644 --- a/theme/css/chrome.css +++ b/theme/css/chrome.css @@ -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; diff --git a/theme/index.hbs b/theme/index.hbs index 049bc3ea7..419bb6e7a 100644 --- a/theme/index.hbs +++ b/theme/index.hbs @@ -144,34 +144,60 @@