Bash is a Unix shell, which is a command-line interface for interacting with an operating system. The advantage of a shell is that you perform these tasks immediately from the computer and not through an abstraction, like a GUI, which allows you to customize your task to your needs. A number of different shells are available for Linux, including the Korn shell, the Z shell, the C shell, and the Bourne-again shell, more widely known as bash.
Bash scripting is writing scripts in the Bash programming language to automate tasks on a Unix-based system. Some common uses for bash scripts include system administration, task automation, and deployment.
Today we are going to write a hacking script, but first let’s take a look at some concepts and features in bash scripting. You’ll need a text editor to create shell scripts. You can use whichever Linux, Windows or Mac text editor you like best.
- Command line arguments:
$0
: the name of the script$1
,$2
, etc.: the first, second, etc. command line argument$@
: all the command line arguments$#
: the number of command line arguments
- Functions:
function name { commands; }
: define a function named “name” with the commands inside the curly braces$1
,$2
, etc.: the first, second, etc. argument passed to the function$@
: all the arguments passed to the function$#
: the number of arguments passed to the functionreturn value
: return a value from the function
- Input/Output:
>
: redirect standard output to a file, overwriting the file if it exists>>
: redirect standard output to a file, appending to the file if it exists<
: redirect standard input from a file2>
: redirect standard error to a file, overwriting the file if it exists2>>
: redirect standard error to a file, appending to the file if it exists&>
: redirect both standard output and standard error to a file, overwriting the file if it exists&>>
: redirect both standard output and standard error to a file, appending to the file if it exists
- Conditional expressions:
-e file
: true if file exists-d file
: true if file is a directory-f file
: true if file is a regular file-z string
: true if string is empty-n string
: true if string is not emptystring1 = string2
: true if string1 is equal to string2string1 != string2
: true if string1 is not equal to string2
- String operations:
${string:start:length}
: substring of string starting at “start” with “length” characters${string/substring/replacement}
: replace the first occurrence of “substring” with “replacement” in string${string//substring/replacement}
: replace all occurrences of “substring” with “replacement” in string${string/#substring/replacement}
: replace the substring at the beginning of string with “replacement” if it matches “substring”${string/%substring/replacement}
: replace the substring at the end of string with “replacement” if it matches “substring”
Hacking Script: Scan for Open Ports
Now that you have some basic scripting skills, let’s move to some slightly more advanced scripting that has real-world application to hacking. We’ll use an example from the world of black hat hacking. Black hat hackers are those with malicious intentions, such as stealing credit card numbers or defacing websites. White hat hackers are those with good intentions, such as helping software developers or system administrators make their systems more secure. Gray hat hackers are those who tend to move between these two extremes.
Before you continue, you need to become familiar with a simple yet essential tool named nmap that comes installed on Kali by default. You’ve likely heard the name; nmap is used to probe a system to see whether it is connected to the network and finds out what ports are open. From the open ports discovered, you can surmise what services are running on the target system. This is a crucial skill for any hacker or system administrator.
In its simplest form, the syntax for running an nmap scan looks like this:
nmap <type of scan><target IP><optionally, target port>
Not too difficult. The simplest and most reliable nmap scan is the TCP connect scan, designated with the -sT switch in nmap. So, if you wanted to scan IP address 192.168.181.1 with a TCP scan, you would enter the following:
nmap -sT 192.168.181.1
To take things a step further, if you wanted to perform a TCP scan of address 192.168.181.1, looking to see whether port 3306 (the default port for MySQL) was open, you could enter this:
nmap -sT 192.168.181.1 -p 3306
Here, -p designates the port you want to scan for. Go ahead and try it out now on your Kali system.
Our Script
➊ #! /bin/bash
➋ # This script is designed to find hosts with MySQL installed
nmap ➌-sT 192.168.181.0/24 ➍-p 3306 ➎>/dev/null ➏-oG MySQLscan
➐ cat MySQLscan | grep open > MySQLscan2 ➑
cat MySQLscan2
We start with the shebang and the interpreter to use ➊. Let’s follow this with a comment to explain what the script does ➋.
Now let’s use the nmap command to request a TCP scan ➌ on our LAN, looking for port 3306 ➍. (Note that your IP addresses may differ; in your terminal, use the ifconfigcommand on Linux or the ipconfig command on Windows to determine your IP address.) To stay stealthy, we also send the standard nmap output that would usually appear on the screen to a special place in Linux, where it disappears ➎. We’re doing this on a local machine, so it doesn’t matter so much, but if you were to use the script remotely, you’d want to hide the nmap output. We then send the output of the scan to a file named MySQLscan in a grep-able format ➏, meaning a format that grep can work on.
The next line displays the MySQLscan file we stored the output in and then pipes that output to grep to filter for lines that include the keyword open ➐. Then we put those lines into a file named MySQLscan2 ➑.
Finally, you display the contents of the file MySQLscan2. This final file should only include lines of output from nmap with hosts that have port 3306 open. Save this file asMySQLscanner.sh and give yourself execute permissions with chmod 755.
Execute the script, like so:
kali >./MySQLscanner.sh
host: 192.168.181.69 () Ports: 3306/open/tcp//mysql///
As we can see, this script was able to identify the only IP address on my LAN with MySQL running. Your results may differ, depending on whether any ports are running MySQL installations on your local network, of course.
Adding Prompts and Variables to Our Hacker Script
#! /bin/bash
➊ echo "Enter the starting IP address : "
➋ read FirstIP
➌ echo "Enter the last octet of the last IP address : "
read LastOctetIP
➍ echo "Enter the port number you want to scan for : "
read port
➎ nmap -sT $FirstIP-$LastOctetIP -p $port >/dev/null -oG MySQLscan
➏ cat MySQLscan | grep open > MySQLscan2
➐ cat MySQLscan2
The first thing we need to do is replace the specified subnet with an IP address range. We’ll create a variable called FirstIP and a second variable named LastOctetIP to create the range as well as a variable named port for the port number (the last octet is the last group of digits after the third period in the IP address. In the IP address 192.168.1.101, the last octet is 101).
The name of the variable is irrelevant, but best practice is to use a variable name that helps you remember what the variable holds.
To get a value for the FirstIP variable, echo “Enter the starting IP address : ” to the screen, asking the user for the first IP address they want to scan ➊. Upon seeing this prompt on the screen, the user will enter the first IP address, so we need to capture that input from the user.
We can do this with the read command followed by the name of the variable we want to store the input in ➋. This command will put the IP address entered by the user into the variable FirstIP. Then we can use that value in FirstIP throughout our script.
We’ll do the same for the LastOctetIP ➌ and port ➍ variables by prompting the user to enter the information and then using a read command to capture it.
Next, we need to edit the nmap command in our script to use the variables we just created and filled. To use the value stored in the variable, we simply preface the variable name with $, as in $port, for example. So at ➎, we scan a range of IP addresses, starting with the first user-input IP through the second user-input IP, and look for the particular port input by the user. We’ve used the variables in place of the subnet to scan and the port to determine what to scan for. The redirect symbol > tells the standard nmap output, which usually goes to the screen, to instead go to /dev/null (/dev/null is simply a place to send output so that it disappears). Then, we send the output in a grep-able format to a file we named MySQLscan.
The next line remains the same as in our simple scanner: it outputs the contents of the MySQLscan file, pipes it to grep, where it is filtered for lines that include the keyword open, and then sends that output to a new file named MySQLscan2 ➏. Finally, we display the contents of the MySQLscan2 file ➐.
If everything works as expected, this script will scan IP addresses from the first input address to the last input address, searching for the input port and then reporting back with just the IP addresses that have the designated port open. Save your script file as MySQLscannerAdvanced, remembering to give yourself execute permission.
A Sample Run
Now we can run our simple scanner script with the variables that determine what IP address range and port to scan without having to edit the script every time we want to run a scan:
kali >./MySQLscannerAdvanced.sh
Enter the starting IP address :
192.168.181.0
Enter the last IP address :
192.168.181.255
Enter the port number you want to scan for :
3306
Host: 192.168.181.254 ()Ports:3306/open/tcp//mysql//
The script prompts the user for the first IP address, the last IP address, and then the port to scan for. After collecting this info, the script performs the nmap scan and produces a report of all the IP addresses in the range that have the specified port open. As you can see, even the simplest of scripting can create a powerful tool.