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 iptest
-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 blockedDifferent 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': , 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]: ''.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;
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.