Industrial Equipment

Introduction to building a scanner

1. Establish a Python development environment
1. Download environment
The Python download site (http://www.python.org/download/) provides Python installation packages on Windows, Mac OS X and Linux.

If you’re running Mac OS X or Linux, a Python interpreter is pre-installed on your system.

The installer provides program developers with the Python interpreter, standard library, and several built-in modules. The Python standard library and built-in modules provide a wide range of functionality, including built-in data types, exception handling, numeric and math modules, and file-handling functions such as

Cryptographic services, interoperability with operating systems, network data processing, and interaction with IP protocols, among many other useful modules. At the same time, program developers can easily install any third-party software packages. A full list of third-party packages can be seen at (http://pypi.python.org/pypi/)

2. Install third-party libraries
Later, we will utilize python’s python-nmap package to process the results of the NMAP scan tool. The following example describes how to download and install the python-nmap package, this method can also be used to install other packages

Because I am using the kali system here, I will use the kali system for demonstration. I also recommend you to use the kali system. After all, it is a special system for penetration testing. Many of the scripts we write later need to cooperate with the penetration testing tools inside.

The kali system will pre-install pip, so we can directly execute the following code

pip install python-nmap
The result is as follows, the installation is successful

I will tell you in advance if there are packages that need to be installed when writing scripts, you only need to know how to install them now.

In recent years, the python source code has been extended into two branches of 2.x and 3.x. In general, I use python3.10. If there are special circumstances, I will tell you in advance (the version does not need to be the same as mine, just 3.x).

3. Interpreted python and interactive python
The difference between interpretive and interactive is the difference between non-interactive and interactive, simply give an example

[1], interpretive
In fact, it is equivalent to calling the interpreter to interpret after the file is generated, that is, to execute the code inside

For example, we create a new hello.py file with the following contents

print(“hello world!”)
At this point, the file has been generated, and then execute the following command in the directory terminal, you can mobilize the interpreter to execute the code in it

python hello.py
At this time, the terminal will display the output result, output “hello world!”,

[2], interactive
In addition, python has interactive capabilities, and programmers can call the python interpreter and “communicate” directly with the interpreter. It is equivalent to calling the interpreter all the time, and the interactive interpreter will execute immediately after each command is entered

Enter python in the terminal to enter the interactive python, and the command entered at this time will be executed directly, the effect is as follows

2. Introduction to Python language
In the following content, we will explain variables, data types, strings, complex data structures, networks, selection, loops, file handling, exception handling, and interacting with the operating system. To show this, we’ll build a simple TCP-style vulnerability scanner that reads notification messages from services and compares them to known vulnerable versions of the service, as an experienced programmer, You may find some of the initial sample code to be very ugly in design, in fact, we hope that you will develop on the code base to make it elegant.

3. Introduction to variables, strings, lists, and dictionaries
So, let’s start with the basics of any programming language – variables!

1. Variables
In python, the data corresponding to variables is stored in memory. This location in memory can store different values, such as integers, real numbers, booleans, strings, or more complex data structures, such as lists or dictionaries. In the following code, we define a variable to store an integer and a prompt message to store a string.

port = 21
banner = “FreeFloat FTP Server”
print(“[+] Checking for “+banner+” on port “+str(port))
In order to concatenate these two variables into a string, we must use the str() function to convert the port to a character type, the result is as follows

[+] Checking for FreeFloat FTP Server on port 21
How about this statement, I believe that the friends of infiltration will be familiar with it, it came from this way, and we will use it later.

In addition, defining variables in python is different from other languages. It does not have to declare the type of the variable. On the contrary, the python interpreter determines the type of the variable and the size of the space reserved for him in memory.

Consider the following example, where we correctly declare a string, an integer, a list and a boolean, and the interpreter automatically and correctly recognizes the type of each variable (the type function is used to return the type of a variable).
banner = “FreeFloat FTP Server” # 字符串类型
type(banner)
# <type ‘str’>

port = 21 # 整型
type(port)
# <type ‘int’>

portList=[21,22,80,110] # 列表类型
type(portList)
# <type ‘list’>

portOpen = True # 布尔类型
type(portOpen)
# <type ‘bool’>

2. String
The string module in python provides a series of very powerful string manipulation methods. Read http://docs.python.org/library/string.html for full usage.

Let’s look at a few commonly used functions. Consider the use of the following functions,

The upper() method converts lowercase letters in a string to uppercase letters,

The lower() method converts all uppercase letters in the string to lowercase,

The replace(old,new) method replaces old (old string) in the string with new (new string),

The find() method detects whether a specified substring is contained in a string.

For example the following code

banner = “FreeFloat FTP Server”
print(banner. upper())
# FREEFLOAT FTP SERVER

print(banner. lower())
# freefloat ftp server

print(banner. replace(‘FreeFloat’,’Ability’))
# Ability FTP Server

print(banner. find(‘FTP’))
#10
3. List
Python’s data structure, the list, provides a way to store a set of data. The elements in this set of data can be of any data type. In addition, there are some built-in methods for manipulating lists, such as adding, removing, inserting, popping, getting index, sorting, counting, sorting and reversing elements

Consider the following example of a program that builds a list by adding elements using append(), printing the items, and then sorting them before outputting them again. Programmers can find the index of a particular element (such as 80 in the example), and in addition, specified elements can be moved.
portList = []
portList.append(21)
portList.append(80)
portList.append(443)
portList.append(25)
print(portList)
# [21, 80, 443, 25]

portList.sort()
print(portList)
# [21, 25, 80, 443]

pos = portList.index(80)
print(“[+] There are “+str(pos)+” ports to scan before 80.”)
# [+] There are 2 ports to scan before 80.

portList.remove(443)
print(portList)
# [21, 25, 80]

cnt = len(portList)
print(“[+] Scanning “+str(cnt)+” Total Ports.”)
# [+] Scanning 3 Total Ports.

4. Dictionary
Python’s data structure, the dictionary, provides a hash table that can store any number of python objects. The elements of a dictionary consist of keys and values, let’s continue with our vulnerability scanner example to explain python’s dictionaries. When scanning specific TCP ports, it can be useful to have a dictionary containing common service names for each port. Building a dictionary, we can look up a key like ftp and return the value 21 associated with the port.

When we create a dictionary, each key and its value are separated by a colon, and at the same time, we separate the elements with a comma. Note that the .keys() function will return a list of all the keys of the dictionary, and the .items() method will return a list of the dictionary’s elements. Next, we verify that the dictionary contains the specified key (ftp), and along with the key, the value 21 is returned.
services = {‘ftp’:21,’ssh’:22,’smtp’:25,’http’:80}
services.keys()
# [‘ftp’, ‘smtp’, ‘ssh’, ‘http’]

services.items()
# [(‘ftp’, 21), (‘smtp’, 25), (‘ssh’, 22), (‘http’, 80)]

services.has_key(‘ftp’)
# True

services[‘ftp’]
# 21

print(“[+] Found vuln with FTP on port “+str(services[‘ftp’]))
#Found vuln with FTP on port 21

Fourth, use the network, iterators, exception handling, modules, etc.
1. Network
The socket module (socket) provides a library that enables python to establish a network connection and is used to establish a connection between a client program and a server program.

Let’s quickly write a script to get the target port information. After connecting to a specific IP address and port, our script will print a prompt message. After that, we use the connect() function to connect to the IP address and port. Once connected, you can read and write through the socket. We store the fetched result in a variable and print it to the server.

import socket # import socket module
socket.setdefaulttimeout(2) # After two seconds and not connected, enter the next operation
s = socket.socket() # create socket
s.connect((“192.168.95.148”,21)) # Initialize tcp connection
ans = str(s.recv(1024)) # Receive tcp data, return byte data, and receive up to 1024 bytes each time
print(ans)
# 220 FreeFloat Ftp Server (Version 1.00).
The above code can implement a simple port 21 service detection function, replace the ip with the target you want to detect, and you can detect the specific service information of the target’s port 21.

2. Condition selection
Like most programming languages, python provides a conditional selection method, through the if statement, to establish a logical expression to judge the result of the selection. Continuing with our script, we want to know, whether the specified FTP server is vulnerable. To do this, we compare our results to known vulnerable FTP server versions.

Four vulnerable ftp service versions are given here, and the modified code is as follows
import socket
socket.setdefaulttimeout(2)
s = socket.socket()
s.connect((“192.168.95.148”,21))
ans = str(s.recv(1024))
if “FreeFloat Ftp Server (Version 1.00)” in ans:
print(“[+] FreeFloat FTP Server is vulnerable.”)
elif “3Com 3CDaemon FTP Server Version 2.0” in ans:
print(“[+] 3CDaemon FTP Server is vulnerable.”)
elif “Ability Server 2.34” in ans:
print(“[+] Ability FTP Server is vulnerable.”)
elif “Sami FTP Server 2.0.2” in ans:
print(“[+] Sami FTP Server is vulnerable.”)
else:
print(“[-] FTP Server is not vulnerable.\n”)

3. Exception handling
Even if a programmer writes a program with correct syntax, the program may still run or execute incorrectly. Consider a classic run error – division by zero. Because zero cannot divide, the python interpreter displays a message telling the programmer about the error: the error stopped the program. as follows

You can see that the program ends directly, and an error message appears, but we don’t want the program to end, and if we want it to continue executing after reporting an error, we should introduce our catch exception operation

You can use the try/except statement to catch exceptions.

The following is the syntax of a simple try….except…else:

try:
<statement> # run other code
except <name>:
<statement> #If a ‘name’ exception is raised in the try part
except <name>, <data>:
<statement> # If a ‘name’ exception is raised, get additional data
else:
<statement> #if no exception occurs
For example, the following piece of code can successfully catch the exception, so that it can play a program error but

try:
print(“1237/0=” + str(1237 / 0))
except:
print(“error”)
else:
print(“right”)
In this way, the 1237/0 will still be recognized as an error, but it will not directly end the program and output an error message, but will output the error we defined.

Now we go ahead and update our script

import socket
socket.setdefaulttimeout(2)
s = socket. socket()
try:
s.connect((“192.168.95.149”, 21))
except Exception as e:
print(“[-] Error = “+str(e))
4. Function
In python, functions provide organized, reusable pieces of code. In general, this allows programmers to write code to perform individual or linked actions.

Although python provides many built-in functions, programmers can still create custom functions. The keyword def() starts a function, and programmers can put any variable in parentheses. These variables are then passed around, which means that any changes to these variables inside the function will affect the value of the calling function. Continuing with our FTP vulnerability scanner example, let’s create a function that simply connects to the FTP server and returns a prompt
import socket

def retBanner(ip, port):
try:
socket.setdefaulttimeout(2)
s = socket.socket()
s.connect((ip, port))
banner = s.recv(1024)
return banner
except:
return

def main():
ip1 = ‘192.168.95.148’
ip2 = ‘192.168.95.149’
port = 21
banner1 = retBanner(ip1, port)
if banner1:
print(‘[+] ‘ + ip1 + ‘: ‘ + banner1)
banner2 = retBanner(ip2, port)
if banner2:
print(‘[+] ‘ + ip2 + ‘: ‘ + banner2)

if __name__ == ‘__main__’:
main()

After returning the information, our script needs to check against known vulnerable programs. This also reflects the singularity and correlation of functions. The function checkVulns() uses the obtained information to judge the vulnerabilities of the server

def checkVulns(banner):
if ‘FreeFloat Ftp Server (Version 1.00)’ in banner:
print(‘[+] FreeFloat FTP Server is vulnerable.’)
elif ‘3Com 3CDaemon FTP Server Version 2.0’ in banner:
print(‘[+] 3CDaemon FTP Server is vulnerable.’)
elif ‘Ability Server 2.34’ in banner:
print(‘[+] Ability FTP Server is vulnerable.’)
elif ‘Sami FTP Server 2.0.2’ in banner:
print(‘[+] Sami FTP Server is vulnerable.’)
else:
print(‘[-] FTP Server is not vulnerable.’)
return
5. Iteration
In the last chapter, you may have noticed that we wrote almost the same code three times to detect three different IP addresses.

Instead of doing one thing over and over, it’s easier to use a for loop to facilitate multiple elements. For example: if we want to facilitate the entire subnet with IP addresses from 192.168.98.1 to 192.168.95.254, we need to use a for loop to traverse from 1 to 255 to print out the information in the subnet.

for x in range(1,255):
print(“192.168.95.”+str(x))
Likewise, we may need to iterate through the list of known ports to check for vulnerabilities. Instead of a series of numbers, we can iterate over them through a list of elements.

portList = [21,22,25,80,110]
for port in portList:
print(port)
Continue to update our script. The updated code is as follows. As the program has the ability to traverse IP and ports, we will also update our vulnerability detection script. Now, our script will test the telnet provided by all 254 IP addresses , SSH, smtp, http,

import socket

def retBanner(ip, port):
try:
socket.setdefaulttimeout(2)
s = socket.socket()
s.connect((ip, port))
banners = s.recv(1024)
return str(banners)
except Exception as e:
print(“扫描错误: “, e)
return

def checkVulns(banners):
if ‘FreeFloat Ftp Server (Version 1.00)’ in banners:
print(‘[+] FreeFloat FTP Server is vulnerable.’)
elif ‘3Com 3CDaemon FTP Server Version 2.0’ in banners:
print(‘[+] 3CDaemon FTP Server is vulnerable.’)
elif ‘Ability Server 2.34’ in banners:
print(‘[+] Ability FTP Server is vulnerable.’)
elif ‘Sami FTP Server 2.0.2’ in banners:
print(‘[+] Sami FTP Server is vulnerable.’)
else:
print(‘[-] FTP Server is not vulnerable.’)
return

def main():
portList = [21, 22, 25, 80, 110, 443]
for x in range(106, 107):
ip = ‘192.168.1.’ + str(x)
for port in portList:
banner = retBanner(ip, port)
if banner:
print(‘[+] ‘ + ip + ‘:’ + str(port) + banner)
checkVulns(banner)
else:
print(‘[+] ‘ + ip + “:” + str(port) + ” :do not have vuln”)

if __name__ == ‘__main__’:
main()

6. File I/O
While our script already has some if statements that help detect vulnerability messages, it would be nice to add a list of vulnerabilities. For example, let’s say we have a text file called vuln_banners.txt.

Each line of this file lists the specific service version and known previous vulnerabilities. We don’t need to build a huge if statement, let’s read this text file and use it to determine whether our prompt information has vulnerabilities.

It is the following txt file that contains many historical vulnerabilities

6. File I/O
While our script already has some if statements that help detect vulnerability messages, it would be nice to add a list of vulnerabilities. For example, let’s say we have a text file called vuln_banners.txt.

Each line of this file lists the specific service version and known previous vulnerabilities. We don’t need to build a huge if statement, let’s read this text file and use it to determine whether our prompt information has vulnerabilities.

It is the following txt file that contains many historical vulnerabilities

def checkVulns(banner):
f = open(“vuln_banners.txt”, ‘r’)
for line in f.readlines():
if line.strip(‘\n’) in banner:
print(“[+] Server is vulnerable: ” + banner.strip(‘\n’))

7. SYS module
The built-in sys module provides the ability to access and maintain the python interpreter. This includes prompts, versions, maximum integer values, available modules, path hooks, standard error, stdin and output locations, and command-line arguments for interpreter invocations. You can find more information on this in python’s online module documentation (http://docs.python.org/library/sys).

Interacting with the sys module can be useful when creating python scripts. We may, for example, want to parse command-line arguments while the program is running. Consider our vulnerability scanner,

What if we wanted to pass the name of the text file as a command line argument? The index sys.argv contains all commands with parameters. The first index sys.argv[0] contains the name of the python script interpreter. The remaining elements of the list contain all of the following command-line arguments. So if we only want to pass additional arguments, sys.argv should contain two elements.

Take a look at the following example

import sys
if len(sys.argv)==2:
filename = sys.argv[1]
print “[+] Reading Vulnerabilities From: “+filename
We use the command line to execute

sys.argv[1] is demo2.py

sys.argv[2] is the first parameter a.txt

And so on

8. OS module
The built-in OS module provides rich capabilities to interact with operating systems such as MAC, NT, and Posix. This module allows programs to be independent of the operating system environment. The file system, user database and permissions interact.

Consider, for example, that in the previous chapter, the user passed a filename as a command-line argument. He can verify that the file exists and that the current user has permission to process the file. If it fails, it will display a message to display an appropriate error message to the user.

import sys
import os

if len(sys.argv) == 2: # The command line passed a parameter
filename = sys.argv[1] # extract the first parameter
if not os.path.isfile(filename): # path does not exist
print(‘[-]’ + filename + ‘does not exist.’)
exit(0)
if not os.access(filename, os.R_OK): # No access permission
print(‘[-] ‘ + filename + ‘ access denied.’)
exit(0)
print(‘[+] Reading Vulnerabilities From: ‘ + filename) # read the file normally
Now we can reassemble the various parts of the vulnerability scanner. Don’t worry that it will terminate incorrectly or lack the ability to use threads or better analyze the command line during execution. We will continue to improve this script in a later blog, and the blogger’s subsequent scripts will be updated on github