cURL for port scanning

By | March 12, 2020

Usually such tools as telnet, nmap or nc are used to find listening remote ports. However nmap and netcat are not included in default Linux installation, telnet is good for manual testing and is not friendly for scripting task. So sometime I am using cURL or wget to get information about open ports on remote devices, even for ports not related to http servers. If cURL connects to not http tcp port it tries to send http request, but does not receive expected http response or does not get any response at all, but the fact of connection can be registered.
There are 4 possible scenarios of connection to not http port with cURL.
1. Not connected to remote host (server is down or not exist)


# curl -I –connect-timeout 10 http://10.195.18.1:3389
curl: (28) connect() timed out!



2. Server is on but port 3389 is not open:


# curl -I --connect-timeout 10 http://10.195.18.10:3389
curl: (7) couldn't connect to host

3. cURL connects to port 3389, sends GET http request, server does not properly responds and disconnects:


# curl -I --connect-timeout 10 http://10.195.18.19:3389
curl: (56) Failure when receiving data from the peer

4. cURL connects to port 3389, sends GET http request and waits for response but server does not respond:


# curl -I --connect-timeout 10 --max-time 10 http://10.195.18.19:135
curl: (28) Operation timed out after 10002 milliseconds with 0 out of -1 bytes received

Below is Linux script how to use cURL for port scanning:


#! /bin/bash
start_message()
{
   echo "Correct argument required, IP range and port"
   echo "Example: 192.168.1.0-127:1234"
   exit 1
}

echo "Pinging IP range"
if [ $# -eq 0 ]; then
   start_message
fi
IPRANGE=$(echo $1 | grep -v '[A-Za-z]' | grep -oE '(\b[0-9]{1,3}\.){3}[0-9]{1,3}-[0-9]{1,3}:[0-9]{1,5}')
echo $IPRANGE
if [ "$IPRANGE" == "" ]; then
   echo "Wrong argument: $1"
   start_message
fi
echo "Connect this IP range and port: $IPRANGE"
IPBASE=$(echo $IPRANGE | grep -oE '(\b[0-9]{1,3}\.){2}[0-9]{1,3}')
# echo $IPBASE
IPSTART=$(echo $IPRANGE | grep -oE '\b[0-9]{1,3}-' | grep -oE '\b[0-9]{1,3}')
# echo $IPSTART
IPEND=$(echo $IPRANGE | grep -oE '\b-[0-9]{1,3}' | grep -oE '\b[0-9]{1,3}')
# echo $IPEND
PORT=$(echo $IPRANGE | grep -oE '\b:[0-9]{1,5}' | grep -oE '\b[0-9]{1,5}')
# echo $PORT
for param in `seq $IPSTART $IPEND`; do
   IPADDR=$IPBASE.$param
# echo $IPADDR:$PORT
   RESULT=$(curl -I --connect-timeout 10 --max-time 10 http://$IPADDR:$PORT 2>&1 | grep -e 'Failure when receiving data from the peer' -e 'Operation timed out after')
   if [ "$RESULT" != "" ]; then
      echo "$IPADDR. Listening on port $PORT"
   fi
done

The script was tested on CentOS and Ubuntu devices. The script also can be downloaded from there.


Example of script execution:
1. Scanning port 3389 for IP range from 10.195.18.1 to 10.195.18.50


# ./curlscan.sh 10.195.18.1-50:3389
Connect this IP range and port: 10.195.18.1-50:3389
10.195.18.13. Listening on port 3389
10.195.18.17. Listening on port 3389
10.195.18.19. Listening on port 3389
10.195.18.21. Listening on port 3389
10.195.18.22. Listening on port 3389
10.195.18.23. Listening on port 3389
10.195.18.32. Listening on port 3389
10.195.18.33. Listening on port 3389
10.195.18.35. Listening on port 3389
10.195.18.36. Listening on port 3389
10.195.18.37. Listening on port 3389
10.195.18.38. Listening on port 3389
10.195.18.41. Listening on port 3389
10.195.18.42. Listening on port 3389
10.195.18.43. Listening on port 3389
10.195.18.49. Listening on port 3389

2. Scanning port 135 for IP range from 10.195.18.1 to 10.195.18.50


# ./curlscan.sh 10.195.18.1-50:135
10.195.18.190-250:135
Connect this IP range and port: 10.195.18.1-50:135
10.195.18.13. Listening on port 135
10.195.18.16. Listening on port 135
10.195.18.17. Listening on port 135
10.195.18.19. Listening on port 135
10.195.18.21. Listening on port 135
10.195.18.22. Listening on port 135
10.195.18.23. Listening on port 135
10.195.18.32. Listening on port 135
10.195.18.33. Listening on port 135
10.195.18.35. Listening on port 135
10.195.18.36. Listening on port 135
10.195.18.37. Listening on port 135
10.195.18.38. Listening on port 135
10.195.18.41. Listening on port 135
10.195.18.42. Listening on port 135
10.195.18.43. Listening on port 135
10.195.18.45. Listening on port 135
10.195.18.49. Listening on port 135

Leave a Reply

Your email address will not be published. Required fields are marked *