

이번 문제는 컨테이너 내부에서 호스트 시스템의 컨테이너 런타임 소켓에 접근할 수 있을 때 발생하는 보안 위험에 대해 다루고 있다.
DIND(Docker In Docker) 방식은 개발 편의성과 CI/CD 구성의 단순함 때문에 과거부터 널리 사용되어 왔다. 하지만 클라우드 네이티브 환경에서 호스트 소켓을 공유하는 행위는 컨테이너의 근본적인 격리 원칙에 위배된다.

문제에서 확인할 수 있는 웹 사이트는 위와 같다. "Ping Your Severs"라고 되어 있는 것으로 보아 특정 IP로 Ping을 보낼 수 있는 것 같다.

127.0.0.1을 입력하고 Submit 버튼을 누르면 아래와 같이 Ping을 수행한 결과를 확인할 수 있다. 일반적으로 터미널에서 ping을 보내는 것과 다를게 없다. 그럼 RCE(Remote Commend Execution)가 가능하지 않을까?

| id 명령을 입력하고 Submit을 눌렀더니 실제 id 명령을 수행했을 때의 결과와 같은 결과를 확인할 수 있었다. 즉, 원격으로 명령어를 실행하는 것이 가능하다는 것을 알 수 있었다. 이제 해당 시스템에 마운트 되어 있는 파일에 대한 정보를 확인 해보자.

; mount 명령을 입력해서 실행한 결과 위와 같은 결과를 확인할 수 있다. (rw,relatime,errors=remount-ro)는 마운트 지점에 적용된 옵션으로 읽기와 쓰기가 가능하다는 것이고, 에러가 발생하면 remout한다는 것이다. tmpfs는 메모리 기반의 임시 파일 시스템이고 /run/containerd/containerd.sock 컨테이너 통신 소켓을 읽기 전용으로 마운트 했다는 것을 알 수 있다.

crictl이라는 K8s 환경에서 컨테이너 런타임과 상호작용을 위한 cli 도구를 내부에 받고, 이를 활용해서 내부 정보를 확인 해보자.
# crictl 다운로드 (aarch64)
;wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.27.1/crictl-v1.27.1-linux-amd64.tar.gz -O /tmp/crictl-v1.27.1.tar.gz
# 압축 해제
;tar -xvf /tmp/crictl-v1.27.1.tar.gz -C /tmp/
crictl 바이너리를 다운로드 받고 명령어를 실행하면 Container 이미지에 대한 정보들을 확인할 수 있고, 이를 통해 권한 상승, 컨테이너 소캣을 활용한 컨테이너 탈출 등 다양한 공격이 가능하다.
해당 문제에서 발생하고 있는 취약점을 방지하기 위해 인프라, 시스템 및 런타임, 어플리케이션 세 가지 측면에서 보안 권고 사항을 작성 해보겠다.
호스트 소켓 마운트 금지
/var/run/docker.sock 또는 containerd.sock과 같은 호스트의 컨테이너 런타임 소켓을 컨테이너 내부에 마운트하지 않아야 한다.
이는 컨테이너가 호스트의 컨테이너 엔진에 명령을 내릴 수 있게 허용하여, 사실상 호스트 노드에 대한 루트 권한을 부여하는 것과 같다.
특권모드 비활성화
Pod의 securityContext에서 privileged: true 설정을 사용하지 않아야 한다. 특권 컨테이너는 호스트의 모든 장치에 접근할 수 있어 탈출 공격에 노출될 위험이 높아진다.
비루트(Non-root) 사용자 실행
컨테이너 내부 프로세스를 루트 권한이 아닌 일반 사용자 권한으로 실행해야 한다. 만약 소켓이 마운트되어 있더라도, 일반 사용자 권한으로는 소켓 파일에 대한 읽기/쓰기 권한이 제한되어 공격을 지연시킬 수 있습니다.
커널레벨 런타임 보안 도구 활용
Falco나 Tetragon과 같은 도구를 사용하여 컨테이너 내부에서 발생하는 비정상적인 소켓 파일 접근, 특정 바이너리(crictl, docker 등)의 실행, 또는 민감한 파일 수정을 실시간으로 탐지하고 차단한다.