From c54859ec379a4a4635fe389ae2f154b3f486cc23 Mon Sep 17 00:00:00 2001 From: Daniel Sagi Date: Fri, 1 Apr 2022 19:12:01 +0300 Subject: [PATCH] removed arp and dns hunters usage due to it's violations of the scapy GPL2 license --- kube_hunter/conf/logging.py | 4 -- kube_hunter/modules/hunting/__init__.py | 2 - kube_hunter/modules/hunting/arp.py | 71 ------------------- kube_hunter/modules/hunting/dns.py | 90 ------------------------- setup.cfg | 1 - tests/core/test_handler.py | 4 -- 6 files changed, 172 deletions(-) delete mode 100644 kube_hunter/modules/hunting/arp.py delete mode 100644 kube_hunter/modules/hunting/dns.py diff --git a/kube_hunter/conf/logging.py b/kube_hunter/conf/logging.py index bf5ed5a..9449883 100644 --- a/kube_hunter/conf/logging.py +++ b/kube_hunter/conf/logging.py @@ -4,10 +4,6 @@ DEFAULT_LEVEL = logging.INFO DEFAULT_LEVEL_NAME = logging.getLevelName(DEFAULT_LEVEL) LOG_FORMAT = "%(asctime)s %(levelname)s %(name)s %(message)s" -# Suppress logging from scapy -logging.getLogger("scapy.runtime").setLevel(logging.CRITICAL) -logging.getLogger("scapy.loading").setLevel(logging.CRITICAL) - def setup_logger(level_name, logfile): # Remove any existing handlers diff --git a/kube_hunter/modules/hunting/__init__.py b/kube_hunter/modules/hunting/__init__.py index 1d38fe4..d5d5e5b 100644 --- a/kube_hunter/modules/hunting/__init__.py +++ b/kube_hunter/modules/hunting/__init__.py @@ -2,12 +2,10 @@ from . import ( aks, apiserver, - arp, capabilities, certificates, cves, dashboard, - dns, etcd, kubelet, mounts, diff --git a/kube_hunter/modules/hunting/arp.py b/kube_hunter/modules/hunting/arp.py deleted file mode 100644 index 0a37f1d..0000000 --- a/kube_hunter/modules/hunting/arp.py +++ /dev/null @@ -1,71 +0,0 @@ -import logging - -from scapy.all import ARP, IP, ICMP, Ether, sr1, srp - -from kube_hunter.conf import get_config -from kube_hunter.core.events import handler -from kube_hunter.core.events.types import Event, Vulnerability -from kube_hunter.core.types import ActiveHunter, KubernetesCluster, ARPPoisoningTechnique -from kube_hunter.modules.hunting.capabilities import CapNetRawEnabled - -logger = logging.getLogger(__name__) - - -class PossibleArpSpoofing(Vulnerability, Event): - """A malicious pod running on the cluster could potentially run an ARP Spoof attack - and perform a MITM between pods on the node.""" - - def __init__(self): - Vulnerability.__init__( - self, - KubernetesCluster, - "Possible Arp Spoof", - category=ARPPoisoningTechnique, - vid="KHV020", - ) - - -@handler.subscribe(CapNetRawEnabled) -class ArpSpoofHunter(ActiveHunter): - """Arp Spoof Hunter - Checks for the possibility of running an ARP spoof - attack from within a pod (results are based on the running node) - """ - - def __init__(self, event): - self.event = event - - def try_getting_mac(self, ip): - config = get_config() - ans = sr1(ARP(op=1, pdst=ip), timeout=config.network_timeout, verbose=0) - return ans[ARP].hwsrc if ans else None - - def detect_l3_on_host(self, arp_responses): - """returns True for an existence of an L3 network plugin""" - logger.debug("Attempting to detect L3 network plugin using ARP") - unique_macs = list({response[ARP].hwsrc for _, response in arp_responses}) - - # if LAN addresses not unique - if len(unique_macs) == 1: - # if an ip outside the subnets gets a mac address - outside_mac = self.try_getting_mac("1.1.1.1") - # outside mac is the same as lan macs - if outside_mac == unique_macs[0]: - return True - # only one mac address for whole LAN and outside - return False - - def execute(self): - config = get_config() - self_ip = sr1(IP(dst="1.1.1.1", ttl=1) / ICMP(), verbose=0, timeout=config.network_timeout)[IP].dst - arp_responses, _ = srp( - Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op=1, pdst=f"{self_ip}/24"), - timeout=config.network_timeout, - verbose=0, - ) - - # arp enabled on cluster and more than one pod on node - if len(arp_responses) > 1: - # L3 plugin not installed - if not self.detect_l3_on_host(arp_responses): - self.publish_event(PossibleArpSpoofing()) diff --git a/kube_hunter/modules/hunting/dns.py b/kube_hunter/modules/hunting/dns.py deleted file mode 100644 index b0e037b..0000000 --- a/kube_hunter/modules/hunting/dns.py +++ /dev/null @@ -1,90 +0,0 @@ -import re -import logging - -from scapy.all import IP, ICMP, UDP, DNS, DNSQR, ARP, Ether, sr1, srp1, srp - -from kube_hunter.conf import get_config -from kube_hunter.core.events import handler -from kube_hunter.core.events.types import Event, Vulnerability -from kube_hunter.core.types import ActiveHunter, KubernetesCluster, CoreDNSPoisoningTechnique -from kube_hunter.modules.hunting.arp import PossibleArpSpoofing - -logger = logging.getLogger(__name__) - - -class PossibleDnsSpoofing(Vulnerability, Event): - """A malicious pod running on the cluster could potentially run a DNS Spoof attack - and perform a MITM attack on applications running in the cluster.""" - - def __init__(self, kubedns_pod_ip): - Vulnerability.__init__( - self, - KubernetesCluster, - "Possible DNS Spoof", - category=CoreDNSPoisoningTechnique, - vid="KHV030", - ) - self.kubedns_pod_ip = kubedns_pod_ip - self.evidence = f"kube-dns at: {self.kubedns_pod_ip}" - - -# Only triggered with RunningAsPod base event -@handler.subscribe(PossibleArpSpoofing) -class DnsSpoofHunter(ActiveHunter): - """DNS Spoof Hunter - Checks for the possibility for a malicious pod to compromise DNS requests of the cluster - (results are based on the running node) - """ - - def __init__(self, event): - self.event = event - - def get_cbr0_ip_mac(self): - config = get_config() - res = srp1(Ether() / IP(dst="1.1.1.1", ttl=1) / ICMP(), verbose=0, timeout=config.network_timeout) - return res[IP].src, res.src - - def extract_nameserver_ip(self): - with open("/etc/resolv.conf") as f: - # finds first nameserver in /etc/resolv.conf - match = re.search(r"nameserver (\d+.\d+.\d+.\d+)", f.read()) - if match: - return match.group(1) - - def get_kube_dns_ip_mac(self): - config = get_config() - kubedns_svc_ip = self.extract_nameserver_ip() - - # getting actual pod ip of kube-dns service, by comparing the src mac of a dns response and arp scanning. - dns_info_res = srp1( - Ether() / IP(dst=kubedns_svc_ip) / UDP(dport=53) / DNS(rd=1, qd=DNSQR()), - verbose=0, - timeout=config.network_timeout, - ) - kubedns_pod_mac = dns_info_res.src - self_ip = dns_info_res[IP].dst - - arp_responses, _ = srp( - Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op=1, pdst=f"{self_ip}/24"), - timeout=config.network_timeout, - verbose=0, - ) - for _, response in arp_responses: - if response[Ether].src == kubedns_pod_mac: - return response[ARP].psrc, response.src - - def execute(self): - config = get_config() - logger.debug("Attempting to get kube-dns pod ip") - self_ip = sr1(IP(dst="1.1.1.1", ttl=1) / ICMP(), verbose=0, timeout=config.network_timeout)[IP].dst - cbr0_ip, cbr0_mac = self.get_cbr0_ip_mac() - - kubedns = self.get_kube_dns_ip_mac() - if kubedns: - kubedns_ip, kubedns_mac = kubedns - logger.debug(f"ip={self_ip} kubednsip={kubedns_ip} cbr0ip={cbr0_ip}") - if kubedns_mac != cbr0_mac: - # if self pod in the same subnet as kube-dns pod - self.publish_event(PossibleDnsSpoofing(kubedns_pod_ip=kubedns_ip)) - else: - logger.debug("Could not get kubedns identity") diff --git a/setup.cfg b/setup.cfg index 53a2f8a..3e22976 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,7 +32,6 @@ packages = find: install_requires = netaddr netifaces - scapy>=2.4.3 requests PrettyTable urllib3>=1.24.3 diff --git a/tests/core/test_handler.py b/tests/core/test_handler.py index 5cf1546..46baab5 100644 --- a/tests/core/test_handler.py +++ b/tests/core/test_handler.py @@ -20,14 +20,12 @@ from kube_hunter.modules.hunting.apiserver import ( AccessApiServerActive, AccessApiServerWithToken, ) -from kube_hunter.modules.hunting.arp import ArpSpoofHunter from kube_hunter.modules.hunting.capabilities import PodCapabilitiesHunter from kube_hunter.modules.hunting.certificates import CertificateDiscovery from kube_hunter.modules.hunting.cves import K8sClusterCveHunter from kube_hunter.modules.hunting.cves import KubectlCVEHunter from kube_hunter.modules.hunting.dashboard import KubeDashboard -from kube_hunter.modules.hunting.dns import DnsSpoofHunter from kube_hunter.modules.hunting.etcd import EtcdRemoteAccess, EtcdRemoteAccessActive from kube_hunter.modules.hunting.kubelet import ( ProveAnonymousAuth, @@ -76,8 +74,6 @@ PASSIVE_HUNTERS = { ACTIVE_HUNTERS = { ProveAzureSpnExposure, AccessApiServerActive, - ArpSpoofHunter, - DnsSpoofHunter, EtcdRemoteAccessActive, ProveRunHandler, ProveContainerLogsHandler,