This commit is contained in:
Carlos Polop
2026-07-04 13:36:42 +02:00
parent c4d28b9207
commit 339eaf5aba
5 changed files with 320 additions and 101 deletions
@@ -95,6 +95,19 @@ spec:
If you **don't specify** the **nodePort** in the yaml (it's the port that will be opened) a port in the **range 3000032767 will be used**. If you **don't specify** the **nodePort** in the yaml (it's the port that will be opened) a port in the **range 3000032767 will be used**.
When reviewing NodePort or LoadBalancer Services, also inspect traffic-policy fields because they change which nodes and backends are useful from a given source:
```bash
kubectl get services --all-namespaces \
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,ETP:.spec.externalTrafficPolicy,ITP:.spec.internalTrafficPolicy,AFFINITY:.spec.sessionAffinity,DIST:.spec.trafficDistribution,NODEPORTS:.spec.ports[*].nodePort'
```
- `externalTrafficPolicy: Local` preserves the original client source IP for NodePort/LoadBalancer traffic and avoids forwarding to endpoints on other nodes. A node without a local ready endpoint may drop the traffic even if the Service has endpoints elsewhere.
- `externalTrafficPolicy: Cluster` is the default and can forward through any node, but backend logs may see node IPs instead of the real external client IP.
- `internalTrafficPolicy: Local` limits in-cluster Service traffic to endpoints local to the source node. This is locality routing, not an authorization boundary.
- `sessionAffinity: ClientIP` can make repeated tests from one client hit the same backend, hiding other ready endpoints during manual checks.
- `trafficDistribution` and EndpointSlice topology hints can prefer same-zone or same-node endpoints on newer clusters; treat them as routing preferences rather than hard security policy.
### LoadBalancer ### LoadBalancer
Exposes the Service externally **using a cloud provider's load balancer**. On GKE, this will spin up a [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) that will give you a single IP address that will forward all traffic to your service. In AWS it will launch a Load Balancer. Exposes the Service externally **using a cloud provider's load balancer**. On GKE, this will spin up a [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) that will give you a single IP address that will forward all traffic to your service. In AWS it will launch a Load Balancer.
@@ -254,8 +267,10 @@ Check Gateway listeners, allowed route namespaces, Route `parentRefs`, hostnames
- [https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0) - [https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0)
- [https://kubernetes.io/docs/concepts/services-networking/service/](https://kubernetes.io/docs/concepts/services-networking/service/) - [https://kubernetes.io/docs/concepts/services-networking/service/](https://kubernetes.io/docs/concepts/services-networking/service/)
- [https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/](https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/) - [https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/](https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/)
- [https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/](https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/)
- [https://kubernetes.io/docs/tutorials/services/source-ip/](https://kubernetes.io/docs/tutorials/services/source-ip/)
- [https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)
- [https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/) - [https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/)
- [https://gateway-api.sigs.k8s.io/](https://gateway-api.sigs.k8s.io/) - [https://gateway-api.sigs.k8s.io/](https://gateway-api.sigs.k8s.io/)
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}
@@ -39,6 +39,8 @@ Note that as the might be several nodes (running several pods), there might also
When a pod creates data that shouldn't be lost when the pod disappear it should be stored in a physical volume. **Kubernetes allow to attach a volume to a pod to persist the data**. The volume can be in the local machine or in a **remote storage**. If you are running pods in different physical nodes you should use a remote storage so all the pods can access it. When a pod creates data that shouldn't be lost when the pod disappear it should be stored in a physical volume. **Kubernetes allow to attach a volume to a pod to persist the data**. The volume can be in the local machine or in a **remote storage**. If you are running pods in different physical nodes you should use a remote storage so all the pods can access it.
Kubernetes also supports **image volumes** in recent versions. An `image` volume mounts an OCI image or artifact as a **read-only** filesystem source inside the Pod, using fields such as `volumes[].image.reference` and `volumes[].image.pullPolicy`. The kubelet pulls the artifact with the same credential sources used for container images, including node credentials, Pod `imagePullSecrets`, and ServiceAccount `imagePullSecrets`. During a security review, treat image volumes as runtime inputs and supply-chain dependencies: check whether the reference is pinned by digest, which registry credentials can fetch it, where it is mounted, and whether `subPath` limits the visible directory.
**Other configurations:** **Other configurations:**
- **ConfigMap**: You can configure **URLs** to access services. The pod will obtain data from here to know how to communicate with the rest of the services (pods). Note that this is not the recommended place to save credentials! - **ConfigMap**: You can configure **URLs** to access services. The pod will obtain data from here to know how to communicate with the rest of the services (pods). Note that this is not the recommended place to save credentials!
@@ -564,6 +566,12 @@ https://sickrov.github.io/
https://www.youtube.com/watch?v=X48VuDVv0do https://www.youtube.com/watch?v=X48VuDVv0do
{{#endref}} {{#endref}}
{{#ref}}
https://kubernetes.io/docs/concepts/storage/volumes/#image
{{#endref}}
{{#ref}}
https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/
{{#endref}}
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}
@@ -67,6 +67,9 @@ High-risk combinations to prioritize:
- `seccompProfile: Unconfined`, `procMount: Unmasked`, or missing runtime profiles on sensitive workloads. - `seccompProfile: Unconfined`, `procMount: Unmasked`, or missing runtime profiles on sensitive workloads.
- Writable root filesystems or broad writable volume mounts in workloads that process untrusted input. - Writable root filesystems or broad writable volume mounts in workloads that process untrusted input.
- Missing CPU, memory, or ephemeral-storage requests and limits in multi-tenant namespaces. - Missing CPU, memory, or ephemeral-storage requests and limits in multi-tenant namespaces.
- Missing or unrealistic pod-level `spec.resources` budgets, and principals with `patch` or `update` on the Pod `resize` subresource, because supported clusters can change running CPU and memory desired state without recreating the Pod.
Resource controls are not part of `securityContext`, but review them in the same workload pass because they define the availability boundary. Modern Kubernetes can define CPU, memory, and hugepage budgets at Pod level under `spec.resources` in addition to container-level `resources`. A Pod with sidecars may be bounded by an aggregate Pod envelope even when one container has no individual limits, while local ephemeral storage still needs separate `ephemeral-storage` limits, `emptyDir.sizeLimit`, LimitRanges, and ResourceQuotas. Also compare desired resources in the Pod spec with `status.containerStatuses[].resources` after an in-place resize request; a failed or pending resize can leave the requested value in `spec` while the kubelet keeps the previous runtime allocation and reports a `PodResizePending` condition.
For most application workloads, a good baseline is to run as a non-root UID, set `runAsNonRoot: true`, set `allowPrivilegeEscalation: false`, drop all capabilities and add back only the minimum required ones, use `seccompProfile: RuntimeDefault`, prefer a read-only root filesystem, and avoid host namespaces, hostPath mounts, and privileged mode. For most application workloads, a good baseline is to run as a non-root UID, set `runAsNonRoot: true`, set `allowPrivilegeEscalation: false`, drop all capabilities and add back only the minimum required ones, use `seccompProfile: RuntimeDefault`, prefer a read-only root filesystem, and avoid host namespaces, hostPath mounts, and privileged mode.
@@ -77,10 +80,11 @@ At cluster level, use [Pod Security Admission](https://kubernetes.io/docs/concep
- [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core) - [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core)
- [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core) - [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)
- [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) - [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
- [https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)
- [https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/](https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/) - [https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/](https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/)
- [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/) - [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
- [https://kubernetes.io/docs/concepts/security/pod-security-admission/](https://kubernetes.io/docs/concepts/security/pod-security-admission/) - [https://kubernetes.io/docs/concepts/security/pod-security-admission/](https://kubernetes.io/docs/concepts/security/pod-security-admission/)
- [https://kubernetes.io/docs/tasks/configure-pod-container/assign-pod-level-resources/](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pod-level-resources/)
- [https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/](https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/)
{{#include ../../../banners/hacktricks-training.md}} {{#include ../../../banners/hacktricks-training.md}}
+174 -58
View File
@@ -155,18 +155,80 @@ body.sidebar-visible #menu-bar {
margin: 0 15px; margin: 0 15px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
column-gap: 2.6rem; column-gap: 1.25rem;
align-items: center; align-items: center;
} }
.right-buttons a { .right-buttons a {
text-decoration: none; text-decoration: none;
} }
.menu-socials {
position: relative;
display: inline-flex;
align-items: center;
}
.menu-socials-toggle {
display: inline-flex;
align-items: center;
gap: 6px;
border: 0;
padding: 0;
font: inherit;
background: transparent;
cursor: pointer;
}
.menu-socials-caret {
font-size: 14px;
line-height: 1;
opacity: 0.9;
}
.menu-socials-popup {
position: absolute;
right: 0;
top: 30px;
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: 0;
display: none;
flex-direction: column;
min-width: 140px;
overflow: hidden;
}
.menu-socials:hover .menu-socials-popup,
.menu-socials:focus-within .menu-socials-popup {
display: flex;
}
.menu-socials-popup .menu-bar-link {
display: inline-flex;
align-items: center;
gap: 8px;
border: 0;
margin: 0;
padding: 8px 20px;
line-height: 25px;
white-space: nowrap;
text-align: start;
color: inherit;
background: inherit;
font-size: inherit;
}
.menu-socials-popup .menu-bar-link i {
width: 16px;
text-align: center;
}
.menu-socials-popup .menu-bar-link:hover {
background-color: var(--theme-hover);
}
@media only screen and (min-width:800px) { @media only screen and (min-width:800px) {
#menubar-collapse { #menubar-collapse {
display: flex !important; display: flex !important;
flex-wrap: wrap; flex-wrap: wrap;
column-gap: 2.6rem; column-gap: 1.25rem;
align-items: center; align-items: center;
} }
@@ -289,6 +351,22 @@ body.sidebar-visible #menu-bar {
overflow: auto; overflow: auto;
background: transparent; background: transparent;
} }
#menubar-collapse-popup.show-socials #menubar-socials-popup {
display: flex;
}
#menubar-socials-popup {
display: none;
flex-direction: column;
border-top: 1px solid var(--table-border-color);
background: transparent;
}
#menubar-collapse-popup #menubar-socials-popup .menu-bar-link {
padding-left: 34px;
}
#menubar-socials-popup .menu-bar-link i {
width: 16px;
text-align: center;
}
#menubar-collapse-popup .menu-bar-link { #menubar-collapse-popup .menu-bar-link {
border: 0; border: 0;
margin: 0; margin: 0;
@@ -796,7 +874,7 @@ ul#searchresults li a span.teaser em {
} }
} }
@media only screen and (min-width:550px) { @media only screen and (min-width:800px) {
.sidebar-float-toggle { .sidebar-float-toggle {
position: fixed; position: fixed;
top: calc(var(--menu-bar-height) + 90px); top: calc(var(--menu-bar-height) + 90px);
@@ -841,15 +919,7 @@ ul#searchresults li a span.teaser em {
margin-right: auto; margin-right: auto;
} }
#sidebar-toggle-anchor:not(:checked) ~ .page-wrapper .page #container .sidetoc { @media only screen and (max-width:799px) {
position: fixed;
right: max(var(--page-padding), calc((100vw - var(--container-max-width)) / 2));
top: 0;
width: 250px;
margin-top: 25px;
}
@media only screen and (max-width:549px) {
.sidebar-float-toggle { .sidebar-float-toggle {
position: fixed; position: fixed;
top: calc(var(--menu-bar-height) + 10px); top: calc(var(--menu-bar-height) + 10px);
@@ -877,14 +947,14 @@ ul#searchresults li a span.teaser em {
} }
} }
@media only screen and (max-width:549px) { @media only screen and (max-width:799px) {
#sidebar-toggle-anchor:checked ~ .page-wrapper .page #container .sidebar-float-toggle { #sidebar-toggle-anchor:checked ~ .page-wrapper .page #container .sidebar-float-toggle {
left: calc(100vw - 34px); left: calc(100vw - 34px);
} }
} }
/* Sidebar */ /* Sidebar */
@media only screen and (min-width:550px) { @media only screen and (min-width:800px) {
.sidebar { .sidebar {
position: sticky; position: sticky;
top: 4rem; top: 4rem;
@@ -903,7 +973,7 @@ ul#searchresults li a span.teaser em {
display: none !important; display: none !important;
} }
} }
@media only screen and (max-width:549px) { @media only screen and (max-width:799px) {
.sidebar { .sidebar {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
@@ -919,7 +989,7 @@ ul#searchresults li a span.teaser em {
z-index: 105; z-index: 105;
} }
} }
@media only screen and (max-width:549px) { @media only screen and (max-width:799px) {
#sidebar { #sidebar {
display: none; display: none;
} }
@@ -935,11 +1005,26 @@ ul#searchresults li a span.teaser em {
#sidebar-toggle-anchor:checked ~ .page-wrapper .page #container #sidebar { #sidebar-toggle-anchor:checked ~ .page-wrapper .page #container #sidebar {
display: block !important; display: block !important;
} }
#sidebar-toggle-anchor:checked ~ .page-wrapper .page #container #sidebar .sidebar-scrollbox {
bottom: 58px;
}
#sidebar-toggle-anchor:checked ~ .page-wrapper .page #container #sidebar .sidebar-socials {
display: flex;
}
#sidebar-toggle-anchor:checked ~ .page-wrapper .page #container #content { #sidebar-toggle-anchor:checked ~ .page-wrapper .page #container #content {
display: none !important; display: none !important;
} }
#sidebar-toggle-anchor:checked ~ .page-wrapper .page > .footer {
display: none !important;
}
#sidebar-toggle-anchor:not(:checked) ~ .page-wrapper .page #container #content {
display: block !important;
}
#sidebar-toggle-anchor:not(:checked) ~ .page-wrapper .page > .footer {
display: flex !important;
}
} }
@media only screen and (max-width:549px) { @media only screen and (max-width:799px) {
#sidebar { #sidebar {
display: none !important; display: none !important;
} }
@@ -990,6 +1075,11 @@ html:not(.sidebar-resizing) .sidebar {
padding: 10px 10px; padding: 10px 10px;
background-color: transparent; background-color: transparent;
} }
@media only screen and (min-width:800px) {
.sidebar .sidebar-scrollbox {
bottom: 58px;
}
}
.sidebar .sidebar-resize-handle { .sidebar .sidebar-resize-handle {
position: absolute; position: absolute;
cursor: col-resize; cursor: col-resize;
@@ -1187,9 +1277,75 @@ html:not(.sidebar-resizing) .sidebar {
height: var(--footer-height); height: var(--footer-height);
border-top: 1px solid var(--table-border-color); border-top: 1px solid var(--table-border-color);
margin-top: 1rem; margin-top: 1rem;
align-content: center; display: flex;
align-items: center;
justify-content: center;
z-index: 106; z-index: 106;
} }
.footer-socials {
display: flex;
align-items: center;
justify-content: center;
gap: 14px;
}
.footer-socials a,
.footer-socials a:visited {
display: inline-flex;
align-items: center;
justify-content: center;
width: 34px;
height: 34px;
border-radius: 9999px;
color: var(--icons);
text-decoration: none;
border: 1px solid var(--table-border-color);
background: color-mix(in srgb, var(--bg) 88%, transparent);
}
.footer-socials a:hover {
color: var(--icons-hover);
background: var(--theme-hover);
}
.footer-socials i {
font-size: 17px;
}
.sidebar-socials {
display: none;
}
@media only screen and (max-width:799px) {
.sidebar-socials {
position: absolute;
left: 10px;
right: 10px;
bottom: 12px;
padding-top: 10px;
border-top: 1px solid var(--table-border-color);
background: var(--bg);
z-index: 2;
}
}
@media only screen and (min-width:800px) {
.page > .footer {
display: none;
position: fixed;
left: max(0px, calc((100vw - var(--container-max-width)) / 2));
bottom: 0;
width: var(--sidebar-width);
height: auto;
margin: 0;
padding: 10px;
box-sizing: border-box;
border-top: 1px solid var(--table-border-color);
background: var(--bg);
z-index: 107;
}
#sidebar-toggle-anchor:checked ~ .page-wrapper .page > .footer {
display: flex;
}
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper .page > .footer {
left: auto;
right: max(0px, calc((100vw - var(--container-max-width)) / 2));
}
}
.theme-wrapper--menubar { .theme-wrapper--menubar {
position: relative; position: relative;
display: flex; display: flex;
@@ -1230,46 +1386,6 @@ html:not(.sidebar-resizing) .sidebar {
background-color: var(--theme-hover); background-color: var(--theme-hover);
} }
.theme-wrapper--menubar .theme-orb {
position: absolute;
right: 6px;
top: 50%;
width: 8px;
height: 8px;
border-radius: 9999px;
background: radial-gradient(circle at 30% 30%, #ffffff, color-mix(in srgb, var(--links) 70%, transparent));
opacity: 0.7;
transform: translateY(10px);
filter: blur(0.2px);
pointer-events: none;
animation: theme-orb-rise 4.2s ease-in-out infinite;
}
.theme-wrapper--menubar .theme-side-icon {
font-size: 16px;
color: var(--icons);
opacity: 0.9;
line-height: 1;
}
@keyframes theme-orb-rise {
0% {
transform: translateY(10px);
opacity: 0;
}
35% {
opacity: 0.6;
}
70% {
transform: translateY(-22px);
opacity: 0.4;
}
100% {
transform: translateY(-30px);
opacity: 0;
}
}
/* Details/Summary */ /* Details/Summary */
summary { summary {
+114 -38
View File
@@ -100,7 +100,7 @@
var sidebar = null; var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor"); var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
var body = document.querySelector("body"); var body = document.querySelector("body");
if (document.body.clientWidth >= 550) { if (document.body.clientWidth >= 800) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { } try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible'; sidebar = sidebar || 'visible';
} else { } else {
@@ -160,18 +160,24 @@
<a class="menu-bar-link" href="https://tools.hacktricks.wiki/" target="_blank"> <a class="menu-bar-link" href="https://tools.hacktricks.wiki/" target="_blank">
HT Tools HT Tools
</a> </a>
<a class="menu-bar-link" href="https://friends.hacktricks.wiki/" target="_blank">
HT Friends
</a>
<a class="menu-bar-link menu-bar-link-request-update" href="https://tools.hacktricks.wiki/hacktricks-research-request/index.html" target="_blank" rel="noopener noreferrer" data-research-request-link="true"> <a class="menu-bar-link menu-bar-link-request-update" href="https://tools.hacktricks.wiki/hacktricks-research-request/index.html" target="_blank" rel="noopener noreferrer" data-research-request-link="true">
Request Page update Request update
</a>
<a class="menu-bar-link" href="https://github.com/sponsors/carlospolop" target="_blank">
Sponsor
</a>
<a class="menu-bar-link" href="https://www.linkedin.com/company/hacktricks" target="_blank">
Linkedin
</a>
<a class="menu-bar-link" href="https://twitter.com/hacktricks_live" target="_blank">
X
</a> </a>
<div class="menu-socials">
<button type="button" class="menu-bar-link menu-socials-toggle" aria-haspopup="true">
Socials <span class="menu-socials-caret" aria-hidden="true">▾</span>
</button>
<div class="menu-socials-popup" aria-label="Social links" role="menu">
<a href="https://github.com/HackTricks-wiki" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-github" aria-hidden="true"></i><span>GitHub</span></a>
<a href="https://github.com/sponsors/carlospolop" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-heart" aria-hidden="true"></i><span>Sponsor</span></a>
<a href="https://www.linkedin.com/company/hacktricks" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-linkedin" aria-hidden="true"></i><span>Linkedin</span></a>
<a href="https://twitter.com/hacktricks_live" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-twitter" aria-hidden="true"></i><span>X</span></a>
<a href="https://www.youtube.com/@hacktricks_LIVE" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-youtube-play" aria-hidden="true"></i><span>YouTube</span></a>
</div>
</div>
</div> </div>
<div class="icons"> <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"> <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">
@@ -180,10 +186,18 @@
<a href="https://hacktricks-training.com" target="_blank" role="menuitem" class="menu-bar-link">HT Training</a> <a href="https://hacktricks-training.com" target="_blank" role="menuitem" class="menu-bar-link">HT Training</a>
<a href="https://hacktricks.wiki/" target="_blank" role="menuitem" class="menu-bar-link">Book HT</a> <a href="https://hacktricks.wiki/" target="_blank" role="menuitem" class="menu-bar-link">Book HT</a>
<a href="https://tools.hacktricks.wiki/" target="_blank" role="menuitem" class="menu-bar-link">HT Tools</a> <a href="https://tools.hacktricks.wiki/" target="_blank" role="menuitem" class="menu-bar-link">HT Tools</a>
<a href="https://tools.hacktricks.wiki/hacktricks-research-request/index.html" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link menu-bar-link-request-update" data-research-request-link="true">Request Page update</a> <a href="https://friends.hacktricks.wiki/" target="_blank" role="menuitem" class="menu-bar-link">HT Friends</a>
<a href="https://github.com/sponsors/carlospolop" target="_blank" role="menuitem" class="menu-bar-link">Sponsor</a> <a href="https://tools.hacktricks.wiki/hacktricks-research-request/index.html" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link menu-bar-link-request-update" data-research-request-link="true">Request update</a>
<a href="https://www.linkedin.com/company/hacktricks" target="_blank" role="menuitem" class="menu-bar-link">Linkedin</a> <button type="button" role="menuitem" class="menu-bar-link menu-action" data-toggle-socials="true">
<a href="https://twitter.com/hacktricks_live" target="_blank" role="menuitem" class="menu-bar-link">X</a> <span>Socials</span> ▾
</button>
<div id="menubar-socials-popup" class="menubar-socials-popup" aria-label="Social links" role="menu">
<a href="https://github.com/HackTricks-wiki" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-github" aria-hidden="true"></i><span>GitHub</span></a>
<a href="https://github.com/sponsors/carlospolop" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-heart" aria-hidden="true"></i><span>Sponsor</span></a>
<a href="https://www.linkedin.com/company/hacktricks" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-linkedin" aria-hidden="true"></i><span>Linkedin</span></a>
<a href="https://twitter.com/hacktricks_live" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-twitter" aria-hidden="true"></i><span>X</span></a>
<a href="https://www.youtube.com/@hacktricks_LIVE" target="_blank" rel="noopener noreferrer" role="menuitem" class="menu-bar-link"><i class="fa fa-youtube-play" aria-hidden="true"></i><span>YouTube</span></a>
</div>
<button type="button" role="menuitem" class="menu-bar-link menu-action" data-toggle-translations="true"> <button type="button" role="menuitem" class="menu-bar-link menu-action" data-toggle-translations="true">
<span>Translations</span> ▾ <span>Translations</span> ▾
</button> </button>
@@ -210,23 +224,23 @@
<span class="translations-caret" aria-hidden="true">▾</span> <span class="translations-caret" aria-hidden="true">▾</span>
<div id="menubar-languages-popup" class="menubar-languages-popup" aria-label="Language menu" role="language menu"> <div id="menubar-languages-popup" class="menubar-languages-popup" aria-label="Language menu" role="language menu">
<a id="af" href="/af/{{ path }}" hreflang="af" lang="af" role="menuitem" class="menu-bar-link">Afrikaans</a> <a id="af" href="/af/{{ path }}" hreflang="af" lang="af" role="menuitem" class="menu-bar-link">🇿🇦 Afrikaans</a>
<a id="zh" href="/zh/{{ path }}" hreflang="zh" lang="zh" role="menuitem" class="menu-bar-link">Chinese</a> <a id="zh" href="/zh/{{ path }}" hreflang="zh" lang="zh" role="menuitem" class="menu-bar-link">🇨🇳 Chinese</a>
<a id="en" href="/en/{{ path }}" hreflang="en" lang="en" role="menuitem" class="menu-bar-link">English</a> <a id="en" href="/en/{{ path }}" hreflang="en" lang="en" role="menuitem" class="menu-bar-link">🇬🇧 English</a>
<a id="fr" href="/fr/{{ path }}" hreflang="fr" lang="fr" role="menuitem" class="menu-bar-link">French</a> <a id="fr" href="/fr/{{ path }}" hreflang="fr" lang="fr" role="menuitem" class="menu-bar-link">🇫🇷 French</a>
<a id="de" href="/de/{{ path }}" hreflang="de" lang="de" role="menuitem" class="menu-bar-link">German</a> <a id="de" href="/de/{{ path }}" hreflang="de" lang="de" role="menuitem" class="menu-bar-link">🇩🇪 German</a>
<a id="el" href="/el/{{ path }}" hreflang="el" lang="el" role="menuitem" class="menu-bar-link">Greek</a> <a id="el" href="/el/{{ path }}" hreflang="el" lang="el" role="menuitem" class="menu-bar-link">🇬🇷 Greek</a>
<a id="hi" href="/hi/{{ path }}" hreflang="hi" lang="hi" role="menuitem" class="menu-bar-link">Hindi</a> <a id="hi" href="/hi/{{ path }}" hreflang="hi" lang="hi" role="menuitem" class="menu-bar-link">🇮🇳 Hindi</a>
<a id="it" href="/it/{{ path }}" hreflang="it" lang="it" role="menuitem" class="menu-bar-link">Italian</a> <a id="it" href="/it/{{ path }}" hreflang="it" lang="it" role="menuitem" class="menu-bar-link">🇮🇹 Italian</a>
<a id="ja" href="/ja/{{ path }}" hreflang="ja" lang="ja" role="menuitem" class="menu-bar-link">Japanese</a> <a id="ja" href="/ja/{{ path }}" hreflang="ja" lang="ja" role="menuitem" class="menu-bar-link">🇯🇵 Japanese</a>
<a id="ko" href="/ko/{{ path }}" hreflang="ko" lang="ko" role="menuitem" class="menu-bar-link">Korean</a> <a id="ko" href="/ko/{{ path }}" hreflang="ko" lang="ko" role="menuitem" class="menu-bar-link">🇰🇷 Korean</a>
<a id="pl" href="/pl/{{ path }}" hreflang="pl" lang="pl" role="menuitem" class="menu-bar-link">Polish</a> <a id="pl" href="/pl/{{ path }}" hreflang="pl" lang="pl" role="menuitem" class="menu-bar-link">🇵🇱 Polish</a>
<a id="pt" href="/pt/{{ path }}" hreflang="pt" lang="pt" role="menuitem" class="menu-bar-link">Portuguese</a> <a id="pt" href="/pt/{{ path }}" hreflang="pt" lang="pt" role="menuitem" class="menu-bar-link">🇵🇹 Portuguese</a>
<a id="sr" href="/sr/{{ path }}" hreflang="sr" lang="sr" role="menuitem" class="menu-bar-link">Serbian</a> <a id="sr" href="/sr/{{ path }}" hreflang="sr" lang="sr" role="menuitem" class="menu-bar-link">🇷🇸 Serbian</a>
<a id="es" href="/es/{{ path }}" hreflang="es" lang="es" role="menuitem" class="menu-bar-link">Spanish</a> <a id="es" href="/es/{{ path }}" hreflang="es" lang="es" role="menuitem" class="menu-bar-link">🇪🇸 Spanish</a>
<a id="sw" href="/sw/{{ path }}" hreflang="sw" lang="sw" role="menuitem" class="menu-bar-link">Swahili</a> <a id="sw" href="/sw/{{ path }}" hreflang="sw" lang="sw" role="menuitem" class="menu-bar-link">🇹🇿 Swahili</a>
<a id="tr" href="/tr/{{ path }}" hreflang="tr" lang="tr" role="menuitem" class="menu-bar-link">Turkish</a> <a id="tr" href="/tr/{{ path }}" hreflang="tr" lang="tr" role="menuitem" class="menu-bar-link">🇹🇷 Turkish</a>
<a id="uk" href="/uk/{{ path }}" hreflang="uk" lang="uk" role="menuitem" class="menu-bar-link">Ukrainian</a> <a id="uk" href="/uk/{{ path }}" hreflang="uk" lang="uk" role="menuitem" class="menu-bar-link">🇺🇦 Ukrainian</a>
</div> </div>
</div> </div>
@@ -242,7 +256,6 @@
</div> </div>
<div id="theme-wrapper" class="theme-wrapper theme-wrapper--menubar"> <div id="theme-wrapper" class="theme-wrapper theme-wrapper--menubar">
<span class="theme-side-icon" aria-hidden="true">☀</span>
<div id="theme-btns" class="theme-btns"> <div id="theme-btns" class="theme-btns">
<button id="hacktricks-light" type="button" role="radio" aria-label="Switch to light theme" aria-checked="false" class="theme"> <button id="hacktricks-light" type="button" role="radio" aria-label="Switch to light theme" aria-checked="false" class="theme">
<i class="fa fa-sun-o"></i> <i class="fa fa-sun-o"></i>
@@ -254,8 +267,6 @@
<i class="fa fa-moon-o"></i> <i class="fa fa-moon-o"></i>
</button> </button>
</div> </div>
<span class="theme-side-icon" aria-hidden="true">☾</span>
<span class="theme-orb" aria-hidden="true"></span>
</div> </div>
{{#if print_enable}} {{#if print_enable}}
@@ -287,6 +298,23 @@
<noscript> <noscript>
<iframe class="sidebar-iframe-outer" src="{{ path_to_root }}toc.html"></iframe> <iframe class="sidebar-iframe-outer" src="{{ path_to_root }}toc.html"></iframe>
</noscript> </noscript>
<nav class="sidebar-socials footer-socials" aria-label="HackTricks social links">
<a href="https://github.com/HackTricks-wiki" target="_blank" rel="noopener noreferrer" aria-label="HackTricks GitHub">
<i class="fa fa-github" aria-hidden="true"></i>
</a>
<a href="https://github.com/sponsors/carlospolop" target="_blank" rel="noopener noreferrer" aria-label="Sponsor HackTricks">
<i class="fa fa-heart" aria-hidden="true"></i>
</a>
<a href="https://www.linkedin.com/company/hacktricks" target="_blank" rel="noopener noreferrer" aria-label="HackTricks Linkedin">
<i class="fa fa-linkedin" aria-hidden="true"></i>
</a>
<a href="https://twitter.com/hacktricks_live" target="_blank" rel="noopener noreferrer" aria-label="HackTricks X">
<i class="fa fa-twitter" aria-hidden="true"></i>
</a>
<a href="https://www.youtube.com/@hacktricks_LIVE" target="_blank" rel="noopener noreferrer" aria-label="HackTricks YouTube">
<i class="fa fa-youtube-play" aria-hidden="true"></i>
</a>
</nav>
</nav> </nav>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM --> <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script> <script>
@@ -380,6 +408,23 @@
</div> </div>
</div> </div>
<div class="footer"> <div class="footer">
<nav class="footer-socials" aria-label="HackTricks social links">
<a href="https://github.com/HackTricks-wiki" target="_blank" rel="noopener noreferrer" aria-label="HackTricks GitHub">
<i class="fa fa-github" aria-hidden="true"></i>
</a>
<a href="https://github.com/sponsors/carlospolop" target="_blank" rel="noopener noreferrer" aria-label="Sponsor HackTricks">
<i class="fa fa-heart" aria-hidden="true"></i>
</a>
<a href="https://www.linkedin.com/company/hacktricks" target="_blank" rel="noopener noreferrer" aria-label="HackTricks Linkedin">
<i class="fa fa-linkedin" aria-hidden="true"></i>
</a>
<a href="https://twitter.com/hacktricks_live" target="_blank" rel="noopener noreferrer" aria-label="HackTricks X">
<i class="fa fa-twitter" aria-hidden="true"></i>
</a>
<a href="https://www.youtube.com/@hacktricks_LIVE" target="_blank" rel="noopener noreferrer" aria-label="HackTricks YouTube">
<i class="fa fa-youtube-play" aria-hidden="true"></i>
</a>
</nav>
</div> </div>
</div> </div>
@@ -512,6 +557,19 @@
} }
}); });
} }
var socialsBtn = document.querySelector('[data-toggle-socials="true"]');
if (socialsBtn) {
socialsBtn.addEventListener('click', function (e) {
e.preventDefault();
e.stopPropagation();
var popup = document.getElementById('menubar-collapse-popup');
if (!popup) { return; }
popup.classList.toggle('show-socials');
popup.style.display = 'flex';
var collapseToggle = document.getElementById('menubar-collapse-toggle');
if (collapseToggle) { collapseToggle.setAttribute('aria-expanded', true); }
});
}
var popupEl = document.getElementById('menubar-collapse-popup'); var popupEl = document.getElementById('menubar-collapse-popup');
if (popupEl) { if (popupEl) {
popupEl.addEventListener('click', function (e) { popupEl.addEventListener('click', function (e) {
@@ -542,7 +600,7 @@
return Number.isFinite(parsed) ? parsed : 15; return Number.isFinite(parsed) ? parsed : 15;
} }
function updatePositions() { function updateLeftTogglePosition() {
var pagePadding = getPagePadding(); var pagePadding = getPagePadding();
var sidebarVisible = sidebarAnchor ? sidebarAnchor.checked : true; var sidebarVisible = sidebarAnchor ? sidebarAnchor.checked : true;
@@ -552,7 +610,10 @@
var sidebarRect = sidebar.getBoundingClientRect(); var sidebarRect = sidebar.getBoundingClientRect();
leftToggle.style.left = Math.round(sidebarRect.right - 14) + 'px'; leftToggle.style.left = Math.round(sidebarRect.right - 14) + 'px';
} }
}
function updateRightTogglePosition() {
var pagePadding = getPagePadding();
var sidetocHidden = document.documentElement.classList.contains('sidetoc-hidden'); var sidetocHidden = document.documentElement.classList.contains('sidetoc-hidden');
if (!sidetoc || sidetoc.offsetParent === null || sidetocHidden) { if (!sidetoc || sidetoc.offsetParent === null || sidetocHidden) {
rightToggle.style.left = Math.round(window.innerWidth - pagePadding - 28) + 'px'; rightToggle.style.left = Math.round(window.innerWidth - pagePadding - 28) + 'px';
@@ -562,14 +623,29 @@
} }
} }
function updatePositions() {
updateLeftTogglePosition();
updateRightTogglePosition();
}
window.addEventListener('resize', updatePositions); window.addEventListener('resize', updatePositions);
window.addEventListener('load', updatePositions); window.addEventListener('load', updatePositions);
rightToggle.addEventListener('click', function () {
window.setTimeout(updateRightTogglePosition, 0);
});
if (sidebarAnchor) { if (sidebarAnchor) {
sidebarAnchor.addEventListener('change', function () { sidebarAnchor.addEventListener('change', function () {
window.setTimeout(updatePositions, 260); window.setTimeout(updateLeftTogglePosition, 260);
}); });
} }
document.addEventListener('transitionend', updatePositions); document.addEventListener('transitionend', function (event) {
if (event.target === sidetoc || event.target === rightToggle || (sidetoc && sidetoc.contains(event.target))) {
updateRightTogglePosition();
}
if (event.target === sidebar || event.target === leftToggle || (sidebar && sidebar.contains(event.target))) {
updateLeftTogglePosition();
}
});
updatePositions(); updatePositions();
})(); })();
</script> </script>