Use Python3 to create a TCP port scanner and a python3 Port Scanner
In the initial stage of penetration testing, we usually need to collect information about attack targets, and port scanning is a crucial step in information collection. Through port scanning, we can find out which services are open to the target host, and even predict certain vulnerabilities based on the service. TCP port scanning is generally divided into the following types:
TCP connect scan: Also known as full connection scan. This method is used to directly connect to the target port and complete the TCP three-way handshake process. The scan results are relatively accurate, however, it is slow and can be easily detected by the target system.
Tcp syn scan: This method sends a SYN packet, starts a TCP session, and waits for the target response packet. If an RST packet is received, the port is closed. if a SYN/ACK packet is received, the corresponding port is opened.
Tcp FIN scan: in this way, a FIN packet indicating to remove an active TCP connection is sent to the other party to close the connection. If an RST packet is received, the corresponding port is closed.
Tcp xmas scan: This method sends packets with PSH, FIN, URG, and TCP flag set to 1. If an RST packet is received, the corresponding port is closed.
Next we will use Python3 to implement a TCP full-connection port scanner. Next we will go to the programming stage.
Coding practices
Full connection Scan
The core method is to establish TCP connections for different ports and determine whether the port is opened based on whether the connection is successful. Now we can implement the simplest port scanner:
#!/usr/bin/python3# -*- coding: utf-8 -*-from socket import *def portScanner(host,port): try: s = socket(AF_INET,SOCK_STREAM) s.connect((host,port)) print('[+] %d open' % port) s.close() except: print('[-] %d close' % port)def main(): setdefaulttimeout(1) for p in range(1,1024): portScanner('192.168.0.100',p)if __name__ == '__main__': main()
The core of this Code isportScanner
Function. It can be seen from the content that only a simple TCP connection is established. If the connection is successful, it is determined that the port is opened. Otherwise, it is regarded as closed. Let's take a look at the running results:
This scan seems to be too inefficient, but it is actually very slow, because we have set the default timeout time to 1 second. If this is to scan 10000 ports, would it be necessary to wait for a while? The simplest way is to useMultithreading
To improve efficiency, although python's multithreading is a little too weak, at least we can use the time we wait to do something else. In addition, the number of ports scanned previously is large, and the displayed information seems inconvenient. This time, we only show what we care about.Opened Port
And the number of opened ports is displayed at the end of the scan.
#!/usr/bin/python3# -*- coding: utf-8 -*-from socket import *import threadinglock = threading.Lock()openNum = 0threads = []def portScanner(host,port): global openNum try: s = socket(AF_INET,SOCK_STREAM) s.connect((host,port)) lock.acquire() openNum+=1 print('[+] %d open' % port) lock.release() s.close() except: passdef main(): setdefaulttimeout(1) for p in range(1,1024): t = threading.Thread(target=portScanner,args=('192.168.0.100',p)) threads.append(t) t.start() for t in threads: t.join() print('[*] The scan is complete!') print('[*] A total of %d open port ' % (openNum))if __name__ == '__main__': main()
Run the command to check the effect, such:
Does it seem much more convenient? So far, the efficiency problem has been solved. Now we need to add a parameter resolution function for the scanner to make it look like this, you cannot change the scan target and port every time!
For Parameter Parsing, we will use the standard module that comes with python3.argparse
In this way, we can save the trouble of parsing strings ourselves! Let's look at the code below:
#!/usr/bin/python3# -*- coding: utf-8 -*-from socket import *import threadingimport argparselock = threading.Lock()openNum = 0threads = []def portScanner(host,port): global openNum try: s = socket(AF_INET,SOCK_STREAM) s.connect((host,port)) lock.acquire() openNum+=1 print('[+] %d open' % port) lock.release() s.close() except: passdef main(): p = argparse.ArgumentParser(description='Port scanner!.') p.add_argument('-H', dest='hosts', type=str) args = p.parse_args() hostList = args.hosts.split(',') setdefaulttimeout(1) for host in hostList: print('Scanning the host:%s......' % (host)) for p in range(1,1024): t = threading.Thread(target=portScanner,args=(host,p)) threads.append(t) t.start() for t in threads: t.join() print('[*] The host:%s scan is complete!' % (host)) print('[*] A total of %d open port ' % (openNum))if __name__ == '__main__': main()
Take a look at the running effect, such:
At this point, our port scanner is basically complete. Although the function is relatively simple, it aims to express the basic implementation ideas of the port scanner! More detailed functions can be gradually improved based on this basic structure!
Summary
This section describes how to implement a simple port scanner in Python3. In this experiment, the Tcp full connection mode is used to continuously try to connect the host port to determine the port opening status, although there are some shortcomings, this method is most suitable for beginners to learn. It will not be difficult to learn more complex methods later. A friend who wants to draw a line between the Protocol and the port can output the protocol at the same time based on the contrast between the Protocol and the port. This looks better. As for more detailed functions, I will leave them for you to practice!