Netcat auto response

11.3k views Asked by At

I have a raspberry pi running that starts listening on port 666 on boot up.

'nc -k -l -p 666'

This server is for a capture the flag type game and what I want to happen is as follows. If a user echos a secret message to the server's 666 port I want the server to respond with another server message.. I also want this to happen anytime a user sends the right secret message no matter how many times they do it..

Client would issue a '$ echo 'secret' | nc 192.168.1.1 666' And get a response only if secret is correct

Can someone instruct me on how to right the server side NC command?

1

There are 1 answers

5
aitap On

Assuming that:

  1. your netcat supports the -c option which launches shell commands with stdin and stdout connected to network socket
  2. the secret messages are exactly one line long

you can try passing the following shell commands to nc's -c option:

read message # read the line that user sent
if [ x"$message" = x"secret message" ]; then # compare them
    echo "secret response"
fi

Which amounts to the following command to launch nc:

nc -k -l -p 666 -c 'read message; [ x"$message" = x"secret message" ] && echo "secret response"'

and the following behaviour:

$ echo zzz | nc localhost 666
$ echo secret message | nc localhost 666
secret response

If your netcat happens to have -c, but no -k option (as Debian's netcat-traditional does), run it in a loop:

while true; do nc -l -p 666 -c 'read message; [ x"$message" = x"secret message" ] && echo "secret response"'; done

By the way, the naive implementation above has a denial of service vulnerability: anyone can connect to it, but send nothing. The read call will be stuck waiting for a string. Being blocking and single-threaded, nc will not accept connections from other players, possibly with correct secret messages.

A crude fix for that would be adding -t <timeout> bashism to the script:

read -t 1 message || exit 1

Now an attacker would have to actively make a lot of connections in a loop instead of having made only one to prevent players from connecting to the server. A proper (though probably overkill) fix would be to write a multi-threaded and/or asynchronous server supporting more than one client a time and host it somewhere with an appropriately durable Internet connection and suitable amount of resources to withstand a flood attack. A first approximation to a proper solution, solving the multi-client issue, would be employing xinetd to run shells simultaneously:

service ctf
{
  port = 666
  socket_type = stream
  wait = no
  user = nobody
  server = /path/to/yourscript.sh
}
# assuming that yourscript.sh contains the script above with a proper shebang and is executable by everyone