From c24795b0067d8ee00ddd3cfb7a9527fa33446cd6 Mon Sep 17 00:00:00 2001 From: Karmaz95 Date: Mon, 23 Sep 2024 22:09:57 +0200 Subject: [PATCH] Uploading crimson_waccess.py --- VIII. Sandbox/python/crimson_waccess.py | 101 ++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 VIII. Sandbox/python/crimson_waccess.py diff --git a/VIII. Sandbox/python/crimson_waccess.py b/VIII. Sandbox/python/crimson_waccess.py new file mode 100644 index 0000000..6736d05 --- /dev/null +++ b/VIII. Sandbox/python/crimson_waccess.py @@ -0,0 +1,101 @@ +import os +import time +import subprocess +import sys + +class Waccess: + '''Class to check write permissions on directories and files.''' + + def log_issue(self, path, issue_type, output_path): + '''Log an issue when write permissions are unexpectedly granted.''' + with open(output_path, "a") as log_file: + log_data = (f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {issue_type}: {path}\n") + log_file.write(log_data) + print(log_data, end="") + + def check_write_permission(self, path, output_path): + '''Check write permission for a directory or file.''' + if os.path.isdir(path): + self.check_directory_write_permission(path, output_path) + elif os.path.isfile(path): + self.check_file_write_permission(path, output_path) + else: + sys.stderr.write(f"Path {path} does not exist.") + + def check_directory_write_permission(self, directory_path, output_path): + '''Check if a directory is writable by attempting to create a test file.''' + test_file_path = os.path.join(directory_path, f"{int(time.time())}_crimson_write_test.txt") + try: + with open(test_file_path, "w") as f: + f.write("This is a test.") + os.remove(test_file_path) + self.log_issue(directory_path, "Directory writable", output_path) + except Exception: + pass # Suppress errors for denied write operations + + def check_file_write_permission(self, file_path, output_path): + '''Check if a file is writable by attempting to 'touch' it.''' + result = subprocess.run(['touch', file_path], capture_output=True) + if result.returncode == 0: + self.log_issue(file_path, "File writable", output_path) + + def check_paths(self, paths_to_check, output_path, recursive): + '''Iterate through paths and check permissions.''' + checked_paths = set() + while paths_to_check: + path = paths_to_check.pop() + if path in checked_paths: + continue + checked_paths.add(path) + + base_path = path.rstrip('*') # Remove trailing asterisks for checking + if path.endswith('*'): + self.check_write_permission(base_path, output_path) + # Always check recursively if '*' is present + if os.path.isdir(base_path): + self.add_child_paths(base_path, paths_to_check, checked_paths) + else: + self.check_write_permission(path, output_path) + if recursive and os.path.isdir(path): + self.add_child_paths(path, paths_to_check, checked_paths) + + return checked_paths + + def add_child_paths(self, base_path, paths_to_check, checked_paths): + '''Add child directories and files to the list to check.''' + for root, dirs, files in os.walk(base_path): + for dir_name in dirs: + child_path = os.path.join(root, dir_name) + if child_path not in checked_paths: + paths_to_check.add(child_path) + for file_name in files: + child_file_path = os.path.join(root, file_name) + if child_file_path not in checked_paths: + paths_to_check.add(child_file_path) + + def check_sip_fp(self, file_path, output_path, recursive): + '''Main function to check each file and directory from the provided list.''' + try: + with open(file_path, "r") as paths_file: + paths_to_check = {line.strip() for line in paths_file if line.strip()} + + checked_paths = self.check_paths(paths_to_check, output_path, recursive) + + # Save all checked paths to a log file + with open("crimson_waccess_checked_paths.log", "w") as checked_paths_file: + for checked_path in checked_paths: + checked_paths_file.write(f"{checked_path}\n") + + except FileNotFoundError: + sys.stderr.write(f"The file {file_path} does not exist.") + +if __name__ == "__main__": + import argparse + parser = argparse.ArgumentParser(description="Check SIP-protected file and directory permissions.") + parser.add_argument("-f", "--file", required=True, help="Path to the file containing paths to check.") + parser.add_argument("-o", "--output", default="crimson_waccess.log", help="Path to the log file to write issues to.") + parser.add_argument("-r", "--recursive", action="store_true", help="Check directories recursively.") + + args = parser.parse_args() + waccess = Waccess() + waccess.check_sip_fp(args.file, args.output, args.recursive) \ No newline at end of file