mirror of
https://github.com/aquasecurity/kube-hunter.git
synced 2026-03-01 09:10:29 +00:00
Compare commits
1 Commits
dep/remove
...
dep/remove
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4887c87694 |
@@ -1,5 +1,6 @@
|
||||
FROM python:3.8-alpine as builder
|
||||
|
||||
RUN apk update
|
||||
RUN apk add --no-cache \
|
||||
linux-headers \
|
||||
tcpdump \
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import struct
|
||||
import socket
|
||||
import logging
|
||||
import itertools
|
||||
import requests
|
||||
|
||||
from pathlib import Path
|
||||
from enum import Enum
|
||||
from netaddr import IPNetwork, IPAddress, AddrFormatError
|
||||
from psutil import net_if_addrs
|
||||
|
||||
from kube_hunter.conf import get_config
|
||||
from kube_hunter.modules.discovery.kubernetes_client import list_all_k8s_cluster_nodes
|
||||
@@ -141,7 +142,7 @@ class FromPodHostDiscovery(Discovery):
|
||||
|
||||
gateway_subnet = self.gateway_discovery()
|
||||
if gateway_subnet:
|
||||
subnets.append(gateway_subnet)
|
||||
subnets += gateway_subnet
|
||||
|
||||
should_scan_apiserver = False
|
||||
if self.event.kubeservicehost:
|
||||
@@ -225,22 +226,20 @@ class FromPodHostDiscovery(Discovery):
|
||||
# netifaces currently does not have a maintainer. so we backported to linux support only for this cause.
|
||||
# TODO: implement WMI queries for windows support
|
||||
# https://stackoverflow.com/a/6556951
|
||||
if sys.platform in ["linux", "linux2"]:
|
||||
try:
|
||||
from pyroute2 import IPDB
|
||||
if not Path("/proc/net/route").exists():
|
||||
logging.debug("Error getting default gateway from /proc/net/route. not runnning in linux environment")
|
||||
return False
|
||||
|
||||
ip = IPDB()
|
||||
gateway_ip = ip.routes["default"]["gateway"]
|
||||
ip.release()
|
||||
return [gateway_ip, "24"]
|
||||
except Exception as x:
|
||||
logging.debug(f"Exception while fetching default gateway from container - {x}")
|
||||
finally:
|
||||
ip.release()
|
||||
else:
|
||||
logging.debug("Not running in a linux env, will not scan default subnet")
|
||||
|
||||
return False
|
||||
try:
|
||||
with open("/proc/net/route") as fh:
|
||||
for line in fh:
|
||||
fields = line.strip().split()
|
||||
if fields[1] != "00000000" or not int(fields[3], 16) & 2:
|
||||
# If not default route or not RTF_GATEWAY, skip it
|
||||
continue
|
||||
return [socket.inet_ntoa(struct.pack("<L", int(fields[2], 16))), "24"]
|
||||
except Exception as x:
|
||||
logging.debug(f"Exception when parsing /proc/net/route to figure default gateway: {x}")
|
||||
|
||||
# querying AWS's interface metadata api v1 | works only from a pod
|
||||
def aws_metadata_v1_discovery(self):
|
||||
@@ -361,61 +360,21 @@ class HostDiscovery(Discovery):
|
||||
|
||||
# generate all subnets from all internal network interfaces
|
||||
def generate_interfaces_subnet(self, sn="24"):
|
||||
if sys.platform == "win32":
|
||||
return self.generate_interfaces_subnet_windows()
|
||||
elif sys.platform in ["linux", "linux2"]:
|
||||
return self.generate_interfaces_subnet_linux()
|
||||
|
||||
def generate_interfaces_subnet_linux(self, sn="24"):
|
||||
try:
|
||||
from pyroute2 import IPRoute
|
||||
|
||||
ip = IPRoute()
|
||||
for i in ip.get_addr():
|
||||
# whitelist only ipv4 ips
|
||||
if i["family"] == socket.AF_INET:
|
||||
ipaddress = i[0].get_attr("IFA_ADDRESS")
|
||||
# TODO: add this instead of hardcoded 24 subnet, (add a flag for full scan option)
|
||||
# subnet = i['prefixlen']
|
||||
|
||||
ifaces = net_if_addrs()
|
||||
for _, ifaceAddresses in ifaces.items():
|
||||
# filter only ipv4 addresses on interface
|
||||
ipv4_addresses = list(filter(lambda x: x.family == socket.AF_INET, ifaceAddresses))
|
||||
if ipv4_addresses:
|
||||
for address in ipv4_addresses:
|
||||
# unless specified explicitly with localhost scan flag, skip localhost ip addresses
|
||||
if not self.event.localhost and ipaddress.startswith(InterfaceTypes.LOCALHOST.value):
|
||||
if not self.event.localhost and address.address.__str__().startswith(
|
||||
InterfaceTypes.LOCALHOST.value
|
||||
):
|
||||
continue
|
||||
|
||||
ip_network = IPNetwork(f"{ipaddress}/{sn}")
|
||||
ip_network = IPNetwork(f"{address.address}/{sn}")
|
||||
for ip in ip_network:
|
||||
yield ip
|
||||
except Exception as x:
|
||||
logging.debug(f"Exception while generating subnet scan from local interfaces: {x}")
|
||||
finally:
|
||||
ip.release()
|
||||
|
||||
def generate_interfaces_subnet_windows(self, sn="24"):
|
||||
from subprocess import check_output
|
||||
|
||||
local_subnets = (
|
||||
check_output(
|
||||
"powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy bypass -Command "
|
||||
' "& {'
|
||||
"Get-NetIPConfiguration | Get-NetIPAddress | Where-Object {$_.AddressFamily -eq 'IPv4'}"
|
||||
" | Select-Object -Property IPAddress, PrefixLength | ConvertTo-Json "
|
||||
' "}',
|
||||
shell=True,
|
||||
)
|
||||
.decode()
|
||||
.strip()
|
||||
)
|
||||
try:
|
||||
subnets = json.loads(local_subnets)
|
||||
for subnet in subnets:
|
||||
if not self.event.localhost and subnet["IPAddress"].startswith(InterfaceTypes.LOCALHOST.value):
|
||||
continue
|
||||
ip_network = IPNetwork(f"{subnet['IPAddress']}/{sn}")
|
||||
for ip in ip_network:
|
||||
yield ip
|
||||
|
||||
except Exception as x:
|
||||
logging.debug(f"ERROR: Could not extract interface information using powershell - {x}")
|
||||
|
||||
|
||||
# for comparing prefixes
|
||||
|
||||
Reference in New Issue
Block a user