Emulating Diagnostic Services
There are a number of simple Internet protocols intended for testing
and measurement purposes. Because they deal with simple, fundamental
network operations they are a good match for Ncat's capabilities. This
section shows how to to emulate services of increasing complexity:
discard, echo, daytime, qotd, and chargen. These particular commands assume you are on a UNIX system such as Linux or Mac OS X, and using a /bin/sh
compatible shell, such as Bash.
The discard service,
defined in
RFC 863, simply
ignores anything sent to it. It runs on TCP or UDP port 9. By
default, Ncat doesn't send any information unless instructed to, so
nothing special is needed to emulate discard. Send Ncat's output to
/dev/null
to avoid filling the screen with characters received, or just let it
write to the terminal if you're curious to see what's there. Use the
--recv-only
option to prohibit sending any characters that might be entered at the
terminal.
Ncat in UDP mode uses all the same options as TCP. The caveat here is that connections can't be closed, only timed out, so you will eventually run out of sockets if you do not use a timeout. Currently, none of the timeout options do the appropriate thing in this instance.
The echo service
is defined in
RFC 862. It runs
on TCP or UDP port 7. One step more advanced than discard, it
sends back any data received until the connection is closed. How do
you instruct Ncat to return what it receives? One easy way is to run
everything through /bin/cat
.
The daytime service,
defined in
RFC 867,
sends a human-readable date and time string over TCP or UDP
port 13. It ignores any input. The format of the date and time
string is left unspecified, so we are free to use the output of
/bin/date
. Because we are not interested in
anything sent by the client we use the
--send-only
option.
Nmap comes with a
daytime.nse
script that works with the daytime service. Here is its output running
against Ncat daytime servers on TCP and UDP.
daytime.nse
against an Ncat daytime server# nmap -sSU -p 13 --script=daytime localhost
Starting Nmap ( https://nmap.org )
Nmap scan report for localhost (127.0.0.1)
PORT STATE SERVICE
13/tcp open daytime
|_daytime: Mon Jan 19 17:43:18 MST 2009
13/udp open daytime
|_daytime: Mon Jan 19 17:43:18 MST 2009
Nmap done: 1 IP address (1 host up) scanned in 0.31 seconds
The qotd
(quote of the day) service is defined in
RFC 865. When a
connection is made to TCP or UDP port 17, it sends back a short
message, ignoring any input. Ncat can do this by invoking a program
that generates messages. A traditional choice is
/usr/games/fortune
, though there are many
possibilities. /usr/bin/uptime
, for example,
could be useful.
In this example it's instructive to consider the difference between ncat -l 17 --exec "/usr/games/fortune" and /usr/games/fortune | ncat -l 17. Think about why the second command stops working after the first connection.
The chargen service
from
RFC 864 rounds
out our tour of diagnostic services. It runs on TCP and UDP port 19.
With TCP, chargen ignores any input and sends a never-ending stream of
data. Never-ending, that is, until the connection is closed by the
user, who the RFC suggests may have “had enough”. There
are many ways of generating the characters; reading from
/dev/zero
and running yes come to mind.
- TCP chargen server
yes "chargenchargenchargen" | ncat -l --keep-open 19 --send-only
Notice that in this case the program pipes its output into
ncat rather than being invoked with
--exec
. For chargen either method would work,
because the output of yes never changes.
Using a pipe requires only one process other than
ncat, but all users connected simultaneously will
see the same output stream in synchrony. If the contents must be
independent for each stream, then use the --exec
method, with the understanding that a new process will be started for
each connection.
The UDP chargen protocol is a little different. When a datagram is received, it sends back one datagram containing a random number of characters. Implementing this is starting to get away from Ncat, but one way it could be done with the Bash shell is this:
Notice the use of
--sh-exec
rather than
--exec
to allow the use of the shell's environment variables and arithmetic
evaluation. Standard
error
is redirected to
/dev/null
to avoid including dd's summary lines
(1+0 records out
), which would
otherwise be included by Ncat.
This completes the tour of simple diagnostic services. These have been easy to implement with Ncat because (with the exception of UDP chargen) they all map directly onto a familiar command-line program. As services become more complex it gets harder to do everything in the shell. For complicated services it's better to write a separate program and have Ncat exec it directly.