Agile Hacking: a homegrown telnet-based portscanner
So here is the scenario: the attacker has limited access to a box and he/she needs to perform a portscan from it. However, he/she does not want to download any tools to the target system. There might be various reasons for not wanting to upload a portscanner to the box. Perhaps, the attacker wants to minimize the footprint.

In my case, the reason why I had to come up with a solution to this problem is because I had to simulate an attack in which the attacker had gained access to a Internet-visible web server. In this case, I needed to perform a portscan of the backend database server and make sure that only required ports are visible (a customized mssql port in this case). For reasons that are irrelevant to this post, the customer could only give me restricted access (NOT root) to the web server via SSH.
I really didn’t want to download a tool such as nmap and then compile it. In theory, I wouldn’t be able to cause serious damage to the system since I was using a restricted user account. Even then, I always try to be as polite as possible with customers’ environments during security assessments, especially when it’s a production system.
Anyway, my solution to this problem was to write a simple TCP portscanner in bash which glues around the telnet command which is present on most Unix/Linux distributions. Literally, all I’m doing is looking for Connected to responses generated by telnet which tells us that a successful TCP connection was established (open port). Very vanilla and trivial stuff as you can see! Nevertheless, I accomplished what I wanted, which is to perform a portscan without having to download any tools and without requiring root privileges.
The following is the short version of our agile hacking TCP portscanner which you can literally copy and paste on your shell (just change the value of the HOST variable to the IP address of the system you want to scan):
HOST=127.0.0.1;for((port=1;port<=65535;++port));do echo -en "$port ";if echo -en "open $HOST $port\nlogout\quit" | telnet 2>/dev/null | grep 'Connected to' > /dev/null;then echo -en "\n\nport $port/tcp is open\n\n";fi;done
The following is a more elaborate version of our portscanner which supports scanning for either common or all ports. The list of common ports is read from the ‘/etc/services’ file which is present on most Unix/Linux systems:
#!/bin/bash
# telnet-based TCP portscanner
# By Adrian 'pagvac' Pastor | www.gnucitizen.org
# delay in seconds
DELAY=0.001
if [[ $# -ne 2 ]]
then
echo "usage: $0 <mode> <host>"
echo -e "modes:\t1 - common TCP ports only"
echo -e "\t2 - all TCP ports"
exit
fi
if [[ $1 -eq 1 ]]
then
echo "scanning for the following common TCP ports on $2 ..."
for port in `grep '/tcp' /etc/services | cut -d '/' -f 1 | cut -d ' ' -f 2 | grep -v '#' | awk '{print $2}' | sort | uniq`
do
echo -en "$port "
if echo -en "open $2 $port\nlogout\quit" | telnet 2>/dev/null | grep 'Connected to' > /dev/null
then
echo -en "\n\nport $port/tcp is open\n\n"
fi
sleep $DELAY
done
echo -en "\n"
elif [[ $1 -eq 2 ]]
then
echo "scanning for all TCP ports on $2 ..."
for((port=1;port<=65535;++port))
do
echo -en "$port "
if echo -en "open $2 $port\nlogout\quit" | telnet 2>/dev/null | grep 'Connected to' > /dev/null
then
echo -en "\n\nport $port/tcp is open\n\n"
fi
sleep $DELAY
done
echo -en "\n"
fi
Syntax follows:
gnucitizen $ ./telnetps.sh
usage: ./telnetps.sh <mode> <host>
modes:
1 - common TCP ports only
2 - all TCP ports





comments
hmm.. Isn’t telnet one of the first services that every sysadmin turns off - for reasons all too known?
doesnt netcat do this?
nc -z host.example.com 20-30we use to do that 5 years ago. nice to see it still rocks .
yihaaaaa
Such a tool can be useful ;) Most UNIX and linux systems come with perl builtin - even the older ones. So I’d make use of that instead if its available. Has the advantage of not relying on screen scraping telnet and not relying on having telnet on the system.
the idea:
@mindcorrosive: I see your point, however I usually find the telnet command available on many systems I audit.
@defcon: that’s completely correct. This solution I proposed would be useful in cases in which netcat is not already installed on the system but telnet is. Also remember that in my case installing/downloading an additional tool was NOT an option.
@Udi: some solutions will always rock! I’m with you on that one :-D
@Sandro: Good to see you at GNUCITIZEN dude :) . Thanks a lot for another very useful solution. Another trick to use when needed. To me, it’s all about knowing different tricks which come in handy in different scenarios! We’ll definitely consider your solution for the Agile Hacking book! (you’ll be credited of course).
@pagvac: the more tricks the merrier :) re the book - that sounds great. looking forward to that
@mindcorrosive: the post refers to telnet the client rather than the daemon/server/service
@mindcorrosive: Yes, telnet as a service, but this is using the telnet client. Not all sysadmins remove the telnet client.
Its more then 5 years old….Good to see refresh version of it by Adrian.
This is really worth using it if you are performing audit in restrictive mode and you see telnet option is available…Bingo!!
I’ll repeat it again in case it wasn’t clear: my proposed homegrown port-scanner relies on the ‘telnet’ *CLIENT* (NOT server), which again is present on most Unix/Linux systems.
@Shoaib: I’ve never seen this specific implementation (telnet parser) of a portscanner in the public, but of course I’m not so naive to think this hasn’t been done before! ;) All in all, this is just another trick of the trade which fits the Agile Hacking book project quite nicely IMHO.
Ok, again. Try this code. Does the same without telnet. It is still buggy but works.
@Venom23: I’m on a Debian-based system now (Ubuntu) which does not support /dev/tcp. However, it looks like your script should work on any systems that support /dev/tcp. Thanks for your solution to this problem!
Any other ideas guys? Any default clients with TCP capabilities (i.e. ftp) is a good candidate for a homegrown port-scanner which doesn’t require root privileges to be run. Also, as Sandro mentioned, using any commonly-supported scripting environments such as Perl is another good candidate.
Adrian,
I totally agree. Another great piece of work from you guys. Keep it up!
This is cool. I believe Ed Skoudis has done something similar to this on Windows….
Here is an alternative, though not as polished, using curl…
Open ports return this response to our stimulous sorry if line is wrapped:
close ports look like this:
———-script———–