Basic scripting skills are critical to becoming a master hacker. Without having developed some basic scripting skills, a beginner hacker who simply uses tools created by someone else will be condemned to the realm of script kiddies. This means that you will be limited to using tools developed by someone else, which decreases your probability of success and increases your probability of detection by antivirus (AV) software, intrusion detection systems (IDSs), and law enforcement. With some scripting skills, you can elevate yourself to the upper echelon of the master hackers!
In Chapter 8, we covered bash scripting basics and built some simple scripts, including MySQLScanner.sh, which finds systems running the ubiquitous MySQL database system. In this chapter, we begin looking at the scripting language most widely used by hackers: Python. Many of the most popular hacker tools are written in Python, including sqlmap, scapy, the Social-Engineer Toolkit (SET), w3af, and many more.
Python has some important features that make it particularly well-suited for hacking, but probably most importantly, it has a huge variety of libraries—prebuilt modules of code that can be imported externally and reused—that provide some powerful functionality. Python ships with over 1,000 modules built in, and many more are available in various other repositories.
Building hacking tools is possible in other languages too, such as bash, Perl, and Ruby, but Python’s modules make building these tools much easier.
When you install Python, you also install its set of standard libraries and modules that provide an extensive range of capabilities, including built-in data types, exception handling, numeric and math modules, file handling, cryptographic services, internet data handling, and interaction with internet protocols (IPs).
Despite all the power offered by these standard libraries and modules, you may need or want additional third-party modules. The third-party modules available for Python are extensive and are probably the reason most hackers prefer Python for scripting. You can find a comprehensive list of third-party modules at PyPI (the Python Package Index, shown in Figure 17-1) at http://www.pypi.org/.
Figure 17-1: The Python Package Index
Python has a package manager specifically for installing and managing Python packages known as pip (Pip Installs Packages). Since we are working with Python 3 here, you will need pip for Python 3 to download and install packages. You can download and install pip from the Kali repository by entering the following:
kali >apt-get install python3-pip
Now, to download modules from PyPI, you can simply enter this:
kali >pip3 install <package name>
When you download these packages, they are automatically placed in the /usr/local//lib/<python-version>/dist-packages directory. So, for instance, if you had used pip to install the Python implementation of the SNMP protocol for Python 3.6, you would find it at /usr/local/lib/python3.6/pysnmp. If you aren’t sure where a package has been placed on your system (sometimes different distributions of Linux use different directories), you can enter pip3 followed by show and the package name, as shown here:
kali >pip3 show pysnmp
Name: pysnmp
Version: 4.4.4
Summary: SNMP library for Python
Home-page: https://github.com/etingof/pysnmp
Author: Ilya Etingof <etingof@gmail.com>
Author-email: etingof@gmail.com
License: BSD
Location: usr/local/lib/python3.6/dist-packages
Requires: ptsmi, pyansl, pycryptodomex
You can see this gives you a lot of information about the package, including the directory that holds it.
As an alternative to using pip, you can download a package directly from the site (make certain that is downloaded to the proper directory), unpack it (see Chapter 9 on how to unpack software), and then run the following:
kali >python setup.py install
This will install any unpacked packages that haven’t yet been installed.
To install a third-party module created by another member of the Python community (as opposed to an officially released Python package), you can simply use wget to download it from wherever it is being stored online, uncompress the module, and then run the python setup.py install command.
As an example, let’s download and install the Python module for the port-scanning tool we used in Chapter 8, nmap, from its online repository at https://xael.org.
First, we need to download the module from xael.org:
kali >wget http://xael.org/norman/python/python-nmap/python-nmap-0.3.4.tar.gz
--2014-12-28 17:48:32-- http://xael.org/norman/python/python-nmap/python-nmap-0.3.4.tar.gz
Resolving xael.org (xael.org)...194.36.166.10
Connecting to xael.org (xael.org)|194.36.166.10|:80...connected.
--snip--
2018-21-28 17.48:34 (113 KB/s) - 'python-nmap-0.3.4.tar.gz' saved
[40307/40307]
Here, you can see we use the wget command and the full URL for the package. After the package has downloaded, you need to uncompress it with tar, as you learned in Chapter 9:
kali >tar -xzf python-nmap-0.3.4.tar.gz
Then change directories to the newly created directory:
kali >cd python-nmap-.03.4/
Finally, in that directory, install the new module by entering the following:
kali >~/python-nmap-0.3.4 >python setup.py install
running install
running build
running build_py
creating build
--snip--
running install_egg_info
writing /usr/local/lib/python2.7/dist-packages/python_nmap-0.3.4.egg.info
Innumerable other modules can be obtained this way as well. Once you’ve installed this nmap module, you can use it in your Python scripts by importing the module. More on this later. Now let’s get started on some scripting.
Now that you know how to install modules in Python, I want to cover some of the basic concepts and terminology of Python, then the basic syntax. After that, you’ll write some scripts that will be useful to hackers everywhere and that I hope will demonstrate the power of Python.
Just as with bash or any other scripting language, we can create Python scripts using any text editor. For this chapter, to keep things simple, I advise you to use a simple text editor such as Leafpad, but it’s useful to know that a number of integrated development environments, or IDEs, are available for use with Python. An IDE is like a text editor with other capabilities built in, such as color-coding, debugging, and compiling capabilities. Kali has the IDE PyCrust built in, but there are many more IDEs available to download, of which the best is arguably JetBrain’s PyCharm. This is an excellent IDE with a lot of enhancements that make learning Python easier and quicker. There is a professional version for purchase and a community edition that is free. You can find them at https://www.jetbrains.com/pycharm/.
Once you’ve completed this chapter, if you want to keep learning Python, PyCharm is an excellent tool that will help you in your development. For now, we will use a basic text editor like Leafpad to keep things simple.
Note that learning any programming language takes time and a lot of hard work. Be patient with yourself—attempt to master each of the small scripts I provide before moving on.
Now, on to some more practical concepts in Python. A variable is one of the most basic data types in programming, and you encountered it earlier in Chapter 8 with bash scripting. In simple terms, a variable is a name associated with a particular value such that whenever you use that name in your program, it will invoke the associated value.
The way it works is that the variable name points to data stored in a memory location, which may contain any kind of value, such as an integer, real number, string, floating-point number, Boolean (true or false statement), list, or dictionary. We’ll briefly cover all of these in this chapter.
To become familiar with the basics, let’s create a simple script, shown in Listing 17-1, in Leafpad and save it as hackers-arise_greetings.py.
#! /usr/bin/python3
name="OccupyTheWeb"
print ("Greetings to " + name + " from Hackers-Arise. The Best Place to Learn Hacking!")
Listing 17-1: Your first Python program
The first line simply tells your system that you want it to use the Python interpreter to run this program, rather than any other language. The second line defines a variable called name and assigns a value to it (in this case, "OccupyTheWeb"). You should change this value to your own name. The value of this variable is in the string character data format, meaning the content is enclosed in quotation marks and is treated like text. You can put numbers in strings, too, and they will be treated like text, in that you won’t be able to use them in numerical calculations.
The third line creates a print() statement concatenating Greetings to with the value in the name variable, followed by the text from Hackers-Arise. The Best Place to Learn Hacking! A print() statement will display whatever you pass to it within the parentheses on your screen.
Now, before you can run this script, you need to give yourself permission to execute it. We need the chmod command to do that. (For more information on Linux permissions, see Chapter 5).
kali >chmod 755 hackers-arise_greetings.py
Just as you did in Chapter 8 with bash scripting, to execute your script, precede the script name with a period and forward slash. Your current directory is not in the $PATH variable for security reasons, so we need to precede the script name with ./ to tell the system to look in the current directory for the filename and execute it.
To run this particular script, enter the following:
kali >./hackers-arise_greetings.py
Greetings to OccupyTheWeb from Hackers-Arise. The Best Place to Learn Hacking!
In Python, each variable type is treated like a class. A class is a kind of template for creating objects. See “Object-Oriented Programming (OOP)” on page 192 for more information. In the following script, I have attempted to demonstrate a few of the types of variables. Variables can hold more than just strings. Listing 17-2 shows some variables containing different data types.
#! /usr/bin/python3
HackersAriseStringVariable = "Hackers-Arise Is the Best Place to Learn
Hacking"
HackersAriseIntegerVariable = 12
HackersAriseFloatingPointVariable = 3.1415
HackersAriseList = [1,2,3,4,5,6]
HackersAriseDictionary = {'name' : 'OccupyTheWeb', 'value' : 27)
print (HackersAriseStringVariable)
print (HackersAriseIntegerVariable)
print (HackersAriseFloatingPointVariable)
Listing 17-2: A series of data structures associated with variables
This creates five variables that contain different data types: a string, treated as text; an integer, which is a number type without decimals that can be used in numerical operations; a float, which is a number type with decimals that can also be used in numerical operations; a list, which is a series of values stored together; and a dictionary, which is an unordered set of data where each value is paired with a key, meaning each value in the dictionary has a unique identifying key. This is useful for when you want to refer to or change a value by referring to a key name. For example, say you have a dictionary called fruit_color configured like the following:
fruit_color = {'apple' : 'red', 'grape' : 'green', orange : 'orange'}
If later in your script you want get the fruit_color of the grape, you simply call it by its key:
print (fruit_color['grape'])
You could also change values for particular keys; for example, here we change the color of the apple:
fruit_color['apple'] : 'green'
We will discuss lists and dictionaries in more detail later in the chapter.
Create this script in any text editor, save it as secondpythonscript.py, and then give yourself permission to execute it, like so:
kali >chmod 755 secondpythonscript.py
When we run this script, it prints the values of the string variable, the integer variable, and the floating-point number variable, like so:
kali >./secondpythonscript.py
Hackers-Arise Is the Best Place to Learn Hacking
12
3.1415
NOTE
In Python, there is no need to declare a variable before assigning a value to it, as in some other programming languages.
Like any other programming and scripting language, Python has the capability for adding comments. Comments are simply parts of your code—words, sentences, and even paragraphs—that explain what the code is meant to do. Python will recognize comments in your code and ignore them. Although comments are not required, they’re incredibly helpful for when you come back to your code two years later and can’t remember what it should do. Programmers often use comments to explain what a certain block of code does or to explain the logic behind choosing a particular method of coding.
Comments are ignored by the interpreter. This means that any lines designated as comments are skipped by the interpreter, which simply continues until it encounters a legitimate line of code. Python uses the # symbol to designate the start of single-line comment. If you want to write multiline comments, you can use three double quotation marks (""") at the start and end of the comment section.
As you can see in the following script, I have added a short, multiline comment to our simple hackers-arise_greetings.py script.
#! /usr/bin/python3
"""
This is my first Python script with comments. Comments are used to help explain code to
ourselves and fellow programmers. In this case, this simple script creates a greeting for
the user.
"""
name = "OccupyTheWeb"
print ("Greetings to "+name+" from Hackers-Arise. The Best Place to Learn Hacking!")
When we execute the script again, nothing changes compared to the last time it was executed, as you can see here:
kali >./hackers-arise_greetings.py
Greetings to OccupyTheWeb from Hackers-Arise. The Best Place to Learn Hacking!
It runs exactly the same as it did in Listing 17-1, but now we have some info about our script when we return to the code at a later time.
Functions in Python are bits of code that perform a particular action. The print() statement you used earlier, for example, is a function that displays whatever values you pass to it. Python has a number of built-in functions you can immediately import and use. Most of them are available on your default installation of Python in Kali Linux, although many more are available from the downloadable libraries. Let’s take a look at just a few of the thousands of functions available to you:
You can also create your own functions to perform custom tasks. Since there are so many already built into the language, it’s always worth checking whether a function already exists before going through the effort of building it yourself. There are many ways to do this check. One is to look at the official Python documentation available at https://docs.python.org. Choose the version you are working with and then select Library Reference.
Many programming languages use arrays as a way to store multiple separate objects. An array is a list of values that can be retrieved, deleted, replaced, or worked with in various ways by referencing a particular value in the array by its position in the list, known as its index. It’s important to note that Python, like many other programming environments, begins counting indexes at 0, so the first element in a list is index 0, the second is index 1, the third is index 3, and so on. So, for instance, if we wanted to access the third value in the array, we could do so with array[2]. In Python, there are a few implementations of arrays, but probably the most common implementation is known as lists.
Lists in Python are iterable, which means that the list can provide successive elements when you run all the way through it (see “Loops” on page 198). This is useful because quite often when we use lists, we are looking through them to find a certain value, to print out values one by one, or to take values from one list and put them into another list.
So, let’s imagine we need to display the fourth element in our list HackersAriseList from Listing 17-2. We can access that element and print it by calling the list’s name, HackersAriseList, followed by the index of the element we want to access enclosed in square brackets.
To test this, add the following line to the bottom of your secondpythonscript.py script to print the element at index 3 in HackersAriseList:
--snip--
print (HackersAriseStringVariable)
print (HackersAriseIntegerVariable)
print (HackersAriseFloatingPointVariable)
print (HackersAriseList[3])
When we run this script again, we can see that the new print statement prints 4 alongside the other output:
kali >./secondpythonscript.py
Hackers-Arise Is the Best Place to Learn Hacking
12
3.1415
4
A module is simply a section of code saved into a separate file so you can use it as many times as you need in your program without having to type it all out again. If you want to use a module or any code from a module, you need to import it. As discussed earlier, using standard and third-party modules is one of the key features that makes Python so powerful for the hacker. If we wanted to use the nmap module we installed earlier, we would add the following line to our script:
import nmap
Later in this chapter, we will use two very useful modules: socket and ftplib.
Before we delve deeper into Python, it’s probably worth taking a few minutes to discuss the concept of object-oriented programming (OOP). Python, like most programming languages today (C++, Java, and Ruby, to name a few) adheres to the OOP model.
Figure 17-2 shows the basic concept behind OOP: the language’s main tool is the object, which has properties in the form of attributes and states, as well as methods that are actions performed by or on the object.
Figure 17-2: Illustration of object-oriented programming
The idea behind OOP-based programming languages is to create objects that act like things in the real world. For example, a car is an object that has properties, such as its wheels, color, size, and engine type; it also has methods, which are the actions the car takes, such as accelerating and locking the doors. From the perspective of natural human language, an object is a noun, a property is an adjective, and a method is generally a verb.
Objects are members of a class, which is basically a template for creating objects with shared initial variables, properties, and methods. For instance, say we had a class called cars; our car (a BMW) would be a member of the class of cars. This class would also include other objects/cars, such as Mercedes and Audi, as shown in Figure 17-3.
Figure 17-3: OOP classes and objects
Classes may also have subclasses. Our car class has a BMW subclass, and an object of that subclass might be the model 320i.
Each object would have properties (make, model, year, and color) and methods (start, drive, and park), as shown in Figure 17-4.
Figure 17-4: OOP properties and methods
In OOP languages, objects inherit the characteristics of their class, so the BMW 320i would inherit the start, drive, and park methods from class car.
These OOP concepts are crucial to understanding how Python and other OOP languages work, as you will see in the scripts in the following sections.
Before we move on to more Python concepts, let’s use what you’ve learned so far to write a couple of hacking scripts to do with network connections.
We’ll create a network connection in Python using the socket module. I’ve already mentioned that Python comes with a library of modules for a multitude of tasks. In this case, we will need the socket module to create a TCP connection. Let’s see it in action.
Take a look at the script in Listing 17-3 named HackersAriseSSHBannerGrab.py (I know, it’s a long name, but bear with me here). A banner is what an application presents when someone or something connects to it. It’s kind of like an application sending a greeting announcing what it is. Hackers use a technique known as banner grabbing to find out crucial information about what application or service is running on a port.
#! /usr/bin/python3
➊ import socket
➋ s = socket.socket()
➌ s.connect(("192.168.1.101", 22))
➍ answer = s.recv(1024)
➎ print (answer)
s.close
Listing 17-3: A banner-grabbing Python script
First, we import the socket module ➊ so we can use its functions and tools. Here, we’re going to use the networking tools from the socket module to take care of interfacing a connection over the network for us. A socket provides a way for two computer nodes to communicate with each other. Usually, one is a server and one is a client.
Then we create a new variable, s, and associate it with the socket class from the socket module ➋. This way, we don’t have to reference the full socket.socket() syntax whenever we want to use the socket class—we can simply use the s variable name.
We then use the connect() method from the socket module ➌ to make a network connection to a particular IP and port. Remember that methods are functions that are available for a particular object. The syntax is object.method (for example, socket.connect). In this case, I’m connecting to IP address 192.168.1.101, which is the IP address of a machine on my network, and port 22, which is the default SSH port. You can test this on another instance of Linux or Kali. Most have port 22 open by default.
Once you make the connection, there are a number of things you can do. Here, we use the receive method recv to read 1024 bytes of data from the socket ➍ and store them in a variable named answer; these 1024 bytes will contain the banner information. Then we print the contents of that variable to the screen with the print() function ➎ to see what data has been passed over that socket, allowing us to spy on it! On the final line, we close the connection.
Save this script as HackersAriseSSHBannerGrab.py and then change its permissions using the chmod command so that you can execute it.
Let’s run this script to connect to another Linux system (you might use an Ubuntu system or even another Kali system) on port 22. If SSH is running on that port, we should be able to read the banner into our answer variable and print it to the screen, as shown here:
kali >./HackersAriseSSHBannerGrab.py
SSH-2.0-OpenSSH_7.3p1 Debian-1
We have just created a simple banner-grabbing Python script! We can use this script to find out what application, version, and operating system are running at that IP address and port. This gives us key information a hacker needs before attacking a system. This is essentially what the website Shodan.io does for nearly every IP address on the planet, and it catalogs and indexes this information for us to search.
We just created a TCP client that can make a connection to another TCP/IP address and port and then spy on the information being transmitted. That socket can also be used to create a TCP listener, to listen to connections from outsiders to your server. Let’s try doing that next.
In the Python script shown in Listing 17-4, you’ll create a socket on any port of your system that, when someone connects to that socket, collects key information about the connector’s system. Enter the script and save it as tcp_server.py. Make sure to give yourself execute permissions with chmod.
#! /usr/bin/python3
import socket
➊ TCP_IP = "192.168.181.190"
TCP_PORT = 6996
BUFFER_SIZE = 100
➋ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
➌ s.bind((TCP_IP, TCP_PORT))
➍ s.listen (1)
➎ conn, addr = s.accept()
print ('Connection address: ', addr )
while 1:
data=conn.recv(BUFFER_SIZE)
if not data:break
print ("Received data: ", data)
conn.send(data) #echo
conn.close
Listing 17-4: A TCP-listening Python script
We declare that we want the script to run with the Python interpreter and then import the socket module as before, so we can use its capabilities. We then define variables to hold information for the TCP/IP address, the port to listen on, and the buffer size of the data we want to capture from the connecting system ➊.
We define the socket ➋ and bind the socket to the IP address and port ➌ using the variables we just created. We tell the socket to listen using the listen() method from the socket library ➍.
We then capture the IP address and port of the connecting system using the socket library’s accept method, and we print that information to the screen so the user can see it ➎. Notice the while 1: syntax here; we’ll discuss this more later in the chapter, but for now just know that it is used to run the indented code that comes after it indefinitely, meaning Python keeps checking for data until the program is stopped.
Finally, we place the information from the connecting system into a buffer, print it, and then close the connection.
Now, go to another computer on your network and use a browser to connect to the 6996 port designated in our script. Run the tcp_server.py script, and you should be able to connect and collect key information about that system, including the IP address and port of the connecting system, as shown here:
kali >./tcp_server.py
Connection Address: ('192.168.181.190', 45368)
Received data: Get /HTTP/1.1
Host:192.168.181.190:6996
User -Agent:Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gec
--snip---
This is critical information for a hacker to gather before deciding on an exploit. Exploits (or hacks) are very specific to the operating system, application, and even language being used, so the hacker needs to know as much information as possible about the target before proceeding. This act of gathering information prior to a hack is often referred to as reconnaissance. You just developed a tool that will gather key reconnaissance information on a potential target, very similar to the popular hacker tool p0F!
Let’s keep expanding your understanding of Python and then use everything you’ve learned so far to build a password cracker for an FTP server.
Dictionaries hold information as unordered pairs, where each pair contains a key and an associated value. We can use a dictionary to store a list of items and give each item a label so we can use and refer to that item individually. We might use a dictionary to store, for example, user IDs and their associated names, or to store known vulnerabilities associated with a specific host. Dictionaries in Python act like associative arrays in other languages.
Like lists, dictionaries are iterable, meaning we use a control structure such as a for statement to go through the entire dictionary, assigning each element of the dictionary to a variable until we come to the end of the dictionary.
Among other things, you might use this structure in building a password cracker that iterates through each password stored in a dictionary until one works or until the cracker comes to the end of the dictionary.
The syntax for creating a dictionary is as follows:
dict = {key1:value1, key2:value2, key3:value3...}
Note that for dictionaries, you use curly brackets and separate items with a comma. You can include as many key-value pairs as you like.
Control statements allows your code to make decisions based on some condition. There are a number of ways in Python to control the flow of the script.
Let’s look at some of these structures in Python.
The if structure in Python, as in many other programming languages including bash, is used to check whether a condition is true or not and run different sets of code for each scenario. The syntax looks like this:
if conditional expression
run this code if the expression is true
The if statement contains a condition that might be something like if variable < 10, for example. If the condition is met, the expression evaluates to true, and then the code that follows, known as the control block, is executed. If the statement evaluates to false, then the statements in the control block are skipped over and not executed.
In Python, the control block must be indented. This indentation identifies the control block to the interpreter. The next statement that is not indented is outside the control block and therefore not part of the if statement, and this is how Python knows where to skip to if the condition is not met.
The if...else structure in Python looks like this:
if conditional expression
*** # run this code when the condition is met
else
*** # run this code when the condition is not met
As before, first the interpreter checks the condition in the if expression. If it evaluates to true, the interpreter executes the statements in the control block. If the conditional statement evaluates to false, the control block following the else statement is executed instead.
For example, here we have a code snippet that checks the value of a user ID; if it is 0 (the root user in Linux is always UID 0), then we print the message “You are the root user.” Else, if it is any other value, we print the message “You are NOT the root user.”
if userid == 0
print ("You are the root user")
else
print ("You are NOT the root user")
Loops are another very useful structure in Python. Loops enable the programmer to repeat a code block multiple times, depending on a value or a condition. The two most widely used are while and for.
The while loop evaluates a Boolean expression (an expression that can evaluate only to true or false) and continues execution while the expression evaluates to true. For example, we could create a code snippet that prints each number from 1 to 10 and then exits the loop, like so:
count = 1
while (count <= 10):
print (count)
count += 1
The indented control block then runs for as long as the condition is true.
The for loop can assign values from a list, string, dictionary, or other iterable structure to an index variable each time through the loop, allowing us to use each item in the structure one after the other. For example, we can use a for loop to attempt passwords until we find a match, like so:
for password in passwords:
attempt = connect (username, password)
if attempt == "230"
print ("Password found: " + password)
sys.exit (0)
In this code snippet, we create a for statement that continues through a list of passwords we have provided and attempts to connect with a username and password. If the connection attempt receives a 230 code, which is the code for a successful connection, the program prints "Password found:" and then the password. It then exits. If it does not get a 230, it will continue through each of the remaining passwords until it receives a 230 or until it exhausts the list of passwords.
Now with a bit more background in Python looping structures and conditional statements, let’s return to our banner-grabbing script and add some capabilities.
We’ll add a list of ports that we want to grab the banner from, rather than just listening on one port, and then loop through the list using a for statement. In this way, we can search for and grab banners for multiple ports and display them to the screen.
First, let’s create a list and put additional ports in it. Open HackersAriseSSHBannerGrab.py, and we’ll work from there. Listing 17-5 shows the full code. Note that the grayed-out lines have stayed the same; the black lines are the ones you need to change or add. We’ll try to grab banners for ports 21 (ftp), 22 (ssh), 25 (smtp), and 3306 (mysql).
#! /usr/bin/python3
import socket
➊ Ports = [21,22,25,3306]
➋ for i in range (0,4):
s = socket.socket()
➌ Ports = Port[i]
print ('This Is the Banner for the Port')
print (Ports)
➍ s.connect (("192.168.1.101", Port))
answer = s.recv (1024)
print (answer)
s.close ()
Listing 17-5: Improving the banner grabber
We create a list called Ports ➊ and add four elements, each representing a port. Then we create a for statement that iterates through that list four times, since it has four items ➋.
Remember that when you’re using a for loop, the code associated with the loop must be indented beneath the for statement.
We need to alter the program to reflect the use of a variable from the list on each iteration through. To do so, we create a variable named Port and assign it to the value from the list at each iteration ➌. Then we use that variable in our connection ➍.
When the interpreter comes to that statement, it will attempt to connect to whichever port is assigned to the variable at the IP address.
Now, if you run this script on a system with all the ports listed open and enabled, you should see something like Listing 17-6.
kali >./HackersArisePortBannerGrab.py
This is the Banner for the Port
21
220 (vsFTPd 2.3.4)
This Is the Banner for the Port
22
SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1
This Is the Banner for the Port
25
220 metasploitable.localdomain ESMTP Postfix (Ubuntu)
This Is the Banner for the Port
3306
5.0.51a-3ubuntu5
Listing 17-6: Output for the port banner grabber
Note that the script has found port 21 open with vsFTPd 2.3.4 running on it, port 22 open with OpenSSH 4.7 running on it, port 25 with Postfix, and port 3306 with MySQL 5.0.51a.
We have just successfully built a multiport banner-grabbing tool in Python to perform reconnaissance on a target system. The tool tells us which service is running on the port and the version of that service! This is key information a hacker needs before proceeding with an attack.
Any code you write will be at risk of errors or exceptions. In programming terms, an exception is anything that disrupts the normal flow of your code—usually an error caused by incorrect code or input. To deal with possible errors, we use exception handling, which is simply code that handles a particular problem, presents an error message, or even uses an exception for decision making. In Python, we have the try/except structure to handle these errors or exceptions.
A try block tries to execute some code, and if an error occurs, the except statement handles that error. In some cases, we can use the try/except structure for decision making, similar to if...else. For instance, we can use try/except in a password cracker to try a password and, if an error occurs due to the password not matching, move to the next password with the except statement. Let’s try that now.
Enter the code in Listing 17-7 and save it as ftpcracker.py; we’ll go through it in a moment. This script asks the user for the FTP server number and the username of whichever FTP account they want to crack. It then reads in an external text file containing a list of possible passwords and tries each one in an effort to crack into the FTP account. The script does this until it either succeeds or runs out of passwords.
#! /usr/bin/python3
import ftplib
➊ server = input(FTP Server: ")
➋ user = input("username: ")
➌ Passwordlist = input ("Path to Password List > ")
➍ try:
with open(Passwordlist, 'r') as pw:
for word in pw:
➎ word = word.strip ('\r').strip('\n')
➏ try:
ftp = ftplib.FTP(server)
ftp.login(user, word)
➐ print (Success! The password is ' + word)
➑ except:
print('still trying...')
except:
print ('Wordlist error')
Listing 17-7: FTP password cracker Python script
We’re going to use tools from the ftplib module for the FTP protocol, so first we import that. Next, we create a variable named server and another variable named user, which will store some commands for user input. Your script will prompt the user to enter the IP address of the FTP server ➊ and the username for the account ➋ the user is trying break into.
Then we ask the user for the path to the password list ➌. You can find numerous password lists in Kali Linux by entering locate wordlist in a terminal.
We then begin the try block of code that will use the password list provided by the user to attempt to crack the password for the username supplied by the user.
Note that we use a new Python function called strip() ➎. This function removes the first and last character of a string (in this case, the Passwordlist). This is necessary if the passwords in this list have a preceding whitespace or comma. The strip() function removes these and leaves just the string of characters of the potential password. If we don’t strip the whitespace, we might get a false negative.
Then, we use a second try ➏ block. Here, we use the ftplib module to first connect to the server using the IP address the user supplied and then try the next password from the password list on that account.
If the combination of the username and password results in an error, the block exits and goes to the except clause ➑, where it prints still trying and then returns to the top of the for clause and grabs the next password from the password list to try.
If the combination succeeds, the successful password is printed to the screen ➐. The final line picks up any other situations that would otherwise result in errors. An example would be if the user input something the program couldn’t process, such as bad path to the wordlist or a missing wordlist.
Now, let's run this script against the FTP server at 192.168.1.101 and see whether we can crack the password of the root user. I am using a password list named bigpasswordlist.txt in my working directory. You may need to provide the entire path to whichever password list you are using if it is not in your working directory (for example, /usr/share/bigpasswordlist.txt).
kali >./ftpcracker.py
FTP Server: 192.168.1.101
username: root
Path to PasswordList >bigpasswordlist.txt
still trying...
still trying...
still trying...
--snip--
Success! The password is toor
As you can see, ftpcracker.py successfully found the password for the user root and presented it onscreen.
To graduate beyond script-kiddie status, a hacker must master a scripting language, and Python is generally a good first choice for its versatility and relatively small learning curve. The majority of hacking tools are written in Python, including sqlmap, scapy, and many others. Here, you have learned some Python fundamentals you can use to build some useful, yet simple hacker tools, including a banner grabber and an FTP password cracker. To learn more Python, I strongly recommend No Starch Press’s excellent book Automate the Boring Stuff with Python (2015) by Al Sweigart.