Did you ever wonder what would you do if telnet or netcat package is missing for Unix/Linux system. Being a sysadmin, you often come across a situation where you want to find out if target system is listening on given port. With simple tools like telnet or netcat your job becomes easy. These utility packages comes preinstalled with *nix like systems.
$ telnet 127.0.0.1 22
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is '^]'.
What if telnet or netcat package is missing and for some mysterious reason you are not allowed to install the packages ?
Well everything in Unix/Linux operating system is file and luckily *nix OS happen to have pseudo tcp device underneath /dev/tcp. Unlike other pseudo devices (ex: /dev/null) /dev/tcp is not visible. Try hitting ls -l /dev/tcp in your shell.
In order to make connection via /dev/tcp one has to follow directory path as /dev/tcp/HOSTNAME/PORT
Lets say you want to check your very own Linux machine is listening on port 22, a psuedo path to be used is /dev/tcp/localhost/22.
$ cat </dev/tcp/localhost/22
Now that we know how to make connection we can use handy command like cat to test this and use /dev/tcp/localhost/22 as a input device.
How about getting some meaningful information like time from internet servers ?
$ cat </dev/tcp/time.nist.gov/13
59100 20-09-08 19:27:13 50 0 0 238.0 UTC(NIST) *
Okay, how about talking to servers with raw application protocols like HTTP and downloading some file ?
$ exec 7<>/dev/tcp/speedtest.tele2.net/80
$ echo -e "GET /1MB.zip HTTP/1.1\nHost: speedtest.tele2.net\n" >&7
$ cat <&7 >1MB.zip
$ du -sh abc.zip
1.1M abc.zip
In the above example we first set number 7 as UNIX file descriptor to /dev/tcp/speedtest.tele2.net/80 for both input and output.
We then echo the HTTP headers and redirect output to file descriptor 7 which points to /dev/tcp/speedtest.tele2.net/80
HTTP headers instruct web server (speedtest.tele2.net) that we are using HTTP GET method and would like to retrieve /1MB.zip page/file followed by HTTP version. Some web servers may host more than one FQDN over same IP address. At the time of writing this blog, domain speedtest.tele2.net resolves to 90.130.70.73. Hence, to be on safer side we explicitly send HTTP HOST header asking web server hosted on 90.130.70.73 to serve data for speedtest.tele2.net. In the above example, we communicated to target web server via raw HTTP instruction. This is what our browser does when they make connection to target web-server with various other tedious job. Of course, this raw communication to establish HTTPS connection becomes even more complex unless you are super human to decode/encode incoming and outgoing data all by yourself.
So far, we saw how powerful /dev/tcp is; if one really knows application level protocols. Our initial goal was to check if target server is listening on given port.
$ echo >/dev/tcp/google.com/23
The above shell command may stuck on shell prompt as we know that google.com is not listening on port 23. Some Linux flavours may show prompt immediately even though target server is not listening on given port. In such scenario you can use a $? to find out status of last command (ex: echo $?). That’s it for the /dev/tcp psudeo device.
UNIX/Linux newbies might be wondering what exec does here ? Well stay tuned for my next blog post 😉
2 replies on “Knock Knock… Who’s There ? … /dev/tcp”
That’s neat and learning
Amazing write-up! Please keep sharing