You are on page 1of 68

Container Security & Hardening

Workshop

This presentation provides an overview of containers,


container architecture, and how to build & deploy secure
containers.

- Rohit Kumar (@rohitcoder)


About me

● Security Engineer @ Groww


● Maintainer of “Code Arsenal Community”
● Top 20 Security Researcher at Meta Bug Bounty since last 5 years
● Automates Everything!
● Participated in Some Live Hacking Events by Meta
● I Code in Rust, Python, Javascript
● Source Code Security, Supply Chain Security & Pipeline Security.

@rohitcoder @rohitcoder @rohitcoder


Agenda

1. Introduction
2. Understanding Containers
3. Docker Basics
4. Writing a Secure Dockerfile
5. Container Vulnerabilities
6. Scanning Docker Images
7. Mitigating Container Vulnerabilities
8. Building Secure Container Images
9. Running Containers Securely
10. Conclusion and Q&A
Let’s first understand,
What are Containers?
1. Container: Lightweight, isolated unit for
packaging applications and dependencies.
2. Creation: Use Docker or Kubernetes with
container images.
3. Dockerfile or Kubernetes manifest: Define
configuration and build instructions.
4. Build: Containerization tool reads instructions
and creates reproducible image.
5. Result: Portable environment for consistent
application execution.
Containers and their benefits

● Portability ● Scalability
● Isolation ● Version Control
● Efficiency ● Security
● Consistency ● Simplified Maintenance
● Rapid Deployment ● Cloud Adoption
Docker & Virtual Machines
● In virtual machines (VMs), hardware resources
are shared among multiple instances. This
involves carefully allocating specific portions of
memory and CPU to each VM. In contrast,
containers function as lightweight processes that
share the underlying operating system.

● Containers have restrictions on the resources


they can access, and they terminate when the
process within them concludes. Starting a VM
demands a substantial boot-up time due to the
presence of its individual operating system,
contributing to their larger size. Conversely,
containers possess a comparably smaller
footprint and can rapidly initiate and execute.
Popular containerization techs and registries
Docker Basics

Let’s Install & Setup Docker

Download Docker Setup from - https://www.docker.com/

● Windows Users: https://www.youtube.com/watch?v=4xK-zaCRiPQ


● Mac OS Users: https://www.youtube.com/watch?v=SGmFGYCuJK4
Docker Basics

Verify docker command


How Container gets created?
How to run Docker images, Containers
and manage it?
Some basic Commands / Options in Docker

● pull ● build & buildx


● images ● Remove (-rm) - Exist once its
● system prune finished
● Mounting to local directory (-v) ● List all running containers (docker
● Interactive mode (-it) ps)
● System Events (docker system
events)
Docker Basics

How to Pull Images?


Docker Basics
How to list all docker Images?
Docker Basics
How to list all running docker process?
Docker Basics
How to run docker Images?
Docker Basics

How to clean all docker Containers / Images?


Docker Basics
Docker system events
Containers We can use this to monitor docker events for security events
======
attach,commit,copy,cre Volumes
ate,destroy,detach,die,e ======
xec_create,exec_detac create,mount,unmou
h,exec_die,exec_start,e nt,destroy
xport,health_status,kill,o
om,pause,rename,resiz Plugins
e,restart,start,stop,top,u =====
npause,update
install,enable,disable
Images ,remove
=====
Daemons
delete,import,load,pull,p =====
ush,save,tag,untag reload

Networks
=====
create,connect,disconn
ect,destroy
Docker Basics

Filters in Docker system events

container (container=<name or id>)


daemon (daemon=<name or id>)
event (event=<event action>)
image (image=<tag or id>)
label (label=<key> or label=<key>=<value>)
network (network=<name or id>)
plugin (plugin=<name or id>)
type (type=<container or image or volume or network or
daemon or plugin>)
volume (volume=<name or id>)

https://docs.docker.com/engine/reference/commandline/system_events/
Docker Basics
How to build our own docker Images?

Build & BuildX


Now, let’s build our own Docker Image!
Clone this sample repo in Your PC

git clone https://github.com/rohitcoder/node-hello


Let’s write a Basic Dockerfile for this!

Use Docker buildX


Command
Use Docker build Command
docker buildx build -t
docker build -t node-vuln .
node-vuln .
Normal docker build command throws an exception

When you have buildX, use only buildx


Command
Use Below command to run application from your local docker image

docker run -p <host_port>:<container_port> <image_name>

docker run -d -p 3005:3000 node-app:vuln


Now, how to make this available to all users?

1. Create local Docker image


2. Now do a docker login using “docker login” command
3. Now create a public repository inside your dockerhub account
4. Now tag your local docker image to dockerhub image name
5. Now, push the docker image to registry!
You Deployed your first Docker image!

Now what?
Security Issues in Container Lifecycle

Over-Privilege issues,
CVEs & Known Vulns Run-time Security issues
Misconfigurations
Possible Security Issues in Dockerfiles
1. Using outdated or vulnerable base images.
2. Setting weak or easily guessable passwords.
3. Running the application as the root user.
4. Copying sensitive files or credentials into the
container.
5. Exposing unnecessary ports or services.
6. Not updating packages or dependencies
regularly.
7. Installing unnecessary packages or tools.
8. Not using a .dockerignore file to exclude
sensitive files from being copied.
9. Ignoring container size and complexity, leading
to potential attack vectors.
10. Executing privileged commands or processes
within the container.
Possible Security Issues in Container Images

gcr.io/google-containers/aggregator:201
1. Vulnerable base images. 5-11-10-34b976a
2. Insecure software installation.
3. Embedded secrets and credentials.
4. Excessive privileges.
5. Unnecessary software and packages.
6. Unpatched software. rapid7/container-image
7. Insecure default settings. -scanner
8. Image sprawl.
9. Unsecured image repositories.
10. Incomplete or misconfigured image build process.

public.ecr.aws/datadog/agent:7.
45.1-rc.2-jmx
Possible Security Issues in Running Containers

1. Container Breakout
2. Privilege Escalation
3. Inadequate Isolation
4. Unsecured Container Interfaces
5. Inadequate Resource Limits
6. Container Image Vulnerabilities
7. Unprotected Sensitive Data
8. Insecure APIs and Orchestration Systems
9. Container Image Integrity
10. Insider Threats
Possible Security Issues in Running Containers

1. Container Breakout
2. Privilege Escalation
3. Inadequate Isolation
4. Unsecured Container Interfaces
5. Inadequate Resource Limits
6. Container Image Vulnerabilities
7. Unprotected Sensitive Data
8. Insecure APIs and Orchestration Systems
9. Container Image Integrity
10. Insider Threats
Hacking time!
Let’s hack a real container, and get
access to all the source code!
1. Run this Command - docker run -d -p 3000:3000
rohitcoder/node-app:vuln
2. List all running containers - docker ps
3. Now pick one Process ID and use it to get into that
docker shell - docker exec -it 51fe99fe2780 bash
4. Now Explore this container, as you explore a normal
disk!
Full root
access!

.env file / creds


exposed

Source Code
Disclosure
How to fix Privilege Escalation?
RUN groupadd -r guests && useradd -r -g guests rohit
Full root
access!

.env file / creds *Start with -u username*


exposed

I tried to switch as sudo, and its asking us


Logged in as rohit user account for password.

Source Code
Disclosure
Still not a proper fix! What if attacker knows the root
password?

Let’s look at one example, with a root password


Let’s take password for root user in build time from user
Privilege escalation, when password is known ;)
Not Recommended! Because a root should be completely disabled not password protected on prod
environment

Attacker trying to switch as root and provided password test123


Let’s restrict root user’s Interactive shell with
nologin

/usr/sbin/nologin is specifically designed to replace a shell and produces output complaining you can't
log-in
Now, no one can login as root, Secured!
Full root
access!
Running container in privilege mode vs restricted
mode Full root
access!

docker run --it --rm --privileged node-hello

Not recommended, Extremely danger!

This gives full access to the host system / linux kernel, bypassing almost all security checks and
implementation enforced by docker. (It removes isolation capabilities)
What if, i Still want to use --privileged flag, but
i’m afraid of getting hacked? Full root
access!

Linux Capabilities to the Rescue!

Let’s look at Man page of Linux Kernel’s Capabilities -


https://linux.die.net/man/7/capabilities
Dropping or adding Capabilities to interact with
Linux kernel Full root
access!

Attacker isn’t able to switch as root

Dropping all Capabilities and then adding NET_ADMIN Capabilities


Other ways to prevent Privilege Escalations
Full
docker run --it --rm --security-opt=no-new-privileges root
node-hello
access!

Attacker isn’t able to switch as root


Restricting container file-system access
Full root
docker run --read-only -u rohit -it --rm node-hello bash
access!

From rohit user i can’t create


file

Same with root user :)


Restricting container file-system access with temp access
docker run --read-only -u rohit -it –tmpfs /opt --rm Full
node-hello
root bash
access!

We can’t create files here

Here we can create files!


Let’s understand how networking works in container

By default all containers run on Bridge network

Let’s take a look at this Subnet 172.17.0.0/16

Inter-Container Communication
Let’s run a container and see it’s network details

By default all containers run on Bridge network

IP 172.17.0.2 is part of Subnet 172.17.0.0/16


Create two containers from same image, and install
net-tools to check IP of both containers
Let’s note IP of both machine and ping it from another
machine
Bridge connection working, this is how dockers
communicate!
Let’s disable inter communication?
Turning off icc communication in our newly created
network

Using same technique you can change Subnet or


other settings
Let’s run a container with newly created network and install
basic networking tools.
Running on Subnet 1
(Bridge) Running on
(test-net)

Pings not successful, process isn’t moving ahead.


Few more slides
Now, let’s look do some Code Scan
and Image scans!

1. SAST Scan 2. Image Scan


Semgrep is a free open-source static code analysis tool
developed by Semgrep, Inc It has stable support for C#,
Go, Java, JavaScript, JSON, Python, PHP, Ruby, and
Scala.

We can use it for scanning Dockerfiles

Find docker rules here -

https://github.com/returntocorp/semgrep-rul
es/tree/develop/dockerfile
Let’s Install semgrep

For Mac Users - brew install semgrep

For Mac / Window / Linux Users - python3 -m pip install semgrep

Use semgrep scan --config p/dockerfile command to scan a


directory
We found 1 Security issue in our Dockerfile
Let’s Install trivy

For Mac Users - brew install trivy

For other users - Try install script from


https://aquasecurity.github.io/trivy/v0.18.3/installation/

Use trivy image node-app:tagname command to scan an image


Trivy Scan Results
Let’s Install Grype

For Mac Users - brew tap anchore/grype


brew install grype

For other users - Try install script from


https://github.com/anchore/grype

Use grype node-app:tagname command to scan an image


Grype Scan Results
How to fix or avoid Security Issues using
different tools?

Shift left - Security in SDLC (SAST) Continuous image scanning Use Trusted Image Providers

Misconfigurations in Kubernetes
Updating base image and installed
deployment / applications
Runtime Container Events logging softwares regularly
Q&A Time

You might also like