from mythic_container.MythicCommandBase import *
from mythic_container.MythicRPC import *


class CatArguments(TaskArguments):
    def __init__(self, command_line, **kwargs):
        super().__init__(command_line, **kwargs)
        self.args = [
            CommandParameter(
                name="file",
                type=ParameterType.String,
                description="Ruta del archivo a leer",
                parameter_group_info=[ParameterGroupInfo(
                    required=True
                )]
            ),
        ]

    async def parse_arguments(self):
        if len(self.command_line) == 0:
            raise ValueError("Se debe indicar un archivo a leer")
        self.add_arg("file", self.command_line)

    async def parse_dictionary(self, dictionary):
        self.load_args_from_dictionary(dictionary)


class CatCommand(CommandBase):
    cmd = "cat"
    needs_admin = False
    help_cmd = "cat <file_path>"
    description = "Read and display the contents of a file on the target system. Supports both absolute and relative paths (relative paths are resolved using the current working directory). Automatically detects and extracts credentials from file contents including: plaintext passwords, NTLM hashes (aad3b435b51404ee:hash format), and domain credentials. Detected credentials are automatically added to Mythic's credential store. Useful for reading configuration files, log files, and credential databases."
    version = 1
    author = "Kaseya OFSTeam"
    attackmapping = []
    argument_class = CatArguments
    attributes = CommandAttributes(
        builtin=False,
        supported_os=[SupportedOS.Windows],
        suggested_command=False
    )

    async def opsec_pre(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPreTaskMessageResponse:
        """
        OPSEC check before creating the task.
        Warns about file reading risks, especially for sensitive files.
        """
        file_path = taskData.args.get_arg("file") or ""
        
        # Sensitive file patterns
        sensitive_patterns = {
            "sam": "SAM database - Credential extraction heavily monitored",
            "system": "SYSTEM hive - Registry access logged",
            "security": "SECURITY hive - Security database access logged",
            "ntds.dit": "NTDS.dit - Active Directory database, highly monitored",
            "lsass": "LSASS memory - Credential extraction heavily monitored",
            "passwd": "Password files - Credential access monitored",
            "shadow": "Shadow files - Credential access monitored",
            "config": "Configuration files - May contain credentials",
        }
        
        warnings = []
        file_lower = file_path.lower()
        
        for pattern, reason in sensitive_patterns.items():
            if pattern in file_lower:
                warnings.append(f"🚨 {pattern}: {reason}")
        
        message = "⚠️ OPSEC WARNING - File Read Detected\n\n"
        message += "File reading is monitored by:\n"
        message += "  • EDR/XDR solutions\n"
        message += "  • Data loss prevention (DLP) systems\n"
        message += "  • File access monitoring tools\n"
        message += "  • File access auditing (if enabled)\n\n"
        
        if file_path:
            message += f"Target File: {file_path}\n\n"
        
        if warnings:
            message += "🚨 SENSITIVE FILE DETECTED:\n"
            for warning in warnings:
                message += f"  {warning}\n"
            message += "\n"
        
        message += "🔍 DETECTION RISKS:\n"
        message += "  • File access events (if auditing enabled)\n"
        message += "  • Sensitive file patterns (DLP detection)\n"
        message += "  • Credential detection (if file contains credentials)\n"
        message += "  • Unusual file access patterns\n\n"
        message += "💡 CONSIDERATIONS:\n"
        message += "  • Sensitive files (credentials, databases) are heavily monitored\n"
        message += "  • Credentials found in file will be automatically reported\n"
        message += "  • File content may be logged by DLP systems\n\n"
        message += "✅ This is a WARNING only - command will proceed.\n"
        message += "Ensure you understand the detection risks before continuing."
        
        return PTTTaskOPSECPreTaskMessageResponse(
            TaskID=taskData.Task.ID,
            Success=True,
            OpsecPreBlocked=False,
            OpsecPreBypassRole="operator",
            OpsecPreMessage=message
        )

    async def opsec_post(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPostTaskMessageResponse:
        """
        OPSEC check after creating the task.
        Warns about artifacts that will be created.
        """
        file_path = taskData.args.get_arg("file") or ""
        
        message = "⚠️ OPSEC POST-CHECK - File Read Artifacts\n\n"
        message += "This task will create the following artifacts:\n"
        message += "  • File Access: Read operations on target file\n"
        message += "  • File Content: File data retrieved and analyzed\n"
        message += "  • Credential Detection: Automatic credential scanning (if found)\n"
        message += "  • File Access Logs: Event logs (if auditing enabled)\n\n"
        
        if file_path:
            message += f"Target File: {file_path}\n\n"
        
        message += "🔍 DETECTION RISKS:\n"
        message += "  • EDR/XDR file access monitoring\n"
        message += "  • DLP systems (sensitive file detection)\n"
        message += "  • File access auditing (if enabled)\n"
        message += "  • Credential extraction detection\n\n"
        message += "⚠️ HIGH DETECTION PROBABILITY IF:\n"
        message += "  • File contains credentials or sensitive data\n"
        message += "  • File access auditing is enabled\n"
        message += "  • DLP rules match file patterns\n"
        message += "  • File is a security database (SAM, NTDS, etc.)\n\n"
        message += "✅ This is a WARNING only - task will proceed.\n"
        message += "Ensure you understand the detection risks before continuing."
        
        return PTTTaskOPSECPostTaskMessageResponse(
            TaskID=taskData.Task.ID,
            Success=True,
            OpsecPostBlocked=False,
            OpsecPostBypassRole="operator",
            OpsecPostMessage=message
        )
    
    async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
        response = PTTaskCreateTaskingMessageResponse(
            TaskID=taskData.Task.ID,
            Success=True,
        )
        return response

    async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
        """
        Process response from agent.
        Note: The cat command automatically detects and reports credentials if found in file content.
        """
        resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
        return resp

