This rainy night is too long. Insomnia, Who is in my dreams? Singing
Security should know the importance of port scanning in the process of penetration testing and vulnerability scanning. Its technology with URL crawling constitutes the first stage of vulnerability scanning, namely the collection of target information. Therefore, the development of an efficient and stable port scanner often determines the quality of the vulnerability scanner. So when it comes to port scanners, we often think of artifacts such as nmap and masscan, which are the benchmarks in this field. But this article is not to introduce these tools, but to talk about how to develop an efficient and stable port scanner.
The port scanner, as its name suggests, is to detect whether a port on the server is open. The principle can be divided into many types of detection methods, such as tcp three-way handshake scanning, syn scanning, etc. This article does not intend to introduce these scanning methods in detail. The difference, interested can look at the nmap document, a detailed introduction to these types of scanning methods.
Then talk about the focus of this article, based on these days I researched and tried to use python, go to develop tcp scanner, tcp-syn scanner, and compare the speed performance and stability difference between them, the test results will be made here. Record and share the code and program.
Note: The Github address of the code used in this article will be given at the end of the article, which can be tested by everyone. The code test environment is centos7.
Python’s Socket module can create sockets and create tcp three-way handshake connections to detect whether the target port is alive. This article will use the socket module to write tcp scans and syn scans, and compare the differences between the two.
Come and see the code:
Explain: You can see that this code scans 1024 ports for 102s. Of course, the code does not use multi-threading, coroutine, etc. to improve scanning efficiency (using the coroutine test to overscan 65,535 ports takes about 400s), because python is here. The ability of the aspect is relatively weak; since the tcp three-way handshake is established during the scanning process, resources are consumed.
Compared with tcp scanning, the tcp syn scanning method is more concealed and more resource-saving. How to use the socket module to implement tcp syn scanning? SOCK_RAW is needed here, which is relatively rare in socket programming and there is not much information.
One thing to note is that you need to install dependencies on your system before running this code:
Explanation: From the point of view of the running results, it is not very accurate, and the speed is not fast. It is not clear whether there is a problem in the code.
In addition to the socket module, Python also has a scapy module, which can be used to simulate the delivery of packets, but can only be used under linux. This module is not recommended for other operating systems.
The code is here:
Description: Since scapy can send multiple syn packages at once, the speed is faster than socket, but the stability is not very good.
The article mentioned nmap at the beginning, in fact, you can also directly call nmap in python, see the code:
Since the nmap scanning speed is relatively slow, only the 4 ports are scanned here, and the speed is not compared. Of course, the stability is still possible.
I have been using the python language to develop a port scanner. However, due to the weakness of Python in multithreading, the performance of the scanner can be imagined. Therefore, I have tried to develop a port scanner by taking advantage of the high concurrency of the go language. (Off topic: For this reason, I spent half a day reading the basics of the go language, barely understood the scan code, and made some changes)
Look at the code directly:
I will not explain the code (I added some comments in the code, it should be roughly understandable), this article does not intend to introduce the usage of go, after all, I am just beginning to learn go, interested can look at go documentation, Then look back at this code.
Code running results:
Note: Because it is a tcp scan, it still accounts for a lot of resources, and the test found that the stability is not very good.
Look at the code to see the code:
Code running results:
That’s right, it’s 2s! I tested the scan full port (0-65535), about 120s, and the stability is good.
After the previous tests, we can easily find that in the performance of concurrent, go wins python, but go is not suitable for complex logic processing, and web development. So how to integrate python and go? Here I think of two options, the first one to package the go language into a .so dynamic link library, which can be called using the python ctypes module; the second is to write the interface into a python call. The way to write an interface is relatively simple, so I won’t introduce it here. Let’s talk about how to package go, that is, how to use python to call go’s method or function.
First look at the modified tcp_syn_scan.go code:
Then use go’s own build command to package it into a .so library:
After packaging, you will get a tcp_syn_scan.so and a tcp_syn_scan.h. Then use the following python code to call the Scan() function in the Go code to create a tcp_syn_scan.py file.
Code running results:
Description: Pretty native go, using python to call go will lose some performance, but overall it is OK.
The conclusion of this article is that you can use go to develop a scanning module (better performance), combined with python calls.
This article code project address: https://github.com/tengzhangchao/PortScan