Division Zero (Div0). Copyright © 2011-2018

All rights reserved.

Port Scanning & Banner Grabbing Using Python

17 Dec 2014

In our “Netcat – The Swiss Army Knife of Networking”, Jun Hao gave a brief introduction to Netcat – how it can be used to perform port scanning and banner grabbing, create backdoor on a compromised system and test your firewall. Towards the end of the tutorial he briefly touched on “Scripting with Netcat” – Jun Hao demonstrated that using shell script, and mentioned how more efficient it will be if it’s done using scripting languages such as Python, Perl, Ruby, etc.

 

Sparking my interest from Jun Hao’s tutorial, I wrote a few Python scripts that perform port scanning and banner grabbing. Although not using Netcat, but Python libraries. My scripts are written with reference to T.J. O’Connor’s very well written book – Violent Python, 1st ed., Syngress, Novber 2008.

 

My Network Setup
  • My Machine: Ubuntu 14.04 LTS with Python 2.7.6, IP address: 192.168.209.128

  • Another Machine: “Damn Vulnerable Linux” (DVL), IP address: 192.168.209.129

 

Port Scanning

import optparse

from socket import *

 

def conn(targetHost, targetPort):

  try:

    conn = socket(AF_INET, SOCK_STREAM)

    conn.connect((targetHost, targetPort))

    print '[+] Connection to ' + targetHost + ' port ' + str(targetPort) + ' succeeded!'

 

  except Exception, e:

    print '[-] Connection to ' + targetHost + ' port ' + str(targetPort) + ' failed: ' + str(e)

 

  finally:

    conn.close()

 

def main():

  parser = optparse.OptionParser("%prog -t <target host(s)> -p <target port(s)>")

  parser.add_option('-t', dest='targetHosts', type='string', help='Specify the target host(s); Separate them by commas')

  parser.add_option('-p', dest='targetPorts', type='string', help='Specify the target port(s); Separate them by commas')

 

  (options, args) = parser.parse_args()

 

  if (options.targetHosts == None) | (options.targetPorts == None):

    print parser.usage

    exit(0)

 

  targetHosts = str(options.targetHosts).split(',')

  targetPorts = str(options.targetPorts).split(',')

 

  setdefaulttimeout(5)

 

  for targetHost in targetHosts:

    for targetPort in targetPorts:

      conn(targetHost, int(targetPort))

      print ''

 

if __name__ == '__main__':

  main()

 

Taking into two arguments (-t for target hosts/nodes, and –p for target ports), it informs the user if the port is open or close by attempting to create a socket connection to the respective host-port combination. The port is considered as open if the attempt succeed, and close otherwise.

 

An example of my script’s output:

$ python PortScanner .py –t 192.168.98.128,192.168.98.129,edgis –p 21,22,80,3306

My Ubuntu machine has SSH and Apache2 service running. And my DVL has an addition MySQL service running. Host “edgis” does not exist on my network.

 

Port Scanning using Python-Nmap Library

My Python script allows user to scan multiple hosts and ports by listing them (separated by commas). But what about notations such as a range of hosts/ports (using the character ‘-‘) like what Nmap allows? We can certainty expand the existing script to fit such needs, but why rebuild the wheel Nmap has provided? Here’s how you can utilise the Python-Nmap library.

 

import optparse 

import nmap

 

def nmapScan(targetHosts, targetPorts):

  try:

    scanner = nmap.PortScanner()

    scanner.scan(targetHosts, targetPorts)

 

  for targetHost in scanner.all_hosts():

    if scanner[targetHost].state() == 'up':

      print targetHost + ' is up'

  for targetPort in scanner[targetHost]['tcp']:

    print 'Port ' + str(targetPort) + '/tcp ' + scanner[targetHost]['tcp'][int(targetPort)]['name'] + ' is ' + scanner[targetHost]['tcp'][int(targetPort)]['state']

    print ''

  except Exception, e:

    print '[-] Something bad happened during the scan: ' + str(e)

 

def main():

  ...

  targetHosts = str(options.targetHosts)

  targetPorts = str(options.targetPorts)

  nmapScan(targetHosts, targetPorts)

 

$ python NmapScanner.py -t 192.168.98.125-130 -p 20,21,80,3306

$ python NmapScanner.py –t 192.168.98.125-130 –p 1-1024

Banner Grabbing

Jun Hao has also mentioned in his tutorial that – port scanning merely identify a list of open ports of a target host, and sometime it’s necessary to find out more about the services running on these ports. And banner grabbing is one of the easiest method to do so.

 

This can be easily done by adding an additional function grab(), and editing the existing conn() function to the first script mentioned above.

def conn(targetHost, targetPort):

  try:

    conn = socket(AF_INET, SOCK_STREAM)

    conn.connect((targetHost, targetPort))

    print '[+] Connection to ' + targetHost + ' port ' + str(targetPort) + ' succeeded!' grab(conn)

  ...

 

def grab(conn):

  try:

    conn.send('Hello, is it me you\'re looking for? \r\n')

    ret = conn.recv(1024)

    print '[+]' + str(ret)

    return

  except Exception, e:

    print '[-] Unable to grab any information: ' + str(e)

    return

We are able to grab the banner from the Apache service running on my DVL machine, but not the Apache2 service running on my Ubuntu machine. Also mentioned in Jun Hao’s tutorial, that’s because the more up-to-date HTTP services require specific input for it to return its banner.

 

So here’s a little tweak – introduce grabHTTP() and edit the existing conn() function.

def conn(targetHost, targetPort):

  try:

    ...

    if targetPort == 80:

      grabHTTP(conn)

    else:

      grab(conn)

  ...

 

def grabHTTP(conn):

  try:

    conn.send('GET HTTP/1.1 \r\n')

    ret = conn.recv(1024)

    print '[+]' + str(ret)

    return

  except Exception, e:

    print '[-] Unable to grab any information: ' + str(e)

    return

What Now? Why Do This?

By the end of this, you may be feeling a little excited that you've coded your own port scanner. But an afterthought might follow – “why do this when there are so many freely available port scanning tools out there?” – “Why write a Python script that uses Nmap when it’s easier to use Nmap itself?”

 

First, because coding is fun. Second, this can be just the beginning of writing your own automated exploit script. You can make your script fires up tools such as Metasploit and exploit hosts based on your reconnaissance results, etc. – all using one simple script, and not yourself scrambling through all your tools that are scattered all over your system.

Share on Facebook
Share on Twitter
Please reload

RECENT POST

September 5, 2017

Please reload

CATEGORIES
Please reload

TAGS
RSS
RSS Feed