ncat: general-purpose network connector

ncat can:

ncat always operates in one of two basic modes: connect mode and listen mode

  • in connect mode, ncat initiates a connection (or sends UDP data) to a service that is listening somewhere. for those familiar with socket programming, connect mode is like using the connect function
  • in listen mode, ncat waits for an incoming connection, like using the bind and listen functions
  • you can think of connect mode as 'client' mode and listen mode as 'server' mode

    to use ncat in connect mode, run

                ncat  <host>   [<port>]

    <host> may be a hostname or IP address, and <port> is a port number

    listen mode is the same, with the addition of the --listen option (or its -l alias):

                ncat --listen [<host>] [<port>]
    ncat -l [<host>] [<port>]

    In listen mode, <host> controls the address on which ncat listens; if you omit it, ncat will bind to all local interfaces (INADDR ANY). If the port number is omitted, ncat uses its default port 31337

    A listening TCP server normally accepts only one connection and will exit after the client disconnects. Combined with the --keep-open option, ncat accepts multiple concurrent connections up to the connection limit. With --keep-open (or -k for short), the server receives everything sent by any of its clients, and anything the server sends is sent to all of them. A UDP server will communicate with only one client (the first one to send it data), because in UDP there is no list of “connected” clients

    By default, ncat uses TCP and IPv4. The option --udp or -u enables UDP instead, --sctp enables SCTP, and -6 enables IPv6

    For a quick summary of options at any time, run ncat --help or man ncat

    A good way to start learning about ncat (and network protocols in general) is to connect to a network service and talk with it. In this case we use ncat to manually retrieve a web page from an HTTP server, just as web browsers do in the background when you visit a web site


    example 1:

    connect mode example

    Text in bold is what you type; everything else is what comes back. The blank line after the GET line is required — just hit enter twice

    $ ncat -C 80
    GET / HTTP/1.0
    HTTP/1.1 200 OK
    Date: Thu, 05 Feb 2009 15:31:40 GMT
    Server: Apache/2.2.2 (Fedora)
    Last-Modified: Mon, 19 May 2008 04:49:49 GMT
    ETag: "fc8c91-2e3-44d8e17edd540"
    Accept-Ranges: bytes
    Content-Length: 739
    Connection: close
    Content-Type: text/html; charset=UTF-8

    <html> <head> <title>Go ahead and ScanMe!</title> </head>

    Here we have instructed ncat to connect to the host on port 80, the port for HTTP. The -C option turns on CRLF replacement, which replaces any line endings you type with CRLF. CRLF line endings are required by many protocols, including HTTP, though many servers will accept a plain newline (LF) character

    GET / HTTP/1.0 requests the root document of the server; we are retrieving the same document named by the URL The web server responds with a status code (HTTP/1.1 200 OK), followed by the HTTP header and the text of the web page. If you try this with other web servers, note that many of them are actually virtual hosts and you will need to send the Host header field.

    listen mode example

    So much for using ncat as a web browser. What about a web server? That's possible too; it just takes a bit of preparation.

    The first step is to create the document to serve. Create a text file called hello.html with these contents:

    HTTP/1.0 200 OK

    <html> <body> <h1>Hello, world!</h1> </body> </html>

    Now run the command ncat -l localhost 8080 < hello.http

    This instructs ncat to listen on the local port 8080 and read hello.http on its input. ncat is now primed to send the contents of the file as soon as it receives a connection

    Now open a web browser and type in the address http://localhost:8080/

    In the terminal where you ran ncat, you will see everything the web browser sent to request the page. You should see a GET line like the one you sent in the connect mode example

    If you try to refresh the page, it won't work. That's because ncat ran out of input; it won't re-send what has already been sent

    connection brokering

    One of ncat's most useful and unique abilities is called connection brokering. A listening ncat in broker mode accepts connections from multiple clients. Anything received from one of the clients is sent back out to all the others. In this way an ncat broker acts like a network hub, broadcasting all traffic to everyone connected

    Activate broker mode with the --broker option, which must be combined with --listen. It wouldn't make sense for a client to be a broker


    ncat can encrypt its traffic using SSL. In connect mode, simply add the --ssl option. --ssl works with TCP (the default) and SCTP (--sctp option)

    Here is the syntax for connecting to an HTTPS server:

    ncat -C --ssl <server> 443

    Sometimes an SSL server will require a client certificate for authentication. When this is the case, use the --ssl-cert and --ssl-key options to give the locations of PEM-encoded files containing the certificate and private key, respectively. The certificate and key may be in the same file

    By default the client will not do any server certificate verification, so it will not be detected if the server has the wrong certificate or no certificate at all. Use the --ssl-verify option to require verification of the certificate and matching of the domain name

    ncat -C --ssl-verify <server> 443

    Verification is done using the ca-bundle.crt certificate bundle shipped with ncat, plus whatever trusted certificates the operating system may provide. If you want to verify a connection to a server whose certificate isn't signed by one of the default certification authorities, use the --ssl-trustfile to name a file containing certificates you trust. The file must be in PEM format

    ncat -C --ssl-verify --ssl-trustfile <custom-certs.pem> <server> 443

    Verification should be done whenever it is feasible. Even with encryption, an unverified connection is vulnerable to a man-in-the-middle attack. ncat does not do certificate revocation checking

    ncat can act as an SSL server as well. The server must provide a certificate that clients can verify if they choose. If you start an SSL server without using the --ssl-cert and --ssl-key options, ncat will automatically generate a certificate and 1,024-bit RSA key. The certificate will of course not be trusted by any application doing certificate verification. In verbose mode, the key's fingerprint will be printed so you can do manual verification if desired

    Example 2 shows sample output.

    example 2. automatic certificate generation

    $ ncat -v --listen --ssl
    ncat ( )
    Generating a temporary 1024-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one
    SHA-1 fingerprint: F0:13:BF:FB:2D:AA:76:88:22:60:3E:17:93:29:3E:0E:6B:92:C0:2F

    Using an existing certificate and key is recommended whenever possible because it allows for robust server authentication. Use the --ssl-cert and --ssl-key options to pass in PEM-encoded files. For testing purposes you can generate a self-signed certificate and private key. If you have OpenSSL installed, use this command:

    openssl req -new -x509 -keyout test-key.pem -out test-cert.pem

    For purposes of certificate verification, the commonName in the certificate should match the fully qualified domain name of the host that will run the server. After generating the files, start the server:

    ncat --listen --ssl --ssl-cert test-cert.pem --ssl-key test-key.pem

    To make a verified client connection, copy the test-cert.pem file somewhere where the client can access it, then run

    ncat --ssl-verify --ssl-trustfile test-cert.pem

    command execution

    ncat can execute an external command after establishing a connection. The command's standard input, output, and error streams are redirected to use ncat's network connection. Anything received over the connection is given to the command's stdin, and anything the command writes is sent back out over the connection. This makes almost any terminal application accessible over a network (with some caveats)

    The --exec option (alias -e) takes the full pathname of a command to execute, along with its arguments. The command is executed directly; ncat does not interpret the given string beyond splitting the command and its arguments

    example 3 : running a command with --exec

    ncat -l --exec "/bin/echo Hello."

    The --sh-exec (-c) works the same way as --exec, except that it executes the command by passing it to /bin/sh -c on Unix or cmd.exe /C on Windows. You don't have to use the full pathname of the command if the command is in the PATH. Additionally you have access to shell facilities such as pipelines and environment variable expansion

    example 4. running a command with --sh-exec

    ncat -l --sh-exec "echo `pwd`"

    The exec options can be used in connect mode and listen mode. In listen mode, ncat accepts one connection, runs the command, and then quits, just like listen mode without exec. But when listen mode is combined with --keep-open, ncat will accept multiple connections, forking off a new handler for each. This works even in UDP mode; the usual limit of only one client doesn't apply. The server will keep running until you press ctrl+C or otherwise terminate it externally. In this way ncat can work much like inetd

    example 5. running an inetd-like server

    ncat -l --keep-open --exec "/bin/echo Hello."

    Any program that takes input and produces output can be executed by ncat, but not all programs are suited for interaction. The reason is that many programs buffer their input and output, so if they receive some bytes, they may not process those bytes and write output until their input buffer is full, or the output may be deferred until the output buffer is full. Buffers are flushed when input or output ends, so even those programs that don't work interactively will work when run on an entire file at a time

    Be careful when using the --exec and --sh-exec options. It can be dangerous to connect a new application to a network, especially one that wasn't written with potentially hostile input in mind. Any local vulnerabilities in an application may become remote vulnerabilities when you execute it through ncat

    output options

    Like any proper pipeline utility, ncat reads from standard input and writes to standard output so you can redirect I/O to or from any program or file. The only exception is when ncat is run with the --exec or --sh-exec options, in which case it communicates with the subprocess instead. Nothing in the streams is added, removed, or altered, unless you specifically ask for it with an option such as -C (CRLF processing) or --telnet (Telnet negotiation). If ncat prints any diagnostic messages, they are sent to standard error so as not to interfere with the data stream. By default ncat does not print any such messages, but you can enable them with the --verbose (-v) option. Use -v more than once for even more output

    Use the --output option or its alias -o to record a transcript of everything sent and received to a file:

    ncat -C --output smtp-debug.log 25

    The log contains everything sent and received without differentiation. Sometimes a hex dump is more useful than a plain text log; for that use --hex-dump or -x. Let's see what happens if we accidentally speak SMTP to an SSH server:

    $ ncat -C --hex-dump ssh-hex.log 22
    SSH-2.0-OpenSSH 4.3
    Protocol mismatch

    The --hex-dump log file for this session:

    [0000]   53 53 48 2D 32 2E 30 2D   4F 70 65 6E 53 53 48 5F   SSH-2.0- OpenSSH 
    [0010]   34 2E 33 0A                                         4.3
    [0000]   48 45 4C 4F 20 65 78 61   6D 70 6C 65 2E 63 6F 6D   HELO exa
    [0010]   0D 0A                                               .
    [0000]   50 72 6F 74 6F 63 6F 6C   20 6D 69 73 6D 61 74 63   Protocol  mismatc
    [0010]   68 2E 0A                                            h.

    Each transmission is dumped separately. There is a break and the counter at the left starts over each time there is a new send