NETWORK PROGRAMMING IN PYTHON

Using the Nmap Port Scanner with Python

In this tutorial, we will learn how to integrate the Nmap security scanner with our Post scanner program.


What is Nmap?

Nmap(Network Mapper) is a security scanner, originally written by Gordon Lyon(also known by his pseudonym Fyodor Vaskovich), and used to discover hosts and services on a computer network, thereby building a map of the network. To accomplish its goal, Nmap sends specially crafted packets to the target host(s) and then analyzes their responses.

Some of the useful Nmap features include:

  • Host Discovery: This enables to identify hosts on any network. For example, listing the hosts that respond to TCP and/or ICMP requests or have a particular port open.
  • Port Scanning: Enumerating(counting and listing one by one) all the open ports on the target hosts.
  • Version Detection: Interrogating network services on remote devices to determine application name and version number.
  • OS Detection: Determining the operating system and hardware characteristics of the network devices.
  • Scriptable Interaction with the target: Using Nmap Scripting Engine(NSE) and Lua programming language, we can easily write sripts to perform operations on the network devices.

Although Nmap is a command line interface, you can download and install the GUI interface for Nmap known as zenmap.

Integrating Port Scanner with Nmap


Above is the screenshot of the command line, when you run nmap command, all the options available for Target specifications and Host discovery, Scan Techniques etc are listed for your assistance. In case you want to install nmap in your machine, then:

The Port scanner program that we wrote in the last tutorial provides a quick script for performing a TCP connect scan. This is very limited as we might require the ability to perform additional scan types such as ACK, RST, FIN, or SYN-ACK scans provided by the Nmap toolkit. Nmap, delivers a rather extensive amount of functionality. This begs the question, why not just use Nmap? Why bother about writing a script for Port scanner?

Nmap is written in C and LUA programming languages, and can be easily integrated into Python. Nmap produces XML based output which provides us with the ability to utilize the full functionality of Nmap from within a Python script. So our Port Scanner script is just the outer shell, inside it we will be using Nmap now.

So, before we start using Nmap, let's first install nmap module:

  • Use the command, pip install python-nmap
  • Or install by downloading the package from here.

Using Nmap in Python script

Below are the commands which can be used to successfully scan all the ports and return the results in a JSON format.

>>> import nmap
>>> nmScan = nmap.PortScanner()
>>> 
>>> nmScan.scan('127.0.0.1', '21-443')

Using Nmap with Python

We all know, what import nmap is for, it is to import the nmap module to our python script. Then we initialise the Nmap PortScanner to scan the ports on our local network.

The third line i.e. nmScan.scan('127.0.0.1', '21-443') returns a dictionary of the scan, executed on the local Home(127.0.0.1) network, for port numbers between 21 to 443. You can also provide the IP address of any remote server as well, to scan the available ports.

If you want to run the Nmap command using the command line, you can easily get the command line equivalent of the nmScan.scan('127.0.0.1', '22-443') line of code, by using the command_line() method, which reads the scan method call and generate an equivalent command for running on command line.

>>> import nmap
>>> nmScan = nmap.PortScanner()
>>> 
>>> nmScan.scan('127.0.0.1', '21-443')
>>> nmScan.command_line()

'nmap -oX - -p 21-443 -sV 127.0.0.1'

Integrating Port Scanner with Nmap


More Nmap methods

Now, let's see some more commands:

>>> nmScan.scaninfo()
{'tcp': {'services': '22-443', 'method': 'connect'}}

>>> nmScan.all_hosts()
['127.0.0.1']

>>> nmScan['127.0.0.1'].hostname()
'localhost'

>>> nmScan['127.0.0.1'].state()
'up'

>>> nmScan['127.0.0.1'].all_protocols()
['tcp']

>>> nmScan['127.0.0.1']['tcp'].keys()
[80, 25, 443, 22, 111]

>>> nmScan['127.0.0.1'].has_tcp(22)
True

>>> nmScan['127.0.0.1'].has_tcp(23)
False

>>> nmScan['127.0.0.1']['tcp'][22]
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}

>>> nmScan['127.0.0.1'].tcp(22)
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}

Let's talk about a few of the methods used above. The method all_protocols() returns the protocol for the current network being scanned. The method keys() returns all the active ports available within the specified range.

When we used the keys() method on our local computer, only the port 80 was returned, because no other port in the specified range is active.

Integrating Port Scanner with Nmap

Note:In last command an error is raised. This is because in command nmScan['127.0.0.1']['tcp'].keys(), only key value obtained is [80], whereas in last line we are specifing [22].

Below we have a simple program, to scan and list the ports for a given host:

import nmap
# initialize the port scanner
nmScan = nmap.PortScanner()

# scan localhost for ports in range 21-443
nmScan.scan('127.0.0.1', '21-443')

# run a loop to print all the found result about the ports
for host in nmScan.all_hosts():
     print('Host : %s (%s)' % (host, nmScan[host].hostname()))
     print('State : %s' % nmScan[host].state())
     for proto in nmScan[host].all_protocols():
         print('----------')
         print('Protocol : %s' % proto)
 
         lport = nmScan[host][proto].keys()
         lport.sort()
         for port in lport:
             print ('port : %s\tstate : %s' % (port, nmScan[host][proto][port]['state'])

Host : 127.0.0.1 (localhost) State : up ---------- Protocol : tcp port : 22 state : open port : 25 state : open port : 80 state : open port : 111 state : open port : 443 state : open