Compare commits

..

2 Commits

Author SHA1 Message Date
Liz Rice
2882af39a6 docs: setuptools-scm is already covered
It's included in requirements-dev.txt. If we're not failing a CI build on this already, presumably it's not an omission in the regular requirements.txt
2020-04-30 14:09:39 +01:00
Liz Rice
3c59dd486f docs: add requirement for setup tools-scm
Also assume pip3
2020-04-29 16:01:18 +01:00
14 changed files with 16 additions and 161 deletions

View File

@@ -118,13 +118,15 @@ You can run kube-hunter directly on your machine.
You will need the following installed:
* python 3.x
* pip
* pip3
Note: These instructions assume `pip3` - please substitute with `pip` if that is the executable name on your system.
##### Install with pip
Install:
~~~
pip install kube-hunter
pip3 install kube-hunter
~~~
Run:
@@ -141,7 +143,7 @@ git clone https://github.com/aquasecurity/kube-hunter.git
Install module dependencies. (You may prefer to do this within a [Virtual Environment](https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/))
~~~
cd ./kube-hunter
pip install -r requirements.txt
pip3 install -r requirements.txt
~~~
Run:

View File

@@ -8,11 +8,7 @@ from kube_hunter.conf import Config, set_config
from kube_hunter.conf.parser import parse_args
from kube_hunter.conf.logging import setup_logger
from kube_hunter.plugins import initialize_plugin_manager
pm = initialize_plugin_manager()
# Using a plugin hook for adding arguments before parsing
args = parse_args(add_args_hook=pm.hook.parser_add_arguments)
args = parse_args()
config = Config(
active=args.active,
cidr=args.cidr,
@@ -28,9 +24,6 @@ config = Config(
setup_logger(args.log)
set_config(config)
# Running all other registered plugins before execution
pm.hook.load_plugin(args=args)
from kube_hunter.core.events import handler
from kube_hunter.core.events.types import HuntFinished, HuntStarted
from kube_hunter.modules.discovery.hosts import RunningAsPodEvent, HostScanEvent

View File

@@ -1,13 +1,9 @@
from argparse import ArgumentParser
from kube_hunter.plugins import hookimpl
@hookimpl
def parser_add_arguments(parser):
"""
This is the default hook implementation for parse_add_argument
Contains initialization for all default arguments
"""
def parse_args():
parser = ArgumentParser(description="kube-hunter - hunt for security weaknesses in Kubernetes clusters")
parser.add_argument(
"--list", action="store_true", help="Displays all tests in kubehunter (add --active flag to see active tests)",
)
@@ -63,18 +59,6 @@ def parser_add_arguments(parser):
parser.add_argument("--network-timeout", type=float, default=5.0, help="network operations timeout")
def parse_args(add_args_hook):
"""
Function handles all argument parsing
@param add_arguments: hook for adding arguments to it's given ArgumentParser parameter
@return: parsed arguments dict
"""
parser = ArgumentParser(description="kube-hunter - hunt for security weaknesses in Kubernetes clusters")
# adding all arguments to the parser
add_args_hook(parser=parser)
args = parser.parse_args()
if args.cidr:
args.cidr = args.cidr.replace(" ", "").split(",")

View File

@@ -148,7 +148,7 @@ class NewHostEvent(Event):
).json()
return result["cloud"] or "NoCloud"
except requests.ConnectionError:
logger.info("Failed to connect cloud type service", exc_info=True)
logger.info(f"Failed to connect cloud type service", exc_info=True)
except Exception:
logger.warning(f"Unable to check cloud of {self.host}", exc_info=True)
return "NoCloud"

View File

@@ -55,7 +55,7 @@ class ArpSpoofHunter(ActiveHunter):
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,
Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op=1, pdst=f"{self_ip}/24"), timeout=config.netork_timeout, verbose=0,
)
# arp enabled on cluster and more than one pod on node

View File

@@ -8,7 +8,7 @@ from kube_hunter.core.events import handler
from kube_hunter.core.events.types import Vulnerability, Event, Service
logger = logging.getLogger(__name__)
email_pattern = re.compile(rb"([a-z0-9]+@[a-z0-9]+\.[a-z0-9]+)")
email_pattern = re.compile(r"([a-z0-9]+@[a-z0-9]+\.[a-z0-9]+)")
class CertificateEmail(Vulnerability, Event):
@@ -39,11 +39,8 @@ class CertificateDiscovery(Hunter):
except ssl.SSLError:
# If the server doesn't offer SSL on this port we won't get a certificate
return
self.examine_certificate(cert)
def examine_certificate(self, cert):
c = cert.strip(ssl.PEM_HEADER).strip(ssl.PEM_FOOTER)
certdata = base64.b64decode(c)
certdata = base64.decodebytes(c)
emails = re.findall(email_pattern, certdata)
for email in emails:
self.publish_event(CertificateEmail(email=email))

View File

@@ -244,7 +244,7 @@ class SecureKubeletPortHunter(Hunter):
""" all methods will return the handler name if successful """
def __init__(self, path, pod, session=None):
self.path = path + '/' if not path.endswith('/') else ''
self.path = path
self.session = session if session else requests.Session()
self.pod = pod
@@ -349,7 +349,7 @@ class SecureKubeletPortHunter(Hunter):
# self.session.cert = self.event.client_cert
# copy session to event
self.event.session = self.session
self.path = f"https://{self.event.host}:10250"
self.path = "https://{self.event.host}:10250"
self.kubehunter_pod = {
"name": "kube-hunter",
"namespace": "default",
@@ -425,7 +425,7 @@ class SecureKubeletPortHunter(Hunter):
pod_data = next(filter(is_kubesystem_pod, pods_data), None)
if pod_data:
container_data = pod_data["spec"]["containers"][0]
container_data = next(pod_data["spec"]["containers"], None)
if container_data:
return {
"name": pod_data["metadata"]["name"],

View File

@@ -1,23 +0,0 @@
import pluggy
from kube_hunter.plugins import hookspecs
hookimpl = pluggy.HookimplMarker("kube-hunter")
def initialize_plugin_manager():
"""
Initializes and loads all default and setup implementations for registered plugins
@return: initialized plugin manager
"""
pm = pluggy.PluginManager("kube-hunter")
pm.add_hookspecs(hookspecs)
pm.load_setuptools_entrypoints("kube_hunter")
# default registration of builtin implemented plugins
from kube_hunter.conf import parser
pm.register(parser)
return pm

View File

@@ -1,24 +0,0 @@
import pluggy
from argparse import ArgumentParser
hookspec = pluggy.HookspecMarker("kube-hunter")
@hookspec
def parser_add_arguments(parser: ArgumentParser):
"""Add arguments to the ArgumentParser.
If a plugin requires an aditional argument, it should implement this hook
and add the argument to the Argument Parser
@param parser: an ArgumentParser, calls parser.add_argument on it
"""
@hookspec
def load_plugin(args):
"""Plugins that wish to execute code after the argument parsing
should implement this hook.
@param args: all parsed arguments passed to kube-hunter
"""

View File

@@ -14,4 +14,3 @@ black
pre-commit
flake8-bugbear
flake8-mypy
pluggy

View File

@@ -38,7 +38,6 @@ install_requires =
future
packaging
dataclasses
pluggy
setup_requires =
setuptools>=30.3.0
setuptools_scm

View File

@@ -1,42 +0,0 @@
# flake8: noqa: E402
from kube_hunter.conf import Config, set_config
set_config(Config())
from kube_hunter.core.events.types import Event
from kube_hunter.modules.hunting.certificates import CertificateDiscovery, CertificateEmail
from kube_hunter.core.events import handler
def test_CertificateDiscovery():
cert = """
-----BEGIN CERTIFICATE-----
MIIDZDCCAkwCCQCAzfCLqrJvuTANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExEDAOBgNVBAoMB05vZGUuanMxETAPBgNVBAsMCG5vZGUt
Z3lwMRIwEAYDVQQDDAlsb2NhbGhvc3QxHzAdBgkqhkiG9w0BCQEWEGJ1aWxkQG5v
ZGVqcy5vcmcwHhcNMTkwNjIyMDYyMjMzWhcNMjIwNDExMDYyMjMzWjB0MQswCQYD
VQQGEwJVUzELMAkGA1UECAwCQ0ExEDAOBgNVBAoMB05vZGUuanMxETAPBgNVBAsM
CG5vZGUtZ3lwMRIwEAYDVQQDDAlsb2NhbGhvc3QxHzAdBgkqhkiG9w0BCQEWEGJ1
aWxkQG5vZGVqcy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDS
CHjvtVW4HdbbUwZ/ZV9s6U4x0KSoyNQrsCZjB8kRpFPe50DS5mfmu2SNBGYKRgzk
4QEEwFB9N2o8YTWsCefSRl6ti4ToPZqulU4hhRKYrEGtMJcRzi3IN7s200JaO3UH
01Su8ruO0NESb5zEU1Ykfh8Lub8TGEAINmgI61d/5d5Aq3kDjUHQJt1Ekw03Ylnu
juQyCGZxLxnngu0mIvwzyL/UeeUgsfQLzvppUk6In7tC1zzMjSPWo0c8qu6KvrW4
bKYnkZkzdQifzbpO5ERMEsh5HWq0uHa6+dgcVHFvlhdqF4Uat87ygNplVf0txsZB
MNVqbz1k6xkZYMnzDoydAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADspZGtKpWxy
J1W3FA1aeQhMvequQTcMRz4avkm4K4HfTdV1iVD4CbvdezBphouBlyLVLDFJP7RZ
m7dBJVgBwnxufoFLne8cR2MGqDRoySbFT1AtDJdxabE6Fg+QGUpgOQfeBJ6ANlSB
+qJ+HG4QA+Ouh5hxz9mgYwkIsMUABHiwENdZ/kT8Edw4xKgd3uH0YP4iiePMD66c
rzW3uXH5J1jnKgBlpxtog4P6dHCcoq+PZJ17W5bdXNyqC1LPzQqniZ2BNcEZ4ix3
slAZAOWD1zLLGJhBPMV1fa0sHNBWc6oicr3YK/IDb0cp9kiLvnUu1pHy+LWQGqtC
rceJuGsnJEQ=
-----END CERTIFICATE-----
"""
c = CertificateDiscovery(Event())
c.examine_certificate(cert)
@handler.subscribe(CertificateEmail)
class test_CertificateEmail(object):
def __init__(self, event):
assert event.email == b"build@nodejs.org0"

View File

@@ -1,13 +0,0 @@
from kube_hunter.plugins import hookimpl
return_string = "return_string"
@hookimpl
def parser_add_arguments(parser):
return return_string
@hookimpl
def load_plugin(args):
return return_string

View File

@@ -1,17 +0,0 @@
from argparse import ArgumentParser
from tests.plugins import test_hooks
from kube_hunter.plugins import initialize_plugin_manager
def test_all_plugin_hooks():
pm = initialize_plugin_manager()
pm.register(test_hooks)
# Testing parser_add_arguments
parser = ArgumentParser("Test Argument Parser")
results = pm.hook.parser_add_arguments(parser=parser)
assert test_hooks.return_string in results
# Testing load_plugin
results = pm.hook.load_plugin(args=[])
assert test_hooks.return_string in results