Compare commits

..

9 Commits

Author SHA1 Message Date
Daniel Sagi
b6fe065dae added windows support using a powershell snippet for interface enum 2022-08-25 21:15:32 +03:00
Daniel Sagi
ad9956e18c fixed bug in subnets appending 2022-08-25 20:05:32 +03:00
Daniel Sagi
7f98e384a5 added pyroute2 as a dependency 2022-08-25 19:30:14 +03:00
Daniel Sagi
0a1e61fd8b changed to using pyroute2 instead of manually parsing /proc/net/route and instead of psutil for interface enum 2022-08-25 19:29:46 +03:00
Daniel Sagi
e43db1dbf2 Checking if /proc/net/route is accessible. before commiting to parse it 2022-08-16 16:42:30 +03:00
Daniel Sagi
a6b17e0f69 removed dependency on netifaces entirely by using psutil and manually parsing /proc/net/route to figure out default gateway 2022-08-16 16:31:41 +03:00
danielsagi
a578726495 update manifest to 0.6.8 (#509) 2022-05-13 12:49:12 +03:00
rhtenhove
c442172715 pin image version (#504)
* pin image version to job

* change docker tag format

* update semver GA
2022-05-13 00:27:39 +03:00
danielsagi
d7df38fc95 Fix: Removed automatic import of handler object (#506)
* removed automatic import of handler object in events package and renamed handler.py to event_handler.py to solve name collision
2022-05-12 22:12:31 +03:00
4 changed files with 85 additions and 11 deletions

View File

@@ -39,7 +39,7 @@ jobs:
password: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
- name: Get version
id: get_version
uses: crazy-max/ghaction-docker-meta@v1
uses: crazy-max/ghaction-docker-meta@v3
with:
images: ${{ env.REP }}
tag-semver: |

View File

@@ -5,11 +5,13 @@ metadata:
name: kube-hunter
spec:
template:
metadata:
labels:
app: kube-hunter
spec:
containers:
- name: kube-hunter
image: aquasec/kube-hunter
image: aquasec/kube-hunter:0.6.8
command: ["kube-hunter"]
args: ["--pod"]
restartPolicy: Never
backoffLimit: 4

View File

@@ -1,11 +1,13 @@
import json
import os
import sys
import socket
import logging
import itertools
import requests
from enum import Enum
from netaddr import IPNetwork, IPAddress, AddrFormatError
from netifaces import AF_INET, ifaddresses, interfaces, gateways
from kube_hunter.conf import get_config
from kube_hunter.modules.discovery.kubernetes_client import list_all_k8s_cluster_nodes
@@ -137,7 +139,9 @@ class FromPodHostDiscovery(Discovery):
elif self.is_aws_pod_v2():
subnets, cloud = self.aws_metadata_v2_discovery()
subnets += self.gateway_discovery()
gateway_subnet = self.gateway_discovery()
if gateway_subnet:
subnets.append(gateway_subnet)
should_scan_apiserver = False
if self.event.kubeservicehost:
@@ -217,7 +221,26 @@ class FromPodHostDiscovery(Discovery):
# for pod scanning
def gateway_discovery(self):
"""Retrieving default gateway of pod, which is usually also a contact point with the host"""
return [[gateways()["default"][AF_INET][0], "24"]]
# read the default gateway directly from /proc
# 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
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
# querying AWS's interface metadata api v1 | works only from a pod
def aws_metadata_v1_discovery(self):
@@ -338,13 +361,62 @@ class HostDiscovery(Discovery):
# generate all subnets from all internal network interfaces
def generate_interfaces_subnet(self, sn="24"):
for ifaceName in interfaces():
for ip in [i["addr"] for i in ifaddresses(ifaceName).setdefault(AF_INET, [])]:
if not self.event.localhost and InterfaceTypes.LOCALHOST.value in ip.__str__():
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']
# unless specified explicitly with localhost scan flag, skip localhost ip addresses
if not self.event.localhost and ipaddress.startswith(InterfaceTypes.LOCALHOST.value):
continue
ip_network = IPNetwork(f"{ipaddress}/{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
for ip in IPNetwork(f"{ip}/{sn}"):
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
class InterfaceTypes(Enum):

View File

@@ -31,7 +31,7 @@ zip_safe = False
packages = find:
install_requires =
netaddr
netifaces
pyroute2
requests
PrettyTable
urllib3>=1.24.3