From 643bcf02921fa367ac8b8f39febd0d03850520a2 Mon Sep 17 00:00:00 2001 From: mzfr Date: Thu, 4 Sep 2025 00:08:40 +0800 Subject: [PATCH] Adding OSV Scalibr test image for dockersocket detector --- docker/socket_exposure/DockerfileSafe | 36 +++++++ docker/socket_exposure/DockerfileUnsafe | 41 ++++++++ docker/socket_exposure/README.md | 95 +++++++++++++++++++ .../socket_exposure/config/daemon-safe.json | 16 ++++ .../socket_exposure/config/daemon-unsafe.json | 13 +++ .../config/docker-safe.service | 29 ++++++ .../config/docker-unsafe.service | 27 ++++++ docker/socket_exposure/docker-compose.yml | 40 ++++++++ 8 files changed, 297 insertions(+) create mode 100644 docker/socket_exposure/DockerfileSafe create mode 100644 docker/socket_exposure/DockerfileUnsafe create mode 100644 docker/socket_exposure/README.md create mode 100644 docker/socket_exposure/config/daemon-safe.json create mode 100644 docker/socket_exposure/config/daemon-unsafe.json create mode 100644 docker/socket_exposure/config/docker-safe.service create mode 100644 docker/socket_exposure/config/docker-unsafe.service create mode 100644 docker/socket_exposure/docker-compose.yml diff --git a/docker/socket_exposure/DockerfileSafe b/docker/socket_exposure/DockerfileSafe new file mode 100644 index 00000000..5227a74b --- /dev/null +++ b/docker/socket_exposure/DockerfileSafe @@ -0,0 +1,36 @@ +FROM ubuntu:22.04 + +LABEL authors="OSV-Scalibr Team" +LABEL description="Secure Docker socket configuration for testing" + +RUN apt update && apt install -y systemd + +# Create Docker-related directory structure +RUN mkdir -p /var/run \ + /etc/docker \ + /etc/systemd/system \ + /lib/systemd/system \ + /usr/lib/systemd/system + +# Create Docker socket with secure permissions (660 - rw-rw----) +RUN touch /var/run/docker.sock && \ + chmod 660 /var/run/docker.sock && \ + chown root:docker /var/run/docker.sock + +# Copy secure configuration files +COPY config/daemon-safe.json /etc/docker/daemon.json +COPY config/docker-safe.service /etc/systemd/system/docker.service + +# Set proper ownership for Docker config +RUN chown root:root /etc/docker/daemon.json && \ + chmod 644 /etc/docker/daemon.json + +# Set proper ownership for systemd service +RUN chown root:root /etc/systemd/system/docker.service && \ + chmod 644 /etc/systemd/system/docker.service + +# Create docker group (typically GID 999) +RUN groupadd -g 999 docker || true + +# Keep container running for testing +CMD ["sleep", "infinity"] \ No newline at end of file diff --git a/docker/socket_exposure/DockerfileUnsafe b/docker/socket_exposure/DockerfileUnsafe new file mode 100644 index 00000000..ceb437b3 --- /dev/null +++ b/docker/socket_exposure/DockerfileUnsafe @@ -0,0 +1,41 @@ +FROM ubuntu:22.04 + +LABEL authors="OSV-Scalibr Team" +LABEL description="Vulnerable Docker socket configuration for testing" + +RUN apt update && apt install -y systemd + +# Create Docker-related directory structure +RUN mkdir -p /var/run \ + /etc/docker \ + /etc/systemd/system \ + /lib/systemd/system \ + /usr/lib/systemd/system + +# Create Docker socket with INSECURE permissions (666 - world-writable) +RUN touch /var/run/docker.sock && \ + chmod 666 /var/run/docker.sock && \ + chown 1000:1000 /var/run/docker.sock + +# Copy insecure configuration files +COPY config/daemon-unsafe.json /etc/docker/daemon.json +COPY config/docker-unsafe.service /etc/systemd/system/docker.service + +# Also place unsafe service in multiple locations for comprehensive testing +COPY config/docker-unsafe.service /lib/systemd/system/docker.service + +# Set ownership for config files +RUN chown root:root /etc/docker/daemon.json && \ + chmod 644 /etc/docker/daemon.json + +RUN chown root:root /etc/systemd/system/docker.service && \ + chmod 644 /etc/systemd/system/docker.service + +RUN chown root:root /lib/systemd/system/docker.service && \ + chmod 644 /lib/systemd/system/docker.service + +# Create docker group (typically GID 999) +RUN groupadd -g 999 docker || true + +# Keep container running for testing +CMD ["sleep", "infinity"] \ No newline at end of file diff --git a/docker/socket_exposure/README.md b/docker/socket_exposure/README.md new file mode 100644 index 00000000..7db25cae --- /dev/null +++ b/docker/socket_exposure/README.md @@ -0,0 +1,95 @@ +# Docker Socket Exposure Testbed + +This testbed demonstrates Docker socket exposure vulnerabilities that can be detected by the OSV-Scalibr Docker socket detector. + +## Setup + +Run `docker compose up` to start both safe and unsafe Docker socket configurations. + +## Vulnerable Instance (docker_socket_unsafe) + +The unsafe container contains multiple Docker security misconfigurations: + +1. **World-writable Docker socket**: `/var/run/docker.sock` has 666 permissions (world-readable and writable) +2. **Non-root socket ownership**: Socket owned by UID 1000 instead of root +3. **Insecure daemon configuration**: `/etc/docker/daemon.json` exposes TCP endpoints without TLS: + - `tcp://0.0.0.0:2375` (unencrypted, accessible from any IP) + - `tcp://127.0.0.1:2376` (unencrypted, localhost only) +4. **Insecure systemd service**: Docker service configured with `-H tcp://` flags without `--tls` + +### Testing the Vulnerable Container + +```bash +# Access the unsafe container +docker exec -it docker_socket_unsafe /bin/bash + +# Check socket permissions (should show 666 permissions) +ls -la /var/run/docker.sock + +# Check daemon configuration (should show insecure TCP bindings) +cat /etc/docker/daemon.json + +# Check systemd service (should show TCP without TLS) +cat /etc/systemd/system/docker.service +``` + +## Safe Instance (docker_socket_safe) + +The safe container demonstrates proper Docker security configurations: + +1. **Secure socket permissions**: `/var/run/docker.sock` has 660 permissions (group-readable/writable only) +2. **Proper ownership**: Socket owned by root:docker +3. **Secure daemon configuration**: `/etc/docker/daemon.json` uses TLS authentication for remote access +4. **Secure systemd service**: Docker service configured with proper TLS flags + +### Testing the Safe Container + +```bash +# Access the safe container +docker exec -it docker_socket_safe /bin/bash + +# Check socket permissions (should show 660 permissions) +ls -la /var/run/docker.sock + +# Check daemon configuration (should show TLS configuration) +cat /etc/docker/daemon.json + +# Check systemd service (should show TLS flags) +cat /etc/systemd/system/docker.service +``` + +## Running the Detector + +To test the OSV-Scalibr Docker socket detector against these containers: + +```bash +# Test against unsafe container (should detect vulnerabilities) +docker exec docker_socket_unsafe /path/to/scalibr --detectors=dockersocket / + +# Test against safe container (should report no issues) +docker exec docker_socket_safe /path/to/scalibr --detectors=dockersocket / +``` + +## Expected Vulnerabilities Detected + +The detector should identify the following issues in the unsafe container: + +- Docker socket is world-readable (permissions: 666) +- Docker socket is world-writable (permissions: 666) +- Docker socket owner is not root (uid: 1000) +- Insecure TCP binding in daemon.json: "tcp://0.0.0.0:2375" (consider using TLS) +- Insecure TCP binding in daemon.json: "tcp://127.0.0.1:2376" (consider using TLS) +- Insecure TCP binding in systemd service files (missing TLS) + +## Cleanup + +```bash +docker compose down +docker image prune -f +``` + +## Reference + +- [Docker Security Documentation](https://docs.docker.com/engine/security/) +- [Docker Daemon Configuration](https://docs.docker.com/engine/reference/commandline/dockerd/) +- [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker) \ No newline at end of file diff --git a/docker/socket_exposure/config/daemon-safe.json b/docker/socket_exposure/config/daemon-safe.json new file mode 100644 index 00000000..c1dca4dc --- /dev/null +++ b/docker/socket_exposure/config/daemon-safe.json @@ -0,0 +1,16 @@ +{ + "hosts": [ + "unix:///var/run/docker.sock" + ], + "tls": true, + "tlscert": "/etc/docker/certs/server-cert.pem", + "tlskey": "/etc/docker/certs/server-key.pem", + "tlsverify": true, + "tlscacert": "/etc/docker/certs/ca.pem", + "storage-driver": "overlay2", + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "3" + } +} \ No newline at end of file diff --git a/docker/socket_exposure/config/daemon-unsafe.json b/docker/socket_exposure/config/daemon-unsafe.json new file mode 100644 index 00000000..631176d7 --- /dev/null +++ b/docker/socket_exposure/config/daemon-unsafe.json @@ -0,0 +1,13 @@ +{ + "hosts": [ + "unix:///var/run/docker.sock", + "tcp://0.0.0.0:2375", + "tcp://127.0.0.1:2376" + ], + "storage-driver": "overlay2", + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "3" + } +} \ No newline at end of file diff --git a/docker/socket_exposure/config/docker-safe.service b/docker/socket_exposure/config/docker-safe.service new file mode 100644 index 00000000..5d4686c8 --- /dev/null +++ b/docker/socket_exposure/config/docker-safe.service @@ -0,0 +1,29 @@ +[Unit] +Description=Docker Application Container Engine +Documentation=https://docs.docker.com +After=network-online.target firewalld.service containerd.service time-set.target +Wants=network-online.target containerd.service +Requires=docker.socket containerd.service + +[Service] +Type=notify +# the default is not to use systemd for cgroups because the delegate issues still +# exists and systemd currently does not support the cgroup feature set required +# for containers run by docker +ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock --tls --tlscert=/etc/docker/certs/server-cert.pem --tlskey=/etc/docker/certs/server-key.pem --tlsverify --tlscacert=/etc/docker/certs/ca.pem +ExecReload=/bin/kill -s HUP $MAINPID +TimeoutStartSec=0 +RestartSec=2 +Restart=always +StartLimitBurst=3 +StartLimitInterval=60s +LimitNOFILE=infinity +LimitNPROC=infinity +LimitCORE=infinity +TasksMax=infinity +Delegate=yes +KillMode=process +OOMScoreAdjust=-500 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/docker/socket_exposure/config/docker-unsafe.service b/docker/socket_exposure/config/docker-unsafe.service new file mode 100644 index 00000000..7d00087a --- /dev/null +++ b/docker/socket_exposure/config/docker-unsafe.service @@ -0,0 +1,27 @@ +[Unit] +Description=Docker Application Container Engine +Documentation=https://docs.docker.com +After=network-online.target firewalld.service containerd.service time-set.target +Wants=network-online.target containerd.service +Requires=docker.socket containerd.service + +[Service] +Type=notify +# INSECURE: Exposing Docker daemon on TCP without TLS +ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375 -H tcp://127.0.0.1:2376 +ExecReload=/bin/kill -s HUP $MAINPID +TimeoutStartSec=0 +RestartSec=2 +Restart=always +StartLimitBurst=3 +StartLimitInterval=60s +LimitNOFILE=infinity +LimitNPROC=infinity +LimitCORE=infinity +TasksMax=infinity +Delegate=yes +KillMode=process +OOMScoreAdjust=-500 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/docker/socket_exposure/docker-compose.yml b/docker/socket_exposure/docker-compose.yml new file mode 100644 index 00000000..62183667 --- /dev/null +++ b/docker/socket_exposure/docker-compose.yml @@ -0,0 +1,40 @@ +version: '3.8' + +networks: + docker_socket_test: + ipam: + config: + - subnet: 172.30.0.0/24 + +services: + docker_socket_safe: + container_name: docker_socket_safe + build: + context: . + dockerfile: DockerfileSafe + image: docker_socket_safe:latest + networks: + docker_socket_test: + ipv4_address: 172.30.0.10 + healthcheck: + test: ["CMD", "test", "-f", "/var/run/docker.sock"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 5s + + docker_socket_unsafe: + container_name: docker_socket_unsafe + build: + context: . + dockerfile: DockerfileUnsafe + image: docker_socket_unsafe:latest + networks: + docker_socket_test: + ipv4_address: 172.30.0.20 + healthcheck: + test: ["CMD", "test", "-f", "/var/run/docker.sock"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 5s \ No newline at end of file