mirror of
https://github.com/aquasecurity/kube-hunter.git
synced 2026-05-11 03:37:52 +00:00
changed output results table format, added AzureMetadata vulnerability on discovery
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import logging
|
||||
from prettytable import PrettyTable
|
||||
from prettytable import PrettyTable, ALL
|
||||
from src.core.events import handler
|
||||
from src.core.events.types import Vulnerability, Information, Service
|
||||
|
||||
@@ -36,14 +36,19 @@ class OpenServiceReport(object):
|
||||
services.append(self.service)
|
||||
|
||||
def print_results(active):
|
||||
services_table = PrettyTable(["Service", "Location", "Description"])
|
||||
services_table = PrettyTable(["Service", "Location", "Description"], hrules=ALL)
|
||||
services_table.align="l"
|
||||
services_table.max_width=60
|
||||
for service in services:
|
||||
services_table.add_row([service.get_name(), "{}:{}{}".format(service.host, service.port, service.get_path()), service.explain()])
|
||||
|
||||
column_names = ["Location", "Category", "Vulnerability", "Description"]
|
||||
if active: column_names.append("Evidence")
|
||||
|
||||
vuln_table = PrettyTable(column_names)
|
||||
vuln_table = PrettyTable(column_names, hrules=ALL)
|
||||
vuln_table.align="l"
|
||||
vuln_table.max_width=70
|
||||
vuln_table.sortby="Category"
|
||||
for vuln in vulnerabilities:
|
||||
row = ["{}:{}".format(vuln.host, vuln.port), vuln.component.name, vuln.get_name(), vuln.explain()]
|
||||
if active:
|
||||
|
||||
@@ -10,8 +10,15 @@ from netifaces import AF_INET, ifaddresses, interfaces
|
||||
|
||||
from __main__ import config
|
||||
from ...core.events import handler
|
||||
from ...core.events.types import Event, NewHostEvent
|
||||
from ...core.events.types import Event, NewHostEvent, Vulnerability
|
||||
from ...core.types import Hunter
|
||||
from ..hunting.aks import Azure
|
||||
|
||||
class AzureMetadataApi(Vulnerability, Event):
|
||||
def __init__(self, cidr):
|
||||
Vulnerability.__init__(self, Azure, "Azure Metadata Exposure")
|
||||
self.cidr = cidr
|
||||
self.evidence = "cidr: {}".format(cidr)
|
||||
|
||||
class HostScanEvent(Event):
|
||||
def __init__(self, pod=False, active=False, predefined_hosts=list()):
|
||||
@@ -41,6 +48,7 @@ class HostDiscovery(Hunter):
|
||||
|
||||
if config.pod:
|
||||
if self.is_azure_cluster():
|
||||
self.event.azure_cluster = True
|
||||
self.azure_metadata_discovery()
|
||||
else:
|
||||
self.traceroute_discovery()
|
||||
@@ -55,7 +63,7 @@ class HostDiscovery(Hunter):
|
||||
if requests.get("http://169.254.169.254/metadata/instance?api-version=2017-08-01", headers={"Metadata":"true"}).status_code == 200:
|
||||
return True
|
||||
except Exception as ex:
|
||||
logging.debug("Not azure cluster " + ex.message)
|
||||
logging.debug("Not azure cluster " + str(ex.message))
|
||||
return False
|
||||
|
||||
# for pod scanning
|
||||
@@ -70,10 +78,12 @@ class HostDiscovery(Hunter):
|
||||
# quering azure's interface metadata api | works only from a pod
|
||||
def azure_metadata_discovery(self):
|
||||
machine_metadata = json.loads(requests.get("http://169.254.169.254/metadata/instance?api-version=2017-08-01", headers={"Metadata":"true"}).text)
|
||||
address, subnet= "", ""
|
||||
for interface in machine_metadata["network"]["interface"]:
|
||||
address, subnet = interface["ipv4"]["subnet"][0]["address"], interface["ipv4"]["subnet"][0]["prefix"]
|
||||
for ip in self.generate_subnet(address, sn=subnet):
|
||||
self.publish_event(NewHostEvent(host=ip))
|
||||
self.publish_event(AzureMetadataApi(cidr="{}/{}".format(address, subnet)))
|
||||
|
||||
# for normal scanning
|
||||
def scan_interfaces(self):
|
||||
|
||||
@@ -8,15 +8,15 @@ from kubelet import ExposedRunHandler
|
||||
from ...core.events import handler
|
||||
from ...core.events.types import Event, Vulnerability, KubernetesCluster
|
||||
from ...core.types import Hunter, ActiveHunter
|
||||
|
||||
class AzureSubscription(KubernetesCluster):
|
||||
"""Azure Metadata containes information about user/machines"""
|
||||
name = "Azure Metadata"
|
||||
|
||||
class Azure(KubernetesCluster):
|
||||
"""Azure Cluster"""
|
||||
name = "Azure"
|
||||
|
||||
class AzureSpnExposure(Vulnerability, Event):
|
||||
"""By exposing the SPN, the attacker can gain access to the azure subscription"""
|
||||
def __init__(self, container):
|
||||
Vulnerability.__init__(self, AzureSubscription, "Azure SPN Exposure")
|
||||
Vulnerability.__init__(self, Azure, "Azure SPN Exposure")
|
||||
self.container = container
|
||||
|
||||
@handler.subscribe(ExposedRunHandler)
|
||||
|
||||
@@ -197,19 +197,22 @@ class SecureKubeletPortHunter(Hunter):
|
||||
pod = self.get_self_pod() if config.pod else self.get_random_pod()
|
||||
debug_handlers = self.DebugHandlers(self.path, pod=pod, session=self.session)
|
||||
|
||||
if debug_handlers.test_container_logs():
|
||||
self.publish_event(ExposedContainerLogsHandler())
|
||||
if debug_handlers.test_exec_container():
|
||||
self.publish_event(ExposedExecHandler())
|
||||
if debug_handlers.test_run_container():
|
||||
self.publish_event(ExposedRunHandler())
|
||||
if debug_handlers.test_running_pods():
|
||||
self.publish_event(ExposedRunningPodsHandler())
|
||||
if debug_handlers.test_port_forward():
|
||||
self.publish_event(ExposedPortForwardHandler()) # not implemented
|
||||
if debug_handlers.test_attach_container():
|
||||
self.publish_event(ExposedAttachHandler())
|
||||
|
||||
try:
|
||||
if debug_handlers.test_container_logs():
|
||||
self.publish_event(ExposedContainerLogsHandler())
|
||||
if debug_handlers.test_exec_container():
|
||||
self.publish_event(ExposedExecHandler())
|
||||
if debug_handlers.test_run_container():
|
||||
self.publish_event(ExposedRunHandler())
|
||||
if debug_handlers.test_running_pods():
|
||||
self.publish_event(ExposedRunningPodsHandler())
|
||||
if debug_handlers.test_port_forward():
|
||||
self.publish_event(ExposedPortForwardHandler()) # not implemented
|
||||
if debug_handlers.test_attach_container():
|
||||
self.publish_event(ExposedAttachHandler())
|
||||
except Exception as ex:
|
||||
logging.debug(str(ex.message))
|
||||
|
||||
def get_self_pod(self):
|
||||
return {"name": "kube-hunter",
|
||||
"namespace": "default",
|
||||
|
||||
Reference in New Issue
Block a user