python's network (nmap, IPy, dnspython)

1. Port Scan

It's not enough just to know if the hosts on the network are reachable. In many cases, we need a port scanner.Use port scanner inches for security detection and *** prevention.For example, on May 12, 2017, a worldwide outbreak of Wannacry extorting worms based on the Windows Network Sharing Protocol occurred.In just five hours, more than 100 countries, including the United States, China, Russia and Europe as a whole, have been subjected to the ever-lasting blue virus ***, especially in universities, large intranets and government agencies. Computers *** have been blackmailed for high ransoms to decrypt recovery files, causing significant data loss.Eternal Blue uses port 445 of the Windows system for worms***. Some operators have blocked port 445 on their backbone networks, but education networks and a large number of intranets do not have this limitation, which has resulted in the proliferation of Eternal Blue-Lasso worms.

Therefore, as an engineer, on the one hand, we need to develop good habits in daily maintenance, such as configuring firewalls, isolating networks, closing unnecessary services, and updating patches in time; on the other hand, we can master some security-related tools to make security precautions in daily life and conduct security detection in emergent situations.In this section, we will show you how to use Python for port scanning.With the port scanner, we can quickly understand which unnecessary ports are opened by the host in order to eliminate security risks in time.
In this section, we will write a port scanner in Python, introduce the well-known port scanning tool nmap, and finally, call nmap in Python code to do port scanning.

1. Scan ports using nmap

The Python-nmap module is an encapsulation of nmap commands.Nmap is a well-known network detection and security scanner, short for Network Mapper.Nmap can perform Host Discovery, Port Scanning, Version Detection, Operating System Detection, and nmap is one of the required software for network administrators.Nmap is widely used in the security field because of its powerful, cross-platform, open source, rich documentation and many other advantages.
nmap needs to be installed before use.As follows:

(1) Install namp

-bash-4.2# yum -y install nmap

Nmap is flexible and powerful, so it has many command line options.When using nmap, you first need to determine which hosts to scan, then how to scan (such as what technology to use and which ports to scan).
Nmap has a very flexible way of specifying the hosts that need to be scanned and can be tested using the -sL option of the nmap command.The -sL option simply prints the IP list and does nothing.As follows:

Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 16:57 CST
Nmap scan report for 192.168.0.0 (192.168.0.0)
Nmap scan report for 192.168.0.1 (192.168.0.1)
Nmap scan report for 192.168.0.2 (192.168.0.2)
Nmap scan report for 192.168.0.3 (192.168.0.3)
Nmap done: 4 IP addresses (0 hosts up) scanned in 2.01 seconds
-bash-4.2# nmap -sL 192.168.1.80/30

Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 16:57 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Nmap scan report for 192.168.1.81 (192.168.1.81)
Nmap scan report for 192.168.1.82 (192.168.1.82)
Nmap scan report for 192.168.1.83 (192.168.1.83)
Nmap done: 4 IP addresses (0 hosts up) scanned in 2.01 seconds

nmap provides a very flexible way to specify hosts, including specifying multiple IP s simultaneously, hosts through network segments, hosts through wildcards, and so on.As follows:

nmap -sL 47.100.98.242 14.215.177.39
nmap -sL 47.100.98.*
nmap -sL 47.100.98.242,243,245
nmap -sL 47.100.98.242-250
nmap -sL 47.100.98.* --exclude 47.100.98.242
nmap -sL 47.100.98.242/30

In addition to the way the host is specified above, we can also save the IP address in text and read the IP address in the file with the -iL option.As follows:

-bash-4.2# vim ip.list 

192.168.1.80
127.0.0.1

-bash-4.2# nmap -iL ip.list

Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 21:32 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Host is up (0.0000050s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
111/tcp  open  rpcbind
8888/tcp open  sun-answerbook

Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000060s latency).
Not shown: 995 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
25/tcp   open  smtp
111/tcp  open  rpcbind
631/tcp  open  ipp
8888/tcp open  sun-answerbook

(2) Scan continuous ports

-bash-4.2# nmap -p20-25 47.100.98.242

(3) Do not scan ports, just judge if the host is reachable

nmap -sL ip
nmap -sn ip

test

-bash-4.2# nmap -sL 192.168.1.80

Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:03 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Nmap done: 1 IP address (0 hosts up) scanned in 2.01 seconds
-bash-4.2# nmap -sn 192.168.1.80

Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:03 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Host is up.
Nmap done: 1 IP address (1 host up) scanned in 2.01 seconds

(4) Host Discovery

Port scanning is the focus of nmap, in addition, we can use nmap to check all the online hosts on the network, similar to the functions listed in the previous section for all active hosts on the network.Using the -sP or -sn option, you can tell nmap not to scan ports, just to determine if the host is reachable.As follows:

[root@bogon ~]# nmap -sP 47.100.98.*
Starting Nmap 6.40 ( http://nmap.org ) at 2020-03-01 00:25 CST
Nmap done: 256 IP addresses (0 hosts up) scanned in 206.44 seconds

[root@bogon ~]# nmap -sn 47.100.98.*
Starting Nmap 6.40 ( http://nmap.org ) at 2020-03-01 00:35 CST
Nmap done: 256 IP addresses (0 hosts up) scanned in 205.38 seconds

(5) Port scan

Port scanning is the most basic and core function of nmap, which determines the opening of TCP/UDP ports on the target host.Without adding any parameters, the host is scanned for ports.By default, nmap scans the 1000 most commonly used port numbers.As follows:

[root@192 ~]# nmap 10.166.224.140

During port scanning, nmap provides parameter control port scanning of large M.Includes port scan protocol, port scan type, port number scanned.As follows:

Port scan protocol: T (TCP), U (UDP), S (SCTP>, P (IP);

Port scan type: -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans;

Port number scanned: -p 80,443-p 80-160

Port scan protocol, scan type, and port number related options in nmap can be combined.As follows:

-p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9

nmap divides the port into six states by probing, and the meaning of each state is given in the table below.

port status State Meaning
open Ports are open
closed Port is closed
filtered Port is blocked by firewall IDS/IPS, unable to confirm its status
unfiltered The port is not blocked, but it needs to be further determined if it is open or not
open|filtered Ports are open or blocked
closed|filtered Port is closed or blocked

Different port scan types can be used when scanning ports.Common types of port scanning are as follows:

TCP SYNC SCAN: Semi-open scan, a type of scan that sends a SYN packet, initiates a TCP session, and waits for a response packet.If a reset package is received, the port is closed; if a SYNC/ACK package is received, the port is open.
TCP NULL SCAN: The NULL scan sets all flag bits in the TCP header to NULL.If an RST packet is received, the port is closed.
TCP FIN SCAN: A TCP FIN scan sends a FIN packet that indicates the end of an active TCP connection and asks the other party to close the connection.If an RST packet is received, the port is closed.TCPXMASSCAN: TCPXMAS scan sends packets with PSH, FIN, URG and TCP flag set to 1. If an RST packet is received, the phased port is closed.

(6) Version Detection

nmap also detects versions when it scans ports.Version monitoring is used to determine the application and version information running on an open port.As follows:

-bash-4.2# nmap -sV 10.166.224.140

Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:06 CST
Nmap scan report for 10.166.224.140 (10.166.224.140)
Host is up (0.00038s latency).
All 1000 scanned ports on 10.166.224.140 (10.166.224.140) are filtered

Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.13 seconds

(7) Operating system monitoring

The operating system detects information such as the type of operating system and device type used to monitor the host.nmap has a rich system database that identifies more than 2600 operating systems and device types.As follows:

-bash-4.2# nmap -sO 192.168.1.80

Starting Nmap 6.40 ( http://nmap.org ) at 2020-05-14 17:05 CST
Nmap scan report for 192.168.1.80 (192.168.1.80)
Host is up (0.000018s latency).
Not shown: 249 closed protocols
PROTOCOL STATE         SERVICE
1        open          icmp
2        open|filtered igmp
6        open          tcp
17       open          udp
103      open|filtered pim
136      open|filtered udplite
255      open|filtered unknown

Nmap done: 1 IP address (1 host up) scanned in 3.21 seconds

2. Port scan using python-nmap

In the previous section, we spent more time introducing nmap.Python-nmap for Python only tends to encapsulate nmap, so to use Python-nmap, you must first understand nmap.The main improvement of Python-nmap over nmap is the processing of output results.Python-nmap saves the output of nmap in the space. We only need Python's dictionary to get the output information of nmap. We do not need to parse the result of nmap through string processing and regular expressions like Shell scripts.Python-nmap perfectly combines the power of nmap with the excellent expressive power of Python. Python-rich data structures are used to save the results for subsequent processing, such as generating reports using Python-nmap.

Python-nmap is an open source library, so you need to install it manually before using it.As follows:

pip3 install python-nmap

The use of Python-nmap is very simple. We can do basic nmap port scanning by simply creating a PortScarmer object and calling the scan method of the object.As follows:

-bash-4.2# ipython
Python 3.8.1 (default, Mar  9 2020, 12:35:12) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import nmap                                              

In [2]: nm = nmap.PortScanner()                                  

In [3]: nm.scan('192.168.1.80','22-1000')                        
Out[3]: 
{'nmap': {'command_line': 'nmap -oX - -p 22-1000 -sV 192.168.1.80',
  'scaninfo': {'tcp': {'method': 'syn', 'services': '22-1000'}},
  'scanstats': {'timestr': 'Thu May 14 17:13:44 2020',
   'elapsed': '8.15',
   'uphosts': '1',
   'downhosts': '0',
   'totalhosts': '1'}},
 'scan': {'192.168.1.80': {'hostnames': [{'name': '192.168.1.80',
     'type': 'PTR'}],
   'addresses': {'ipv4': '192.168.1.80'},
   'vendor': {},
   'status': {'state': 'up', 'reason': 'localhost-response'},
   'tcp': {22: {'state': 'open',
     'reason': 'syn-ack',
     'name': 'ssh',
     'product': 'OpenSSH',
     'version': '6.6.1',
     'extrainfo': 'protocol 2.0',
     'conf': '10',
     'cpe': 'cpe:/a:openbsd:openssh:6.6.1'},
    111: {'state': 'open',
     'reason': 'syn-ack',
     'name': 'rpcbind',
     'product': '',
     'version': '2-4',
     'extrainfo': 'RPC #100000',
     'conf': '10',
     'cpe': ''}}}}}

When we create a PortScanner object, Python-nmap checks to see if nmap is installed in the felt system and throws a PortScannerError exception if it is not.After calling the scan method of the PortScanner object to scan, you can get the information of this scan through other methods of this class.Such as command line parameters, host list, scanning methods, and so on.As follows:

In [4]: nm.command_line()                                        
Out[4]: 'nmap -oX - -p 22-1000 -sV 192.168.1.80'

In [5]: nm.scaninfo()                                            
Out[5]: {'tcp': {'method': 'syn', 'services': '22-1000'}}

In [6]: nm.all_hosts()    #All Hosts                                       
Out[6]: ['192.168.1.80']

Python-nmap also provides detailed information about a single host by using the host address as the key.Includes getting host network status, all protocols, all open port numbers, services corresponding to port numbers, etc.As follows:

In [8]: nm['192.168.1.80'].state()                               
Out[8]: 'up'

In [9]: nm['192.168.1.80'].all_protocols()                       
Out[9]: ['tcp']

In [10]: nm.scan('47.100.98.242,127.0.0.2','21-25')              
Out[10]: 
{'nmap': {'command_line': 'nmap -oX - -p 21-25 -sV 47.100.98.242,127.0.0.2',
  'scaninfo': {'error': ['Failed to resolve "47.100.98.242,127.0.0.2".\nWARNING: No targets were specified, so 0 hosts scanned.\n'],
   'warning': ['WARNING: No targets were specified, so 0 hosts scanned.\n'],
   'tcp': {'method': 'syn', 'services': '21-25'}},
  'scanstats': {'timestr': 'Thu May 14 17:22:06 2020',
   'elapsed': '16.00',
   'uphosts': '0',
   'downhosts': '0',
   'totalhosts': '0'}},
 'scan': {}}

In [11]: nm['192.168.1.80'].key()  
Out[11]: dict_keys(['hostnames', 'addresses', 'vendor', 'status', 'tcp'])

2. Use IPy for IP management

In network design, the first thing to do is to plan the IP address.IP address planning directly affects the efficiency of routing algorithms, including network performance and scalability.In IP address planning, a large number of IP address calculations are required, including network segment, network mask, broadcast address, number of subnets, IP type, and so on.Calculating IP addresses is an interesting and error-prone task without a good tool in many computing operations.In Perl, you can use the NET::IP module, and in Python, you can use the open source IPy module to operate.

1. Introduction of IPy module

IPy module is a module that handles IP addresses. It can automatically identify the version of IP address and the type of IP address.With the IPy module, it is easy to calculate the IP address.

IPy modules are third-party open source modules, so they need to be installed before they can be used.Install using pip directly:

pip install ipy

2. Basic use of IPy module

The IPy module has an IP class that can accept IP addresses and segments in almost any format.As follows:

In [1]: import IPy 

In [2]:from IPy import IP           

In [3]: IP(0x7f000001)               
Out[3]: IP('127.0.0.1')

In [4]: IP('127.0.0.1')               
Out[4]: IP('127.0.0.1')

In [5]: IP('127.0.0.0/30')             
Out[5]: IP('127.0.0.0/30')

In [6]: IP('1080:0:0:0:8:800:200C:417A')
Out[6]: IP('1080::8:800:200c:417a')

In [7]: IP('127.0.0.0-127.255.255.255')
Out[7]: IP('127.0.0.0/8')

The IP class contains many methods for flexible IP address operations.For example:

(1) version: Get the version of the IP address

In [9]: IP('127.0.0.0-127.255.255.255') 
Out[9]: IP('127.0.0.0/8')

In [10]: IP('10.0.0.0/8').version()  
Out[10]: 4

In [11]: IP('::1').version()        
Out[11]: 6

(2) len: Number of subnet IP addresses obtained

In [12]: IP('127.0.0.0/30').len()    
Out[12]: 4

In [13]: IP('127.0.0.0/28').len()    
Out[13]: 16

(3) iptype: Type of return IP address

In [14]: IP('127.0.0.1').iptype()    
Out[14]: 'LOOPBACK'

In [15]: IP('8.8.8.8').iptype()      
Out[15]: 'PUBLIC'

(4) int: Returns the integer form of the IP address

In [16]: IP('8.8.8.8').int()         
Out[16]: 134744072

(5) strHex: Returns the hexadecimal form of an IP address

In [17]: IP('8.8.8.8').strHex()    
Out[17]: '0x8080808'

(6) strBin: Returns the binary form of the IP address

In [18]: IP('8.8.8.8').strBin()
Out[18]: '00001000000010000000100000001000'

There is a convenient function to convert IP to different formats, which will be very useful in your working environment.For example, there are two ways to store IP addresses in a database, one is to store IP addresses in a database as variable-length strings, the other is to store IP addresses in a database after converting them to integers.Converting IP addresses to integers for storage can save storage space and improve database storage efficiency and access speed.Therefore, in best practice, we generally store IP addresses in a database as numbers.When an IP address is required, the digital form of the IP address is converted to a string format of the IP address.This requirement is common, so MySQL provides two functions for converting IP addresses in string format to IP addresses in data format and IP addresses in number format to IP addresses in string format.As follows:

mysql> select INET_ATON('10.166.224.14');
+----------------------------+
| INET_ATON('10.166.224.14') |
+----------------------------+
|                  178708494 |
+----------------------------+
1 row in set (0.00 sec)

mysql> select INET_NTOA('178708494');
+------------------------+
| INET_NTOA('178708494') |
+------------------------+
| 10.166.224.14          |
+------------------------+
1 row in set (0.00 sec)

In addition to using MySQL's native functions, we can also convert string IP addresses to digital IP addresses using the int method provided by the IP class.To convert a digital IP address to a string IP address, you can create an IP object directly using a digital format.As follows:

In [9]: IP('178708494')             
Out[9]: IP('10.166.224.14')

In [10]: '{0}'.format(IP("178708494"))
Out[11]: '10.166.224.14'

3. Segment Management

The constructor of an IP class can accept IP addresses in different formats or network segments.As follows:

In [1]: from IPy import IP            

In [2]: IP('127.0.0.0/24')        
Out[2]: IP('127.0.0.0/24')

In [3]: IP('127.0.0.0-127.255.255.255')
Out[3]: IP('127.0.0.0/8')

In [4]: IP('127.0.0.0/127.255.255.255')
Out[4]: IP('127.0.0.0/31')

Segments contain multiple IP addresses. We can either use the len method or Python's built-in len function directly to get the number of IP addresses in a segment, or we can iterate over each IP using a for loop directly.As follows:

In [19]: ips = IP('10.166.224.144/28')                           

In [20]: ips.len()                                               
Out[20]: 16

In [21]: len(ips)                      
Out[21]: 16

In [22]: ip = [ip for ip in ips]                                 

In [23]: ip = [ip for i in ips]                                  

In [24]: ip                                                      
Out[24]: 
[[IP('10.166.224.144'),
  IP('10.166.224.145'),
  IP('10.166.224.146'),
  IP('10.166.224.147'),
  IP('10.166.224.148'),

With IP classes, we can also easily determine whether an IP belongs to one network segment, whether a subnet is contained in another network segment, and whether two network segments overlap.As follows:

In [25]: '10.166.224.146' in IP('10.166.224.144/28')   
//Test if ip is in a segment
Out[25]: True

In [16]: '10.166.224.144' in IP('10.166.224.144/28')
Out[16]: True

In [17]: IP('10.166.224.144/29') in IP('10.166.224.144/28')
Out[17]: True

In [18]: IP('10.166.224.0/28').overlaps('10.166.224.144/28')
Out[18]: 0

For network segments, we can easily get the network address mask and the broadcast address of the network.As follows:

In [22]: ips.netmask()              
Out[22]: IP('255.255.255.240')

In [23]: ips.broadcast()            
Out[23]: IP('10.166.224.159')

3. Resolving DNS using dnspython

1. Introduction and installation of dnspython

Dnspython is a DNS toolset implemented by Python that supports almost all record types and can be used to query, transmit, and dynamically update ZONE information, as well as TSIG (Transaction Signature) verification messages and EDNS0 (Extended DNS).Using dnspython can replace tools like nslookup and dig on the Linux command line.

dnspython is a third-party open source module and therefore needs to be installed before use:

pip3 install dnspython

2. Use dnspython for domain name resolution

dnspython provides rich APIs, where high-level APIs perform query operations based on name and type, and low-level APIs update ZONE information, messages, names, and records directly.Of all APIs, domain name queries are most commonly used.dnspython provides a DNS resolver class that uses its query method to query domain names.

dns.resolver.query(qname,rdtype=1,rdclass=1,tcp=False,source=None,raise_on_no_answer=True,source_port=0)

The query method parameters have the following meanings:

qname: The domain name you are asking for;
rdtype: Specify RR resource;

A: Address, returns the IP address to which the domain name refers;
NS: Name Server, returns the address of the server where the next level of domain name information is stored.This record can only be set as a domain name, not as an IP address.
MX: Mail exchange, return to the server address where the e-mail is received;
CNAME: Canonical Name, alias record, to map domain names;
PTR: Pointer Record, reverse parsing, converts IP address to host name, as opposed to A record.

rdclass: Network type;
TCP: Specifies whether TCP protocol is enabled for query;
Source: The address of the source of the query;
source_port: The port on which the source is queried;
raise_on_no_answer: Specifies whether an exception is triggered when the query is not answered, defaulting to True.

Before using dnspython to query DNS-related information, let's take a brief look at the dig command to compare the output of the Python program with that of the dig command.
The full name of dig is domain information groper, which is a flexible tool for detecting DNS, performing DNS lookups and displaying the answers returned from the name server of the query.Because the dig command is flexible and easy to use, most DNS administrators use dig to solve DNS problems.
Run the dig command on my host to find information about the dnspython.org domain name.The results are as follows:

[root@192 ~]# dig qiniu.lexizhi.com

; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> qiniu.lexizhi.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35907
;; flags: qr rd ra; QUERY: 1, ANSWER: 12, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;qiniu.lexizhi.com.     IN  A

;; ANSWER SECTION:
qiniu.lexizhi.com.  5   IN  CNAME   www.lexizhi.com.qiniudns.com.
www.lexizhi.com.qiniudns.com. 5 IN  CNAME   dt003.china.line.qiniudns.com.
dt003.china.line.qiniudns.com. 5 IN CNAME   tinychinacdnweb.qiniu.com.w.kunlunno.com.
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.231
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.234
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.232
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.233
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 219.147.157.66
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.228
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.235
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.229
tinychinacdnweb.qiniu.com.w.kunlunno.com. 5 IN A 150.138.180.230

;; Query time: 633 msec
;; SERVER: 192.168.79.2#53(192.168.79.2)
;; WHEN: March 02 17:29:51 CST 2020
;; MSG SIZE  rcvd: 300

(1) In Python code, you can use dnspython to query A records.As follows:

from __future__ import print_function
import dns.resolver

data = dns.resolver.query('www.lexizhi.com', 'A')
for item in data:
    print(item)
The output is as follows:
47.100.98.242

(2) NS records are implemented using dnspython using the following query methods:

from __future__ import print_function
import dns.resolver

data = dns.resolver.query('dnspython.org', 'NS')
for item in data:
    print(item)
The output is as follows:
ns-343.awsdns-42.com.
ns-518.awsdns-00.net.
ns-1253.awsdns-28.org.
ns-2020.awsdns-60.co.uk.

From the output, using the dig command or the dnspython module is the same.If you are operating on the command line, the dig command is recommended.The dnspython module is recommended if you want to use a program to manage or query DNS content.

Tags: Python network DNS Database

Posted on Thu, 14 May 2020 23:43:14 -0400 by Mohammad