August 6, 2026
CTF Basics: Understanding Netcat (nc)
Learn how to use netcat (nc) to connect to CTF challenge servers, transfer files, and understand what’s happening under the hood when two…

By Walter Moar
6 min read
Learn how to use netcat (nc) to connect to CTF challenge servers, transfer files, and understand what's happening under the hood when two computers talk to each other.
This article covers netcat, or "nc", the tool that shows up in nearly every CTF challenge that involves connecting to a remote server. General Skills challenges in particular love to say something like "connect to the server at fickle-tempest.picoctf.net on port 22902", and that's exactly what netcat is for. Understanding it will unlock an entire category of challenges that would otherwise be a dead end.
To make this article easier to understand, it will help to first read "CTF Basics: Understanding the Linux Terminal".
What Netcat Actually Is
Netcat (abbreviated nc) is a command-line tool that opens a raw network connection between two computers and lets them send data back and forth. There's no extra networking protocols on top, no encryption, nothing beyond the basics. It's just a very simple connection between two computers.
The simplicity of netcat is what makes it so useful. Most networking tools are built for one specific job: a web browser speaks HTTP, an email client speaks SMTP, an FTP client speaks FTP. Netcat speaks nothing. It just connects and passes along whatever is typed, and that makes it flexible enough to talk to almost anything.
In CTF challenges, netcat is used most often as a client: the challenge runs a server that is waiting for a connection, and netcat is how the connection gets made.
The Basic Connection
The core syntax is straightforward:
$ nc fickle-tempest.picoctf.net 22902$ nc fickle-tempest.picoctf.net 22902The two arguments are the host (a domain name or IP address) and the port (a number between 0 and 65535 that identifies which service to connect to on that host).
After running this, one of two things will happen. Either the server will immediately send some output, or it will wait for input. Either way, the connection is live and the challenge has begun.
A typical CTF netcat session might look like:
$ nc fickle-tempest.picoctf.net 22902
Welcome! Solve this riddle to get your flag:
I speak without a mouth and hear without ears. What am I?
echo
picoCTF{example_flag_here}$ nc fickle-tempest.picoctf.net 22902
Welcome! Solve this riddle to get your flag:
I speak without a mouth and hear without ears. What am I?
echo
picoCTF{example_flag_here}The server sent the riddle, the player typed the answer "echo", and the server responded with the flag. This back-and-forth over a raw connection is the core of how netcat-based challenges work.
What Is a Port?
A port is a number that identifies a specific service or program on a computer. Think of an IP address as a building's street address and the port number as the apartment number inside that building. The address gets the data to the right machine, and the port gets it to the right program.
Some port numbers are standardized by convention:
- 21: FTP (file transfer)
- 22: SSH (secure remote login)
- 80: HTTP (unencrypted web traffic)
- 443: HTTPS (encrypted web traffic)
A port number may conventionally be used for a certain service, but that same service could be run on any port. For example, HTTP can also be found on 8000, 8080, or any other port. Similarly, any service can run on any port, so port 80 could be used for FTP, SSH, or anything else. These are non-standard uses but they're possible.
CTF challenges tend to use high-numbered ports like 22902, 9001, or 31337 specifically because those ports are not already claimed by a standard service. When a challenge gives a port number above 1024, it's almost certainly a custom challenge server.
Flags and Options Worth Knowing
The basic nc <host> <port> command covers the majority of CTF use. A few options come up often enough to be worth knowing.
-v (verbose) prints connection status information. Without it, netcat connects silently. With it, a successful connection shows a confirmation message, and a failed one explains why:
$ nc -v fickle-tempest.picoctf.net 22902
Connection to fickle-tempest.picoctf.net 22902 port [tcp/*] succeeded!
Welcome! Solve this riddle to get your flag:$ nc -v fickle-tempest.picoctf.net 22902
Connection to fickle-tempest.picoctf.net 22902 port [tcp/*] succeeded!
Welcome! Solve this riddle to get your flag:Compared to:
$ nc -v not-a-server.picoctf.net 22902
nc: getaddrinfo for host "not-a-server.picoctf.net" port 22902:
Name or service not known$ nc -v not-a-server.picoctf.net 22902
nc: getaddrinfo for host "not-a-server.picoctf.net" port 22902:
Name or service not knownOr:
$ nc -v fickle-tempest.picoctf.net 1337
nc: connect to fickle-tempest.picoctf.net (3.137.126.208) port 1337 (tcp)
failed: Connection refused$ nc -v fickle-tempest.picoctf.net 1337
nc: connect to fickle-tempest.picoctf.net (3.137.126.208) port 1337 (tcp)
failed: Connection refused-l (listen) flips netcat into server mode, making it wait for an incoming connection instead of initiating one. This comes up in challenges where the player needs to receive a file or run a service:
$ nc -l 4444$ nc -l 4444This opens port 4444 on the local machine and waits. Another instance of netcat connecting to that port from another terminal (or another machine) will complete the connection.
-z checks whether a port is open without sending any data, which is a quick way to test connectivity before committing to a full session.
Sending and Receiving Files
Netcat can transfer files between machines without any additional tools. The technique is used in CTF challenges that involve moving data to or from a server.
To receive a file, the listener side redirects its output into a file using >:
$ nc -l 4444 > received_file.txt$ nc -l 4444 > received_file.txtTo send a file, the connecting side redirects a file as input using <:
$ nc 127.0.0.1 4444 < file_to_send.txt$ nc 127.0.0.1 4444 < file_to_send.txt127.0.0.1 is called the "loopback" or "localhost" address, and always refers to the local machine. It's useful for testing a two-terminal setup locally before working with a remote server.
The transfer completes when the file ends. Because netcat has no built-in end-of-transfer signal, the connection usually closes automatically when the sending side finishes and closes its input. If it hangs, pressing Ctrl+C will end the session.
Piping Commands Into Netcat
The same pipe operator | used with grep and other terminal tools works with netcat too. This is especially useful when a challenge server asks a question that could be answered programmatically.
For example, if a server sends an arithmetic problem that must be solved within a time limit:
$ nc fickle-tempest.picoctf.net 22902
Solve 10000 math problems to get your flag.
Problem 1: 4823 + 9174 = ?$ nc fickle-tempest.picoctf.net 22902
Solve 10000 math problems to get your flag.
Problem 1: 4823 + 9174 = ?Typing 10000 answers by hand isn't practical. The solution is to write a script that reads the server's output, computes the answer, and sends it back (but that's an entirely different topic).
For simpler cases, a command can be piped directly:
$ echo "echo" | nc fickle-tempest.picoctf.net 22902$ echo "echo" | nc fickle-tempest.picoctf.net 22902This sends the word echo immediately when the connection opens, without waiting for keyboard input. It's useful when the expected input is known in advance.
When the Connection Refuses
If netcat exits immediately with an error, the most common reasons are:
Connection refused means the host is reachable but nothing is listening on that port. The challenge server may have timed out or crashed, or the port number may be wrong. Double-check the challenge description.
No route to host or Network is unreachable means the machine itself could not be reached. This is usually a network issue on the local side, or the challenge server is temporarily down.
Timeout (the command just hangs without any output) often means a firewall is blocking the connection. Some networks, like school or workplace WiFi, block outbound connections on non-standard ports. The picoCTF WebShell avoids this problem because it runs with unrestricted outbound access.
Why Netcat Matters for Security
Netcat's power comes from the same property that makes raw network connections dangerous in the real world: it bypasses all the protocol-level protections that higher-level tools enforce.
A web browser refuses to connect to a server with an invalid SSL certificate. Netcat does not care. A properly configured SFTP client enforces authentication before transferring files. Netcat has no authentication at all. When two computers are connected by netcat, whatever is typed goes over the wire.
This is why cleartext protocols are a security risk. Anything sent over a plain netcat connection is readable to anyone who can see the network traffic. Passwords, flags, and commands are all visible. Tools like SSH exist to solve exactly this problem by encrypting the connection before any data is exchanged.
Netcat sessions are also unlogged by default. Running nc -l 4444 and accepting connections leaves no trace in standard system logs, which is why security professionals use it for legitimate testing and why attackers use it for the same reason. A compromised machine with netcat installed can be turned into a remote shell with a single command. Understanding the tool means understanding the risk it represents.
Summary
Netcat opens raw network connections. The essential form is nc host port to connect to a server, and nc -l port to listen for an incoming connection. The -v flag gives verbose output that confirms whether a connection succeeded. Files can be transferred using input and output redirection with < and >. Pipes | can feed command output directly into a netcat connection.
When a CTF challenge says "connect to our server," the first tool to try is netcat.
The reliable first steps for a netcat challenge are: connect with nc -v host port to confirm the connection and see the server's initial output, then read what the server sends and respond accordingly. If the output is long or complex, pipe it through grep or redirect it to a file for inspection.
Want to learn more about security weaknesses? I'm working through the CWE list and doing writeups for security challenges. Follow along for more articles like this one.