diff --git a/kube_hunter/console/__init__.py b/kube_hunter/console/__init__.py index 564019a..f8b569a 100644 --- a/kube_hunter/console/__init__.py +++ b/kube_hunter/console/__init__.py @@ -1,4 +1,5 @@ from . import manager from . import env from . import models -from . import discover \ No newline at end of file +from . import discover +from . import show \ No newline at end of file diff --git a/kube_hunter/console/discover.py b/kube_hunter/console/discover.py index f16e8e0..5c435e4 100644 --- a/kube_hunter/console/discover.py +++ b/kube_hunter/console/discover.py @@ -8,14 +8,8 @@ class DiscoverSubConsole(cmd.Cmd): prompt = environment.get_prompt(sub_console="discover") def do_local(self, arg): - """Try to determine where we are based on local files and mounts""" # pod discovery - pod_event = RunningAsPodEvent() - if pod_event.auth_token: - logging.info("Running as a pod in a kuberentes cluster") - environment.current_pod.incluster_update(pod_event) - environment.is_inside_pod = True - + pass def do_exit(self, arg): diff --git a/kube_hunter/console/manager.py b/kube_hunter/console/manager.py index 2f32868..f22e4c2 100644 --- a/kube_hunter/console/manager.py +++ b/kube_hunter/console/manager.py @@ -1,7 +1,12 @@ import cmd +import logging from kube_hunter.console.env import environment from kube_hunter.console.discover import DiscoverSubConsole +from kube_hunter.console.show import ShowSubConsole + +from kube_hunter.modules.discovery.hosts import RunningAsPodEvent + def start_console(): KubeHunterMainConsole().cmdloop() @@ -19,30 +24,43 @@ class KubeHunterMainConsole(cmd.Cmd): intro = f'{kube_hunter_logo}\n\nWelcome to kube-hunter Immeresed Console. Type help or ? to list commands.\n' prompt = environment.get_prompt() + discover_cmd = DiscoverSubConsole() + show_cmd = ShowSubConsole() + + def do_show(self, arg): + 'Show your environment data collected so far' + self.show_cmd.cmdloop() + def do_discover(self, arg): 'Depends on your environment, lets you discover nearby Services/Pods/Clusters' - discover_cmd = DiscoverSubConsole() - discover_cmd.cmdloop() + self.discover_cmd.cmdloop() def do_hunt(self, arg): 'Depends on your environment, lets you hunt nearby Services/Pods/Clusters' - discover_cmd = DiscoverSubConsole() - discover_cmd.cmdloop() - - def do_show(self, arg): pass + + def do_interactive(self, arg): + import ipdb + ipdb.set_trace() + + def do_whereami(self, arg): + """Try to determine you are based on local files and mounts""" + pod_event = RunningAsPodEvent() + if pod_event.auth_token: + environment.current_pod.incluster_update(pod_event) + environment.current_auth.new_auth(pod_event.auth_token) + environment.is_inside_pod = True def postcmd(self, stop, line): self.prompt = environment.get_prompt() - # def do_help(self, arg): - # if not arg: - # pass - def do_exit(self, arg): 'exists shell' return True - + + def emptyline(self): + pass + # binds EOF to exit the shell as well do_EOF = do_exit diff --git a/kube_hunter/console/models.py b/kube_hunter/console/models.py index aeb3e0c..88af049 100644 --- a/kube_hunter/console/models.py +++ b/kube_hunter/console/models.py @@ -1,4 +1,8 @@ +import json import socket +import base64 + +from prettytable import ALL, PrettyTable """ Models for console """ @@ -42,8 +46,68 @@ class UnknownCloud(Cloud): """ Auth models""" class Auth: - token = "" + def parse_token(self, token): + """ Extracting data from token file """ + # adding maximum base64 padding to parse correctly + self.raw_token = token + token_json = base64.b64decode(f"{token.split('.')[1]}==") + token_data = json.loads(token_json) + + self.iss = token_data.get("iss") + self.namespace = token_data.get("kubernetes.io/serviceaccount/namespace") + self.name = token_data.get("kubernetes.io/serviceaccount/secret.name") + self.name = token_data.get("kubernetes.io/serviceaccount/service-account.name") + self.uid = token_data.get("kubernetes.io/serviceaccount/service-account.uid") + self.sub = token_data.get("sub") + + def __init__(self, token=None): + if token: + self.parse_token(token) class AuthStore: auths = [] - selected_auth = None \ No newline at end of file + selected_auth = None + + def new_auth(self, token): + """ Initializes new Auth object and adds it to the auth db """ + new_auth = Auth(token) + + if not self.is_exists(new_auth): + self.auths.append(new_auth) + + # if it's the only auth, selecting it + if not self.selected_auth: + self.selected_auth = 0 + + def is_exists(self, check_auth): + """ Checks for uniques auth in auth_store """ + for auth in self.auths: + if auth.sub == check_auth.sub: + return True + return False + + def get_current_auth(self): + auths[selected_auth] + + def get_auth(self, index): + return self.auths[index] + + def __repr__(self): + auth_table = PrettyTable(["index", "Name", "Selected"], hrules=ALL) + auth_table.align = "l" + auth_table.padding_width = 1 + auth_table.header_style = "upper" + + # building auth token table, showing selected auths + for i, auth in enumerate(self.auths): + selected_mark = "" + if i == self.selected_auth: + selected_mark = "*" + auth_table.add_row([i, auth.sub, selected_mark]) + + return auth_table + + + + + diff --git a/kube_hunter/console/show.py b/kube_hunter/console/show.py new file mode 100644 index 0000000..897fb9e --- /dev/null +++ b/kube_hunter/console/show.py @@ -0,0 +1,34 @@ +import cmd +import logging + +from kube_hunter.console.env import environment + +class ShowSubConsole(cmd.Cmd): + prompt = environment.get_prompt(sub_console="show") + + def do_auth(self, auth_index): + """Displays the auth database, to show raw data of an auth entry pass it's index as a parameter.""" + if auth_index: + try: + auth_index = int(auth_index) + except: + print("ERROR: Auth index should be a number") + return + + print(environment.current_auth.get_auth(auth_index).raw_token) + else: + print(environment.current_auth.__repr__()) + + def do_exit(self, arg): + return True + + def postcmd(self, stop, line): + self.prompt = environment.get_prompt(sub_console="show") + if stop: + return True + + def emptyline(self): + pass + + # binds EOF to exit the shell as well + do_EOF = do_exit \ No newline at end of file