Compare commits

...

6 Commits

Author SHA1 Message Date
“Amir
d36cd1e631 Added severity to the kube-hunter found issues 2022-03-18 17:54:17 +02:00
danielsagi
7c62cc21af Feature: Custom Hunting (#489)
* added partial and partial-names flag. mechanism for whitelisting hunter subscrption for custom hunts

* changed name from partial to custom

* ran black to format

* flake8 formatting

* added documentation in readme for Custom hunting and made Advanced Usage a higher level topic

* added Collector, StartedInfo and SendFullReport to the core_hunters

* changed old name class-names to raw-hunter-names

* fixed bug in import loop
2022-01-28 18:54:36 +02:00
Juvenile
c17aa17096 ignore https certificate verification (#484) 2022-01-22 16:06:39 +02:00
testn
4204879251 Update README.md (#487)
Fix typo
2022-01-22 16:05:20 +02:00
danielsagi
a746bd0eb1 Added correct exception handling for discovery of Metadata apis (#488)
* Added correct exception handling for discovery of Metadata apis

* fixed linting issues
2022-01-22 15:56:04 +02:00
danielsagi
b379e64314 Added MITRE documentation in README (#485)
* Added documentation about differences between vulnerabilities and the attack matrix techniques

* moved docs to start of README, also created MITRE image, showing covered areas of kube-hunter

* fixed link in readme
2022-01-14 00:00:29 +02:00
46 changed files with 174 additions and 20 deletions

BIN
MITRE.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@@ -18,7 +18,8 @@ kube-hunter hunts for security weaknesses in Kubernetes clusters. The tool was d
**Run kube-hunter**: kube-hunter is available as a container (aquasec/kube-hunter), and we also offer a web site at [kube-hunter.aquasec.com](https://kube-hunter.aquasec.com) where you can register online to receive a token allowing you to see and share the results online. You can also run the Python code yourself as described below.
**Explore vulnerabilities**: The kube-hunter knowledge base includes articles about discoverable vulnerabilities and issues. When kube-hunter reports an issue, it will show its VID (Vulnerability ID) so you can look it up in the KB at https://aquasecurity.github.io/kube-hunter/
**Explore vulnerabilities**: The kube-hunter knowledge base includes articles about discoverable vulnerabilities and issues. When kube-hunter reports an issue, it will show its VID (Vulnerability ID) so you can look it up in the KB at https://aquasecurity.github.io/kube-hunter/
_If you're interested in kube-hunter's integration with the Kubernetes ATT&CK Matrix [Continue Reading](#kuberentes-attck-matrix)_
**Contribute**: We welcome contributions, especially new hunter modules that perform additional tests. If you would like to develop your modules please read [Guidelines For Developing Your First kube-hunter Module](https://github.com/aquasecurity/kube-hunter/blob/main/CONTRIBUTING.md).
@@ -28,6 +29,7 @@ Table of Contents
=================
- [Table of Contents](#table-of-contents)
- [Kubernetes ATT&CK Matrix](#kubernetes-attck-matrix)
- [Hunting](#hunting)
- [Where should I run kube-hunter?](#where-should-i-run-kube-hunter)
- [Scanning options](#scanning-options)
@@ -37,8 +39,9 @@ Table of Contents
- [Nodes Mapping](#nodes-mapping)
- [Output](#output)
- [Dispatching](#dispatching)
- [Advanced Usage](#advanced-usage)
- [Azure Quick Scanning](#azure-quick-scanning)
- [Advanced Usage](#advanced-usage)
- [Azure Quick Scanning](#azure-quick-scanning)
- [Custom Hunting](#custom-hunting)
- [Deployment](#deployment)
- [On Machine](#on-machine)
- [Prerequisites](#prerequisites)
@@ -48,9 +51,21 @@ Table of Contents
- [Pod](#pod)
- [Contribution](#contribution)
- [License](#license)
## Hunting
---
## Kubernetes ATT&CK Matrix
kube-hunter now supports the new format of the Kubernetes ATT&CK matrix.
While kube-hunter's vulnerabilities are a collection of creative techniques designed to mimic an attacker in the cluster (or outside it)
The Mitre's ATT&CK defines a more general standardised categories of techniques to do so.
You can think of kube-hunter vulnerabilities as small steps for an attacker, which follows the track of a more general technique he would aim for.
Most of kube-hunter's hunters and vulnerabilities can closly fall under those techniques, That's why we moved to follow the Matrix standard.
_Some kube-hunter vulnerabities which we could not map to Mitre technique, are prefixed with the `General` keyword_
![kube-hunter](./MITRE.png)
## Hunting
### Where should I run kube-hunter?
There are three different ways to run kube-hunter, each providing a different approach to detecting weaknesses in your cluster:
@@ -61,6 +76,7 @@ You can run kube-hunter directly on a machine in the cluster, and select the opt
You can also run kube-hunter in a pod within the cluster. This indicates how exposed your cluster would be if one of your application pods is compromised (through a software vulnerability, for example). (_`--pod` flag_)
### Scanning options
First check for these **[pre-requisites](#prerequisites)**.
@@ -141,11 +157,49 @@ Available dispatch methods are:
* KUBEHUNTER_HTTP_DISPATCH_URL (defaults to: https://localhost)
* KUBEHUNTER_HTTP_DISPATCH_METHOD (defaults to: POST)
### Advanced Usage
#### Azure Quick Scanning
## Advanced Usage
### Azure Quick Scanning
When running **as a Pod in an Azure or AWS environment**, kube-hunter will fetch subnets from the Instance Metadata Service. Naturally this makes the discovery process take longer.
To hardlimit subnet scanning to a `/24` CIDR, use the `--quick` option.
### Custom Hunting
Custom hunting enables advanced users to have control over what hunters gets registered at the start of a hunt.
**If you know what you are doing**, this can help if you want to adjust kube-hunter's hunting and discovery process for your needs.
Example:
```
kube-hunter --custom <HunterName1> <HunterName2>
```
Enabling Custom hunting removes all hunters from the hunting process, except the given whitelisted hunters.
The `--custom` flag reads a list of hunters class names, in order to view all of kube-hunter's class names, you can combine the flag `--raw-hunter-names` with the `--list` flag.
Example:
```
kube-hunter --active --list --raw-hunter-names
```
**Notice**: Due to kube-huner's architectural design, the following "Core Hunters/Classes" will always register (even when using custom hunting):
* HostDiscovery
* _Generates ip addresses for the hunt by given configurations_
* _Automatically discovers subnets using cloud Metadata APIs_
* FromPodHostDiscovery
* _Auto discover attack surface ip addresses for the hunt by using Pod based environment techniques_
* _Automatically discovers subnets using cloud Metadata APIs_
* PortDiscovery
* _Port scanning given ip addresses for known kubernetes services ports_
* Collector
* _Collects discovered vulnerabilities and open services for future report_
* StartedInfo
* _Prints the start message_
* SendFullReport
* _Dispatching the report based on given configurations_
## Deployment
There are three methods for deploying kube-hunter:

View File

@@ -2,6 +2,7 @@
vid: KHV002
title: Kubernetes version disclosure
categories: [Information Disclosure]
severity: LOW
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV003
title: Azure Metadata Exposure
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV004
title: Azure SPN Exposure
categories: [Identity Theft]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV005
title: Access to Kubernetes API
categories: [Information Disclosure, Unauthenticated Access]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV006
title: Insecure (HTTP) access to Kubernetes API
categories: [Unauthenticated Access]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV007
title: Specific Access to Kubernetes API
categories: [Access Risk]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV020
title: Possible Arp Spoof
categories: [IdentityTheft]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV021
title: Certificate Includes Email Address
categories: [Information Disclosure]
severity: LOW
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV022
title: Critical Privilege Escalation CVE
categories: [Privilege Escalation]
severity: CRITICAL
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV023
title: Denial of Service to Kubernetes API Server
categories: [Denial Of Service]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV024
title: Possible Ping Flood Attack
categories: [Denial Of Service]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV025
title: Possible Reset Flood Attack
categories: [Denial Of Service]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV026
title: Arbitrary Access To Cluster Scoped Resources
categories: [PrivilegeEscalation]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV027
title: Kubectl Vulnerable To CVE-2019-11246
categories: [Remote Code Execution]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV028
title: Kubectl Vulnerable To CVE-2019-1002101
categories: [Remote Code Execution]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV029
title: Dashboard Exposed
categories: [Remote Code Execution]
severity: CRITICAL
---
# {{ page.vid }} - {{ page.title }}
@@ -12,4 +13,5 @@ An open Kubernetes Dashboard was detected. The Kubernetes Dashboard can be used
## Remediation
Do not leave the Dashboard insecured.
Do not leave the Dashboard insecured.

View File

@@ -2,6 +2,7 @@
vid: KHV030
title: Possible DNS Spoof
categories: [Identity Theft]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV031
title: Etcd Remote Write Access Event
categories: [Remote Code Execution]
severity: CRITICAL
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV032
title: Etcd Remote Read Access Event
categories: [Access Risk]
severity: CRITICAL
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV033
title: Etcd Remote version disclosure
categories: [Information Disclosure]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV034
title: Etcd is accessible using insecure connection (HTTP)
categories: [Unauthenticated Access]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV036
title: Anonymous Authentication
categories: [Remote Code Execution]
severity: CRITICAL
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV037
title: Exposed Container Logs
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV038
title: Exposed Running Pods
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV039
title: Exposed Exec On Container
categories: [Remote Code Execution]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV040
title: Exposed Run Inside Container
categories: [Remote Code Execution]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV041
title: Exposed Port Forward
categories: [Remote Code Execution]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV042
title: Exposed Attaching To Container
categories: [Remote Code Execution]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV043
title: Cluster Health Disclosure
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV044
title: Privileged Container
categories: [Access Risk]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV045
title: Exposed System Logs
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV046
title: Exposed Kubelet Cmdline
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV047
title: Pod With Mount To /var/log
categories: [Privilege Escalation]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV049
title: kubectl proxy Exposed
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV050
title: Read access to Pod service account token
categories: [Access Risk]
severity: MEDIUM
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV051
title: Exposed Existing Privileged Containers Via Secure Kubelet Port
categories: [Access Risk]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV052
title: Exposed Pods
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -2,6 +2,7 @@
vid: KHV053
title: AWS Metadata Exposure
categories: [Information Disclosure]
severity: HIGH
---
# {{ page.vid }} - {{ page.title }}

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python3
# flake8: noqa: E402
from functools import partial
import logging
import threading
@@ -29,6 +30,7 @@ config = Config(
service_account_token=args.service_account_token,
kubeconfig=args.kubeconfig,
enable_cve_hunting=args.enable_cve_hunting,
custom=args.custom,
)
setup_logger(args.log, args.log_file)
set_config(config)
@@ -73,16 +75,20 @@ def interactive_set_config():
return True
def list_hunters():
def list_hunters(class_names=False):
print("\nPassive Hunters:\n----------------")
for hunter, docs in handler.passive_hunters.items():
name, doc = hunter.parse_docs(docs)
if class_names:
name = hunter.__name__
print(f"* {name}\n {doc}\n")
if config.active:
print("\n\nActive Hunters:\n---------------")
for hunter, docs in handler.active_hunters.items():
name, doc = hunter.parse_docs(docs)
if class_names:
name = hunter.__name__
print(f"* {name}\n {doc}\n")
@@ -95,7 +101,10 @@ def main():
scan_options = [config.pod, config.cidr, config.remote, config.interface, config.k8s_auto_discover_nodes]
try:
if args.list:
list_hunters()
if args.raw_hunter_names:
list_hunters(class_names=True)
else:
list_hunters()
return
if not any(scan_options):

View File

@@ -1,7 +1,11 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import Any, Optional
def get_default_core_hunters():
return ["FromPodHostDiscovery", "HostDiscovery", "PortDiscovery", "SendFullReport", "Collector", "StartedInfo"]
@dataclass
class Config:
"""Config is a configuration container.
@@ -41,6 +45,9 @@ class Config:
service_account_token: Optional[str] = None
kubeconfig: Optional[str] = None
enable_cve_hunting: bool = False
custom: Optional[list] = None
raw_hunter_names: bool = False
core_hunters: list = field(default_factory=get_default_core_hunters)
_config: Optional[Config] = None

View File

@@ -46,6 +46,22 @@ def parser_add_arguments(parser):
help="One or more remote ip/dns to hunt",
)
parser.add_argument(
"-c",
"--custom",
nargs="+",
metavar="HUNTERS",
default=list(),
help="Custom hunting. Only given hunter names will register in the hunt."
"for a list of options run `--list --raw-hunter-names`",
)
parser.add_argument(
"--raw-hunter-names",
action="store_true",
help="Use in combination with `--list` to display hunter class names to pass for custom hunting flag",
)
parser.add_argument(
"--k8s-auto-discover-nodes",
action="store_true",

View File

@@ -257,9 +257,33 @@ class EventQueue(Queue):
self.hooks[event].append((hook, predicate))
logging.debug("{} subscribed to {}".format(hook, event))
def allowed_for_custom_registration(self, target_hunter):
"""
Check if the partial input list contains the hunter we are about to register for events
If hunter is considered a Core hunter as specified in `config.core_hunters` we allow it anyway
Returns true if:
1. partial hunt is disabled
2. partial hunt is enabled and hunter is in core hunter class
3. partial hunt is enabled and hunter is specified in config.partial
@param target_hunter: hunter class for registration check
"""
config = get_config()
if not config.custom:
return True
hunter_class_name = target_hunter.__name__
if hunter_class_name in config.core_hunters or hunter_class_name in config.custom:
return True
return False
def subscribe_event(self, event, hook=None, predicate=None, is_register=True):
if not is_register:
return
if not self.allowed_for_custom_registration(hook):
return
if not self._register_hunters(hook):
return
@@ -272,9 +296,11 @@ class EventQueue(Queue):
def subscribe_events(self, events, hook=None, predicates=None, is_register=True):
if not is_register:
return False
return
if not self.allowed_for_custom_registration(hook):
return
if not self._register_hunters(hook):
return False
return
if predicates is None:
predicates = [None] * len(events)

View File

@@ -166,7 +166,9 @@ class FromPodHostDiscovery(Discovery):
return True
except requests.exceptions.ConnectionError:
logger.debug("Failed to connect AWS metadata server v1")
return False
except Exception:
logger.debug("Unknown error when trying to connect to AWS metadata v1 API")
return False
def is_aws_pod_v2(self):
config = get_config()
@@ -189,7 +191,9 @@ class FromPodHostDiscovery(Discovery):
return True
except requests.exceptions.ConnectionError:
logger.debug("Failed to connect AWS metadata server v2")
return False
except Exception:
logger.debug("Unknown error when trying to connect to AWS metadata v2 API")
return False
def is_azure_pod(self):
config = get_config()
@@ -206,7 +210,9 @@ class FromPodHostDiscovery(Discovery):
return True
except requests.exceptions.ConnectionError:
logger.debug("Failed to connect Azure metadata server")
return False
except Exception:
logger.debug("Unknown error when trying to connect to Azure metadata server")
return False
# for pod scanning
def gateway_discovery(self):

View File

@@ -12,10 +12,7 @@ class HTTPDispatcher:
dispatch_url = os.environ.get("KUBEHUNTER_HTTP_DISPATCH_URL", "https://localhost/")
try:
r = requests.request(
dispatch_method,
dispatch_url,
json=report,
headers={"Content-Type": "application/json"},
dispatch_method, dispatch_url, json=report, headers={"Content-Type": "application/json"}, verify=False
)
r.raise_for_status()
logger.info(f"Report was dispatched to: {dispatch_url}")