From c06b94f558dda58f6ad5199d718f5bddc05af644 Mon Sep 17 00:00:00 2001 From: Idan Revivo Date: Sun, 3 Mar 2019 18:53:35 +0200 Subject: [PATCH 1/3] moved CVE_2018_1002105 to generic cvehunter --- src/modules/hunting/{CVE_2018_1002105.py => cvehunter.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/modules/hunting/{CVE_2018_1002105.py => cvehunter.py} (100%) diff --git a/src/modules/hunting/CVE_2018_1002105.py b/src/modules/hunting/cvehunter.py similarity index 100% rename from src/modules/hunting/CVE_2018_1002105.py rename to src/modules/hunting/cvehunter.py From 1d258f7447e52d5e74d102c130ca081f77bd776c Mon Sep 17 00:00:00 2001 From: Idan Revivo Date: Sun, 3 Mar 2019 18:57:12 +0200 Subject: [PATCH 2/3] added support for new Vulnerability CVE-2019-1002100 --- src/core/types.py | 2 + src/modules/hunting/cvehunter.py | 105 ++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/src/core/types.py b/src/core/types.py index 9a404fd..0e13e64 100644 --- a/src/core/types.py +++ b/src/core/types.py @@ -48,5 +48,7 @@ class AccessRisk(object): class PrivilegeEscalation(KubernetesCluster): name = "Privilege Escalation" +class DenialOfService(object): + name = "Denial of Service" from events import handler # import is in the bottom to break import loops \ No newline at end of file diff --git a/src/modules/hunting/cvehunter.py b/src/modules/hunting/cvehunter.py index ae2b4b1..1f035f1 100644 --- a/src/modules/hunting/cvehunter.py +++ b/src/modules/hunting/cvehunter.py @@ -7,16 +7,28 @@ import ast from ...core.events import handler from ...core.events.types import Vulnerability, Event from ..discovery.apiserver import ApiServer -from ...core.types import Hunter, ActiveHunter, KubernetesCluster, RemoteCodeExec, AccessRisk, InformationDisclosure, PrivilegeEscalation +from ...core.types import Hunter, ActiveHunter, KubernetesCluster, RemoteCodeExec, AccessRisk, InformationDisclosure, \ + PrivilegeEscalation, DenialOfService """ Vulnerabilities """ -class ServerApiVersionEndPointAccess(Vulnerability, Event): - """ Node is vulnerable to critical CVE-2018-1002105 """ + + +class ServerApiVersionEndPointAccessPE(Vulnerability, Event): + """Node is vulnerable to critical CVE-2018-1002105""" def __init__(self, evidence): Vulnerability.__init__(self, KubernetesCluster, name="Critical Privilege Escalation CVE", category=PrivilegeEscalation) self.evidence = evidence + +class ServerApiVersionEndPointAccessDos(Vulnerability, Event): + """Node is vulnerable to critical CVE-2019-1002100""" + + def __init__(self, evidence): + Vulnerability.__init__(self, KubernetesCluster, name="Medium Denial of Service CVE", category=DenialOfService) + self.evidence = evidence + + # Passive Hunter @handler.subscribe(ApiServer) class IsVulnerableToCVEAttack(Hunter): @@ -30,29 +42,6 @@ class IsVulnerableToCVEAttack(Hunter): self.api_server_evidence = '' self.k8sVersion = '' - def access_api_server_version_end_point(self): - logging.debug(self.event.host) - logging.debug('Passive Hunter is attempting to access the API server /version end point using the pod\'s service account token') - try: - res = requests.get("{path}/version".format(path=self.path), - headers=self.headers, verify=False) - self.api_server_evidence = res.content - resDict = ast.literal_eval(res.content) - version = resDict["gitVersion"].split('.') - first_two_minor_digists = eval(version[1]) - last_two_minor_digists = eval(version[2]) - - if first_two_minor_digists == 10 and last_two_minor_digists < 11: - return True - elif first_two_minor_digists == 11 and last_two_minor_digists < 5: - return True - elif first_two_minor_digists == 12 and last_two_minor_digists < 3: - return True - elif first_two_minor_digists < 10: - return True - except (requests.exceptions.ConnectionError, KeyError): - return False - def get_service_account_token(self): logging.debug(self.event.host) logging.debug('Passive Hunter is attempting to access pod\'s service account token') @@ -65,8 +54,68 @@ class IsVulnerableToCVEAttack(Hunter): except IOError: # Couldn't read file return False + def get_api_server_version_end_point(self): + logging.debug(self.event.host) + logging.debug('Passive Hunter is attempting to access the API server version end point using the pod\'s service account token') + try: + res = requests.get("{path}/version".format(path=self.path), + headers=self.headers, verify=False) + self.api_server_evidence = res.content + resDict = ast.literal_eval(res.content) + version = resDict["gitVersion"].split('.') + first_two_minor_digits = eval(version[1]) + last_two_minor_digits = eval(version[2]) + return [first_two_minor_digits, last_two_minor_digits] + + except (requests.exceptions.ConnectionError, KeyError): + return None + + def check_cve_2018_1002105(self, api_version): + first_two_minor_digists = api_version[0] + last_two_minor_digists = api_version[1] + + if first_two_minor_digists == 10 and last_two_minor_digists < 11: + return True + elif first_two_minor_digists == 11 and last_two_minor_digists < 5: + return True + elif first_two_minor_digists == 12 and last_two_minor_digists < 3: + return True + elif first_two_minor_digists < 10: + return True + + return False + + def check_cve_2019_1002100(self, api_version): + """ + Kubernetes v1.0.x-1.10.x + Kubernetes v1.11.0-1.11.7 (fixed in v1.11.8) + Kubernetes v1.12.0-1.12.5 (fixed in v1.12.6) + Kubernetes v1.13.0-1.13.3 (fixed in v1.13.4) + """ + + first_two_minor_digists = api_version[0] + last_two_minor_digists = api_version[1] + + if first_two_minor_digists == 11 and last_two_minor_digists < 8: + return True + elif first_two_minor_digists == 12 and last_two_minor_digists < 6: + return True + elif first_two_minor_digists == 13 and last_two_minor_digists < 4: + return True + elif first_two_minor_digists < 11: + return True + + return False + def execute(self): self.get_service_account_token() # From within a Pod we may have extra credentials - if self.access_api_server_version_end_point(): - self.publish_event(ServerApiVersionEndPointAccess(self.api_server_evidence)) + api_version = self.get_api_server_version_end_point() + + if api_version: + if self.check_cve_2018_1002105(api_version): + self.publish_event(ServerApiVersionEndPointAccessPE(self.api_server_evidence)) + + elif self.check_cve_2019_1002100(api_version): + self.publish_event(ServerApiVersionEndPointAccessDos(self.api_server_evidence)) + From 5935e0ba96c988764ff70f969aa46805147d02db Mon Sep 17 00:00:00 2001 From: Idan Revivo Date: Mon, 4 Mar 2019 11:33:39 +0200 Subject: [PATCH 3/3] changed checking all cves --- src/modules/hunting/cvehunter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/hunting/cvehunter.py b/src/modules/hunting/cvehunter.py index 1f035f1..e862c1f 100644 --- a/src/modules/hunting/cvehunter.py +++ b/src/modules/hunting/cvehunter.py @@ -115,7 +115,7 @@ class IsVulnerableToCVEAttack(Hunter): if self.check_cve_2018_1002105(api_version): self.publish_event(ServerApiVersionEndPointAccessPE(self.api_server_evidence)) - elif self.check_cve_2019_1002100(api_version): + if self.check_cve_2019_1002100(api_version): self.publish_event(ServerApiVersionEndPointAccessDos(self.api_server_evidence))