From 0a68249a0c355ae3df66836c2018b354ae873820 Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 12:28:54 -0400 Subject: [PATCH 01/13] add command to display history --- pacu/main.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pacu/main.py b/pacu/main.py index c122835c..188324a8 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -126,6 +126,7 @@ def display_pacu_help(): swap_session Change the active Pacu session to another one in the database delete_session Delete a Pacu session from the database. Note that the output folder for that session will not be deleted + history List the previously typed commands exit/quit Exit Pacu @@ -179,7 +180,7 @@ class Main: 'aws', 'data', 'exec', 'exit', 'help', 'import_keys', 'assume_role', 'list', 'load_commands_file', 'ls', 'quit', 'regions', 'run', 'search', 'services', 'set_keys', 'set_regions', 'swap_keys', 'update_regions', 'set_ua_suffix', 'unset_ua_suffix', 'whoami', 'swap_session', 'sessions', - 'list_sessions', 'delete_session', 'export_keys', 'open_console', 'console' + 'list_sessions', 'delete_session', 'export_keys', 'open_console', 'console', 'history' ] def __init__(self): @@ -366,6 +367,12 @@ def get_regions(self, service, check_session=True) -> List[Optional[str]]: else: return valid_regions + def display_history(self): + # https://stackoverflow.com/a/7008316 + import readline + for i in range(readline.get_current_history_length()): + print("{0:>3}: {}".format(i,readline.get_history_item(i + 1)) + def display_all_regions(self): for region in sorted(self.get_regions('all')): print(' {}'.format(region)) @@ -595,6 +602,8 @@ def parse_command(self, command): self.parse_commands_from_file(command) elif command[0] == 'regions': self.display_all_regions() + elif command[0] == 'history': + self.display_history() elif command[0] == 'run' or command[0] == 'exec': self.print_user_agent_suffix() self.parse_exec_module_command(command) @@ -780,7 +789,7 @@ def parse_list_command(self, command): elif len(command) == 3: if command[1] in ('cat', 'category'): self.list_modules(command[2], by_category=True) - + def parse_exec_module_command(self, command: List[str]) -> None: if len(command) > 1: self.exec_module(command) From a2efe6efa3bed78324ac5c85ec4c2a92af467332 Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 12:30:29 -0400 Subject: [PATCH 02/13] Update main.py --- pacu/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pacu/main.py b/pacu/main.py index 188324a8..80949be8 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -371,7 +371,7 @@ def display_history(self): # https://stackoverflow.com/a/7008316 import readline for i in range(readline.get_current_history_length()): - print("{0:>3}: {}".format(i,readline.get_history_item(i + 1)) + print("{0:>3}: {}".format(i,readline.get_history_item(i + 1))) def display_all_regions(self): for region in sorted(self.get_regions('all')): From f57564e53b6003972e864e9b7d9e18fa405bad22 Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 12:32:02 -0400 Subject: [PATCH 03/13] Update main.py --- pacu/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pacu/main.py b/pacu/main.py index 80949be8..b48b086b 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -371,7 +371,7 @@ def display_history(self): # https://stackoverflow.com/a/7008316 import readline for i in range(readline.get_current_history_length()): - print("{0:>3}: {}".format(i,readline.get_history_item(i + 1))) + print("{:>3}: {}".format(i,readline.get_history_item(i + 1))) def display_all_regions(self): for region in sorted(self.get_regions('all')): From 71ef108f297da95077785028a4ae0f34f3fbb95f Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 12:36:23 -0400 Subject: [PATCH 04/13] implement history command --- pacu/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pacu/main.py b/pacu/main.py index b48b086b..13dd22e7 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -371,7 +371,7 @@ def display_history(self): # https://stackoverflow.com/a/7008316 import readline for i in range(readline.get_current_history_length()): - print("{:>3}: {}".format(i,readline.get_history_item(i + 1))) + print("{:>3}: {}".format(i+1, readline.get_history_item(i + 1))) def display_all_regions(self): for region in sorted(self.get_regions('all')): From 5f7bc935086bfb67312570a2b119b0d4c938e6b5 Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 12:54:13 -0400 Subject: [PATCH 05/13] save and load command history --- pacu/main.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pacu/main.py b/pacu/main.py index 13dd22e7..b7322a81 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -5,6 +5,7 @@ import os import random import re +import readline import shlex import subprocess import sys @@ -16,7 +17,7 @@ from typing import List, Optional, Any, Dict, Union, Tuple from pacu.core import lib -from pacu.core.lib import session_dir +from pacu.core.lib import session_dir, home_dir try: import jq # type: ignore @@ -42,6 +43,9 @@ print('Refer to https://github.com/RhinoSecurityLabs/pacu/wiki/Installation') sys.exit(1) +# arbitrary number, seems reasonable though +readline.set_history_length(200) +readline.read_history_file(home_dir() + 'command_history.txt') def load_categories() -> set: categories = set() @@ -369,7 +373,6 @@ def get_regions(self, service, check_session=True) -> List[Optional[str]]: def display_history(self): # https://stackoverflow.com/a/7008316 - import readline for i in range(readline.get_current_history_length()): print("{:>3}: {}".format(i+1, readline.get_history_item(i + 1))) @@ -629,6 +632,8 @@ def parse_command(self, command): elif command[0] == 'whoami': self.print_key_info() elif command[0] == 'exit' or command[0] == 'quit': + # write out command history for loading later + readline.write_history_file(home_dir() + 'command_history.txt') self.exit() else: print(' Error: Unrecognized command') @@ -1586,7 +1591,6 @@ def get_boto3_resource( def initialize_tab_completion(self) -> None: try: - import readline # Big thanks to samplebias: https://stackoverflow.com/a/5638688 MODULES = [] CATEGORIES = [] From 0f3a8fb700d47b83da9d1a3df98a094ed45926d0 Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 12:59:18 -0400 Subject: [PATCH 06/13] Fix poxipath --- pacu/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pacu/main.py b/pacu/main.py index b7322a81..bbb2f006 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -45,7 +45,7 @@ # arbitrary number, seems reasonable though readline.set_history_length(200) -readline.read_history_file(home_dir() + 'command_history.txt') +readline.read_history_file(f'{home_dir()}/command_history.txt') def load_categories() -> set: categories = set() @@ -633,7 +633,7 @@ def parse_command(self, command): self.print_key_info() elif command[0] == 'exit' or command[0] == 'quit': # write out command history for loading later - readline.write_history_file(home_dir() + 'command_history.txt') + readline.write_history_file(f'{home_dir()}/command_history.txt') self.exit() else: print(' Error: Unrecognized command') From 9a3f746ecca425cf6e7891f1bff9ea352d1dbbfe Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 13:03:11 -0400 Subject: [PATCH 07/13] read history if it exists --- pacu/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pacu/main.py b/pacu/main.py index bbb2f006..9dc4aeed 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -45,7 +45,8 @@ # arbitrary number, seems reasonable though readline.set_history_length(200) -readline.read_history_file(f'{home_dir()}/command_history.txt') +if os.path.isfile(f'{home_dir()}/command_history.txt') and os.access(file, os.R_OK): + readline.read_history_file(f'{home_dir()}/command_history.txt') def load_categories() -> set: categories = set() From 00ce419895d8eaf9f176af45f0018eb20a113b42 Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 13:04:04 -0400 Subject: [PATCH 08/13] Update main.py --- pacu/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pacu/main.py b/pacu/main.py index 9dc4aeed..961340db 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -45,7 +45,7 @@ # arbitrary number, seems reasonable though readline.set_history_length(200) -if os.path.isfile(f'{home_dir()}/command_history.txt') and os.access(file, os.R_OK): +if os.path.isfile(f'{home_dir()}/command_history.txt') and os.access(f'{home_dir()}/command_history.txt', os.R_OK): readline.read_history_file(f'{home_dir()}/command_history.txt') def load_categories() -> set: From bafced38d4b69be60e83d5518e1268eb6e807c2b Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 29 May 2024 13:14:19 -0400 Subject: [PATCH 09/13] remove spaces --- pacu/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pacu/main.py b/pacu/main.py index 961340db..dffaa52a 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -795,7 +795,7 @@ def parse_list_command(self, command): elif len(command) == 3: if command[1] in ('cat', 'category'): self.list_modules(command[2], by_category=True) - + def parse_exec_module_command(self, command: List[str]) -> None: if len(command) > 1: self.exec_module(command) From c183c0e7afb2d751d88eb69da9708c7758577fea Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 4 Jun 2024 19:20:24 -0400 Subject: [PATCH 10/13] resolve merge conflicts --- pacu/main.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pacu/main.py b/pacu/main.py index eda41d45..93b929e1 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -606,13 +606,9 @@ def parse_command(self, command): self.parse_commands_from_file(command) elif command[0] == 'regions': self.display_all_regions() -<<<<<<< HEAD elif command[0] == 'history': self.display_history() - elif command[0] == 'run' or command[0] == 'exec': -======= elif command[0] in ['run', 'exec', 'use']: ->>>>>>> master self.print_user_agent_suffix() self.parse_exec_module_command(command) elif command[0] == 'search': From 38201bf68a97fa5aceb3c35a062a4b365a4e8ce2 Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 4 Jun 2024 19:21:51 -0400 Subject: [PATCH 11/13] flake8 issues fixed --- pacu/main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pacu/main.py b/pacu/main.py index 93b929e1..792ed2bb 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -48,6 +48,7 @@ if os.path.isfile(f'{home_dir()}/command_history.txt') and os.access(f'{home_dir()}/command_history.txt', os.R_OK): readline.read_history_file(f'{home_dir()}/command_history.txt') + def load_categories() -> set: categories = set() current_directory = os.getcwd() @@ -184,8 +185,8 @@ class Main: COMMANDS = [ 'assume_role', 'aws', 'console', 'data', 'delete_session', 'exec', 'exit', 'export_keys', 'help', 'history', 'import_keys', 'list', 'list_sessions', 'load_commands_file', 'ls', 'open_console', 'quit', - 'regions','run', 'search', 'services', 'sessions', 'set_keys', 'set_regions', 'set_ua_suffix', - 'swap_keys','swap_session', 'unset_ua_suffix', 'update_regions', 'use', 'whoami' + 'regions', 'run', 'search', 'services', 'sessions', 'set_keys', 'set_regions', 'set_ua_suffix', + 'swap_keys', 'swap_session', 'unset_ua_suffix', 'update_regions', 'use', 'whoami' ] def __init__(self): @@ -376,7 +377,7 @@ def display_history(self): # https://stackoverflow.com/a/7008316 for i in range(readline.get_current_history_length()): print("{:>3}: {}".format(i+1, readline.get_history_item(i + 1))) - + def display_all_regions(self): for region in sorted(self.get_regions('all')): print(' {}'.format(region)) From 4f0820415a5d55f60679fc3c9216d8a9bae7e356 Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 4 Jun 2024 19:25:20 -0400 Subject: [PATCH 12/13] move history file location to settings file --- pacu/main.py | 6 +++--- pacu/settings.py | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pacu/main.py b/pacu/main.py index 792ed2bb..957e0abb 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -45,8 +45,8 @@ # arbitrary number, seems reasonable though readline.set_history_length(200) -if os.path.isfile(f'{home_dir()}/command_history.txt') and os.access(f'{home_dir()}/command_history.txt', os.R_OK): - readline.read_history_file(f'{home_dir()}/command_history.txt') +if os.path.isfile(settings.history_file) and os.access(settings.history_file, os.R_OK): + readline.read_history_file(settings.history_file) def load_categories() -> set: @@ -635,7 +635,7 @@ def parse_command(self, command): self.print_key_info() elif command[0] == 'exit' or command[0] == 'quit': # write out command history for loading later - readline.write_history_file(f'{home_dir()}/command_history.txt') + readline.write_history_file(settings.history_file) self.exit() else: print(' Error: Unrecognized command') diff --git a/pacu/settings.py b/pacu/settings.py index 30459df7..40d5e84e 100644 --- a/pacu/settings.py +++ b/pacu/settings.py @@ -17,6 +17,8 @@ _home_dir = Path('~/.local/share/pacu') home_dir = _home_dir.expanduser().absolute() +history_file = f'{home_dir}/command_history.txt' + os.makedirs(home_dir, exist_ok=True, mode=0o700) DATABASE_FILE_PATH = os.path.join(home_dir, 'sqlite.db') From fa3bea4dff5afb6b9c78d20f4a323a2617a94273 Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 4 Jun 2024 19:26:28 -0400 Subject: [PATCH 13/13] remove unused variable --- pacu/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pacu/main.py b/pacu/main.py index 957e0abb..8473bc04 100644 --- a/pacu/main.py +++ b/pacu/main.py @@ -17,7 +17,7 @@ from typing import List, Optional, Any, Dict, Union, Tuple from pacu.core import lib -from pacu.core.lib import session_dir, home_dir +from pacu.core.lib import session_dir try: import jq # type: ignore