Container Escapes 101


AppSec Village


@ DEF CON 34



SSID = AppSec Village Workshops

Password = container-escapes

Hi, I'm Natalie!

I do application security, supply chain threat modeling, and software factory stuff for the public sector ... now with humans and AI.


I work in the public sector.


All opinions and snark my own.


Natalie Somersall

Where we're going


  1. (start some setup)
  2. What's a container?
  3. The security boundaries around our container
  4. What do we mean by escape?
  5. Where this fits in an attack
  6. What do we have to work with here? (enumerate)
  7. Escape time!!!
  8. Some thoughts on AI 🤖
  9. Where to learn more 📚

Setup!


From a vanilla Ubuntu VM (24.04 tested, both x86_64 and aarch64 acceptable)


wget https://raw.githubusercontent.com/some-natalie/some-natalie/refs/heads/main/container-security/ubuntu-setup.sh

wget https://raw.githubusercontent.com/some-natalie/some-natalie/refs/heads/main/container-security/pull-all-images.sh

sudo bash ubuntu-setup.sh

sudo reboot

bash pull-all-images.sh

What's a container, anyways?

Take a trip in the wayback machine


Traditional deployment (apps on an OS on hardware), virtualized deployment (VMs on a hypervisor), container deployment (containers on a container runtime)

But why though?


  • Managing this took time.
  • Reducing "waste" needed skill.
  • Performance tuning wasn't easy either.
  • This costs time and money.
Animation of differently-sized workloads being packed into a fixed CPU-by-memory virtual machine

Constraint


Containers are an abstraction


  • resource management
    • reduce waste
    • scales where needed
  • "reusable bits" such as
    • authentication
    • load balancing
    • metrics and observability
    • log forwarding!
    • ... so much more ...
  • speeds time to production
Workloads of different sizes packed into a single virtual machine's CPU and memory
Patrick Star meme: let's take all our app's complexity and move it somewhere else

I was promised simplicity


  • Run as many copies as needed at the same time, in parallel, with no time needed to scale up/down
  • Remove dependency hell across different processes that share the same host machine
  • Declare dependencies between services without hacky scripts or init systems
  • "Lift and shift" from my makefiles or Jenkinsfiles into a Dockerfile to build and run anywhere I want
  • Get rid of Puppet (or Ansible, Chef, etc...)
  • Separate persistent states (data) from ephemeral workloads (tasks)
  • "Livestock not pets"
every abstraction doubles your threat model, over an animated Rube Goldberg machine

What is a container, anyways?


(the ten-thousandth iteration of software distribution)

If it isn't a virtual machine, what is it?

Container stack diagram — apps and dependencies in containers, on a container runtime, on an OS, on hardware. 'You are here' points at one container.

It's a Linux process that carries along its' own dependencies.


✨ It isn't as isolated as you think ✨


Honestly, it isn't really isolated at all. At least not by default.


But it's convenient!

The same layer diagram, plus the OCI configuration: user, entrypoint, CMD, environment variables, and more

Security boundaries

✨ A container is a process. ✨

Secure Computing (seccomp)


The foundation we build on!

  • Want to read a file? open() and read()
  • Write to the network? socket() + friends
  • Make a new directory? mkdir()

It's all system calls (syscalls). There's hundreds. makelinux.github.io/kernel/map


Do you need hundreds?

seccomp is like an electric fence.


Jurassic Park — animation of a boy climbing an electric fence, thrown backwards when it energizes

I didn't want to become a kernel expert today


Let's chart our escapes based on what a container is under the hood.


  • namespaces - what a container can SEE
  • cgroups - what a container can HAVE
  • capabilities - what a container can DO
  • overlayfs - the weird filesystem that stacks on top of itself

AppArmor or SELinux are part of the host's kernel called Mandatory Access Control. They make sure each process can only touch things it's allowed to.

Namespaces (see)


How single resources, like a network card, are shared across many processes without those processes seeing each other.


  1. Hostname (uts)
  2. System time (time)
  3. Inter-process comms (ipc)
  4. Control groups! (cgroup)
  5. Mount points (mount)
  6. Network (network)
  7. Process IDs (process)
  8. User IDs (user)

Minimizing what a container can see


  • Reduces attack surface
  • Reduces amount of information exposed for living off the land
docker run -it --uts=host ubuntu:jammy bash gives a shell whose hostname is the host's; without --uts=host the hostname is the container ID

Control groups (have)


  • It's a weird filesystem.
  • Defines and sets boundaries on what a process can have.
  • Protect it. Messing with it can be part of a denial of service attack.
cat /sys/fs/cgroup/cpu.stat and memory.pressure showing CPU usage and memory pressure counters
ls -lah /sys/fs/cgroup showing cgroup.controllers, cpu.stat, memory.pressure, io.stat, system.slice, user.slice and more

Capabilities (do) - let's get dangerous!


  • Used to be root/admin/everything or nothing at all
  • Now there's about 40 unique permissions
  • CAP_NET_BIND_SERVICE
  • CAP_AUDIT_READ
  • CAP_SYS_PTRACE
  • CAP_SYS_ADMIN is effectively everything

Be careful out there!


This gives us a better escape and more of a foothold once we're out.

xkcd 149: 'make me a sandwich' / 'what? make it yourself' / 'sudo make me a sandwich' / 'okay'

Mandatory Access Controls


'Fun Police — the fun is done' sticker
  • One more line of defense - SELinux or AppArmor
  • Part of the host - each process (container) can only touch/do things based on
    • User
    • Role
    • File locations, processes, etc - CONTEXT
  • SELinux is more RedHat
  • AppArmor is more Debian

😩 The reason I bring this up is that it's common to disable these! It's usually the first suggestion and it's easier to leave it off than troubleshoot and write a new policy.

What's an escape?

Container escape — an arrow from an app inside a container down to the host operating system, past the container runtime

Types of escapes


  1. Kernel vulnerabilities ("dirty pipe" or CVE-2022-0847)
  2. Runtime vulnerabilities (2024's "leaky vessels" CVEs for runc and BuildKit)
  3. Insecure configuration at runtime

We're focusing on that third one.


  • Most common (in my experience)
  • Least "alarmed on" and most likely to get dismissed (in my experience)
  • ... also most reliable in a workshop ...

Where this fits in an attack


Several hosts each running containers on a runtime, all under a container orchestration layer (usually Kubernetes), with an image registry alongside

ATT&CK matrix for containers

Initial Access

  • Exploit Public-Facing Application in the wild
  • External Remote Services
  • Default Accounts
  • Local Accounts

Execution

  • Container CLI/API runtime groups · sockets
  • Container Administration Command shared sockets
  • Deploy Container shared sockets
  • Container Orchestration Job
  • Malicious Image

Persistence

  • Additional Container Cluster Roles
  • Local Account
  • Container Service
  • External Remote Services
  • Implant Internal Image
  • Container Orchestration Job
  • Default Accounts
  • Local Accounts

Privilege Escalation

  • Additional Container Cluster Roles
  • Container Service
  • Escape to Host storage · chroot · runtime groups · sockets · ptrace
  • Exploitation for Privilege Escalation
  • Container Orchestration Job
  • Default Accounts
  • Local Accounts

Stealth

  • Build Image on Host
  • Indicator Removal
  • Match Legitimate Name or Location
  • Masquerade Account Name
  • Default Accounts
  • Local Accounts

Defense Impairment

  • Disable or Modify Tools

Credential Access

  • Password Guessing
  • Password Spraying
  • Credential Stuffing
  • Steal Application Access Token
  • Credentials In Files secrets in layers
  • Container API shared sockets

Discovery

  • Container and Resource Discovery who am I? · shared kernel · capabilities · seccomp · microVM?
  • Network Service Discovery
  • Permission Groups Discovery who am I? · capabilities

Lateral Movement

  • Application Access Token

Impact

  • Data Destruction
  • Endpoint Denial of Service
  • Inhibit System Recovery
  • Network Denial of Service
  • Compute Hijacking
  • Bandwidth Hijacking

Highlighted = we do this today, with the workshop module named · attack.mitre.org/matrices/enterprise/containers

Enumeration


  1. Who am I? - Let's get oriented and figure out what we have in our container.
  2. Our shared kernel - Containers are processes that share a kernel. What can we see?
  3. Are we capable? - What sort of capabilities do we have?
  4. Seccomp is your friend - Seccomp filters what a container can do. Let's learn what's been set for us.
  5. Are we in a microVM? - With microVM runtimes gaining popularity, how do you know if you're in a container?

Escapes!!


  1. Persistent storage - Persisting through persistent storage
  2. Chrooooooooot - chroot right on out of a container's filesystem.
  3. Runtime groups - The default "docker" group is basically root.
  4. Shared runtime sockets - Use a shared socket to create a new container
  5. Messing with the host's memory - Let's modify a process in memory to do fun things! (example is x86_64 only)
  6. Vulnerable apps in the wild - You're typically not SSH'd into the container host, so ... how does this still work in the wild?
  7. Finding secrets in image layers - Finding secrets in a container image's layers can be done at runtime if you have access to download it and a shell or access to the host's socket or access to the registry.

Some thoughts on AI


  • This is a 101-type class, full of minutia and variants and "gotchas".
  • Robots do this really work really well and silly fast.
  • The past few months, I've seen autonomous or semi-autonomous offensive systems
    • figure out the CNI that an application uses, then find the rest of the application components through a default configuration
    • exfiltrate data over DNS records
    • enumerate database tables and find other applications using the same database
    • find a command injection point, chroot out, and start to enumerate the root file system
  • Before "AI", it was still a pretty common "script kiddy" automated task.
  • My graduate school advisor said "Excel is the single worst thing to happen to engineering." We may be at that point with AI. It's okay.

💖 Never let a "better/faster next number prediction machine" take the joy of learning away from you. 💖

The Linux kernel map — hundreds of labelled subsystems and functions layered from user space down through system calls, virtual memory, and device drivers to hardware

makelinux/linux_kernel_map (GPL-3.0)

An agent transcript: it refreshes a GitHub token with the admin:org scope, exports an account-admin AWS profile, then runs terraform plan against live state — each step reported as completed

you're still responsible when you give up control

Workshops


  • Two parts
    • Enumeration
    • Escapes!!
  • Need a screen reader?
  • Need to make fonts bigger?
  • Want to work at your own pace?
  • Revisit things later?

some-natalie.dev/container-escapes-workshop


(slides, notes, workshop examples, etc.)

QR code linking to some-natalie.dev/container-escapes-workshop