Fixed the PR comments :-)

This commit is contained in:
ori.agmon
2018-10-08 17:18:19 +03:00
parent 4573fe4089
commit 19c10fd8e9
3 changed files with 35 additions and 33 deletions

View File

@@ -50,7 +50,7 @@ class EventQueue(Queue, object):
else:
self.active_hunters[hook] = hook.__doc__
elif Hunter in hook.__mro__:
self.passive_hunters[hook] = hook.__doc__
self.passive_hunters[hook] = hook.__doc__
if hook not in self.hooks[event]:
self.hooks[event].append((hook, predicate))
@@ -92,4 +92,4 @@ class EventQueue(Queue, object):
with self.mutex:
self.queue.clear()
handler = EventQueue(800)
handler = EventQueue(800)

View File

@@ -7,11 +7,9 @@ from ...core.events import handler
from ...core.events.types import Event, OpenPortEvent, Service
from ...core.types import Hunter
"""Etcd is a DB that stores cluster's data,
it contains configuration and current state information, and might contain secrets"""
#services:
# Service:
class etcdAccessEvent(Service, Event):
class EtcdAccessEvent(Service, Event):
"""Etcd is a DB that stores cluster's data, it contains configuration and current state information, and might contain secrets"""
def __init__(self):
Service.__init__(self, name="Etcd")
@@ -19,7 +17,7 @@ class etcdAccessEvent(Service, Event):
@handler.subscribe(OpenPortEvent, predicate= lambda p: p.port == 2379)
class etcdRemoteAccess(Hunter):
class EtcdRemoteAccess(Hunter):
"""Etcd Remote Access
Checks for remote availability of etcd, version, read access, write access
"""
@@ -28,7 +26,7 @@ class etcdRemoteAccess(Hunter):
def execute(self):
try:
self.publish_event(etcdAccessEvent())
self.publish_event(EtcdAccessEvent())
except Exception as e:
import traceback
traceback.print_exc()

View File

@@ -39,61 +39,63 @@ def helperDoRequest(req, is_verify, data=None, req_type="get"):
""" Vulnerabilities """
class etcdRemoteWriteAccessEvent(Vulnerability, Event):
class EtcdRemoteWriteAccessEvent(Vulnerability, Event):
"""Remote write access might grant an attacker full control over the kubernetes cluster"""
def __init__(self):
def __init__(self, write_res):
Vulnerability.__init__(self, KubernetesCluster, name="Etcd Remote Write Access Event", category=RemoteCodeExec)
self.evidence = write_res
class etcdRemoteReadAccessEvent(Vulnerability, Event):
class EtcdRemoteReadAccessEvent(Vulnerability, Event):
"""Remote read access might expose to an attacker cluster's possible exploits, secrets and more."""
def __init__(self, keys):
Vulnerability.__init__(self, KubernetesCluster, name="Etcd Remote Read Access Event", category=AccessRisk)
self.evidence = keys
class etcdRemoteVersionDisclosureEvent(Vulnerability, Event):
class EtcdRemoteVersionDisclosureEvent(Vulnerability, Event):
"""Remote version disclosure might give an attacker a valuable data to attack a cluster"""
def __init__(self, version):
Vulnerability.__init__(self, KubernetesCluster, name="Etcd Remote version disclosure", category=AccessRisk)
Vulnerability.__init__(self, KubernetesCluster, name="Etcd Remote version disclosure", category=InformationDisclosure)
self.evidence = version
class etcdAccessEnabledWithoutAuthEvent(Vulnerability, Event):
class EtcdAccessEnabledWithoutAuthEvent(Vulnerability, Event):
"""Etcd is accessible without authorization, it would allow a potential attacker to gain access to the etcd"""
def __init__(self, version):
Vulnerability.__init__(self, KubernetesCluster, name="Etcd is accessible without authorization", category=UnauthenticatedAccess)
self.evidence = version
@handler.subscribe(OpenPortEvent, predicate= lambda p: p.port == 2379)
class etcdRemoteAccessActive(ActiveHunter):
# Active Hunter
@handler.subscribe(OpenPortEvent, predicate=lambda p: p.port == 2379)
class EtcdRemoteAccessActive(ActiveHunter):
"""Checks for remote write access to etcd"""
def __init__(self, event):
self.event = event
self.write_evidence = ''
def db_keys_write_access(self):
logging.debug(self.event.host)
logging.debug("Active hunter is attempting to write keys remotely")
logging.debug("Active hunter is attempting to write keys remotely on host " + self.event.host)
data = {
'value': 'remote write access penetration'
'value': 'remotely written data'
}
r_secure = "https://{host}:{port}/v2/keys/message".format(host=self.event.host, port=2379)
r_not_secure = "https://{host}:{port}/v2/keys/message".format(host=self.event.host, port=2379)
r_not_secure = "http://{host}:{port}/v2/keys/message".format(host=self.event.host, port=2379)
res = helperFuncDo2Requests(r_secure, r_not_secure)
if res:
self.publish_event(etcdRemoteWriteAccessEvent())
self.write_evidence = res.content
return True
return False
def execute(self):
self.db_keys_write_access()
if self.db_keys_write_access():
self.publish_event(EtcdRemoteWriteAccessEvent(self.write_evidence))
# Passive Hunter
@handler.subscribe(OpenPortEvent, predicate=lambda p: p.port == 2379)
class etcdRemoteAccess(Hunter):
class EtcdRemoteAccess(Hunter):
"""Etcd Remote Access
Checks for remote availability of etcd, version, read access, write access
"""
@@ -101,6 +103,8 @@ class etcdRemoteAccess(Hunter):
# Check the etcd hunter on a remote cluster! (currently everything was checked only at 127.0.0.1:2379)
def __init__(self, event):
self.event = event
self.version_evidence = ''
self.keys_evidence = ''
def db_keys_disclosure(self):
logging.debug(self.event.host)
@@ -109,7 +113,7 @@ class etcdRemoteAccess(Hunter):
r_not_secure = "http://{host}:{port}/v2/keys".format(host=self.event.host, port=2379)
res = helperFuncDo2Requests(r_secure, r_not_secure)
if res:
self.publish_event(etcdRemoteReadAccessEvent(res.content))
self.keys_evidence = res.content
return True
return False
@@ -120,8 +124,7 @@ class etcdRemoteAccess(Hunter):
r_not_secure = "http://{host}:{port}/version".format(host=self.event.host, port=2379)
res = helperFuncDo2Requests(r_secure, r_not_secure)
if res:
self.no_auth_evidence = res.content
self.publish_event(etcdRemoteVersionDisclosureEvent(res.content))
self.version_evidence = res.content
return True
return False
@@ -129,14 +132,15 @@ class etcdRemoteAccess(Hunter):
logging.debug(self.event.host)
logging.debug("Passive hunter is attempting to access etcd without authorization")
r_not_secure = "http://{host}:{port}/version".format(host=self.event.host, port=2379)
res = helperFuncDo2Requests(r_not_secure, r_not_secure)# We dont have to do 2 requests this time
res = helperFuncDo2Requests(r_not_secure, r_not_secure) # We don't have to do 2 requests this time
if res:
self.publish_event(etcdAccessEnabledWithoutAuthEvent(res.content))
return True
return False
def execute(self):
if self.version_disclosure():
self.unauthorized_access()
self.db_keys_disclosure()
self.db_keys_write_access()
self.publish_event(EtcdRemoteVersionDisclosureEvent(self.version_evidence))
if self.unauthorized_access():
self.publish_event(EtcdAccessEnabledWithoutAuthEvent(self.version_evidence))
if self.db_keys_disclosure():
self.publish_event(EtcdRemoteReadAccessEvent(self.keys_evidence))