Welcome to Programming Thursdays, where we dive deep into the world of coding and explore new tools and techniques for the discerning pen tester and red teamer. Today, we’re going to take a look at Bash Scripting Language, one of the most powerful and versatile languages in the hacker’s toolkit.

As a pen tester or red teamer, you’re no doubt familiar with the concept of automation. Writing scripts to automate common tasks and exploit vulnerabilities is essential to your success, and that’s where Bash comes in. Whether you’re looking to brute force a password, execute a series of commands, or manipulate files and directories, Bash is the perfect language for the job.

Basic Syntax

Before we get started, let’s cover some basic concepts and syntax in Bash. If you’re already familiar with programming languages, feel free to skip ahead, but if you’re new to the game, read on.

Variables and Data Types

Like most programming languages, Bash uses variables to store data. Variables can hold any type of data, including strings, integers, and arrays. To declare a variable, simply assign a value to it:

#!/bin/bash

# Declare a string variable
str="Hello, World!"

# Declare an integer variable
num=42

# Declare an array
arr=("apple" "banana" "cherry")

Operators

Bash supports a wide range of operators, including arithmetic, comparison, and logical operators. Here are a few examples:

#!/bin/bash

# Arithmetic operators
a=10
b=5
echo $((a + b))    # Output: 15
echo $((a - b))    # Output: 5
echo $((a * b))    # Output: 50
echo $((a / b))    # Output: 2
echo $((a % b))    # Output: 0

# Comparison operators
a=10
b=5
if [ $a -gt $b ]; then
    echo "a is greater than b"
fi

# Logical operators
a=10
b=5
if [ $a -gt $b ] && [ $a -lt 20 ]; then
    echo "a is between 5 and 20"
fi

Control Structures

Control structures allow you to execute code conditionally or repeatedly. Bash supports if/else statements, loops, and case statements. Here are a few examples:

#!/bin/bash

# If/else statement
a=10
b=5
if [ $a -gt $b ]; then
    echo "a is greater than b"
else
    echo "b is greater than a"
fi

# Loop
for i in {1..5}; do
    echo $i
done

# Case statement
a="apple"
case $a in
    "apple") echo "It's an apple";;
    "banana") echo "It's a banana";;
    "cherry") echo "It's a cherry";;
esac

Functions

Functions allow you to encapsulate code and reuse it throughout your script. To define a function, use the following syntax:

#!/bin/bash

# Define a function
function greet {
    echo "Hello, $1!"
}

# Call the function
greet "World"

Advanced Elements

In this section, we’ll cover some more advanced examples of Bash Scripting Language, including conditional tests, taking arguments for the script, default values, Heredoc, boolean logic, redirection, reading input, special variables, and variable substitutions.

Conditional Tests

Bash supports a wide range of conditional tests, including file tests, string tests, and numeric tests. Here are a few examples:

#!/bin/bash

# File test
if [ -f /path/to/file ]; then
    echo "File exists"
fi

# String test
if [ "$str" = "Hello, World!" ]; then
    echo "Strings are equal"
fi

# Numeric test
if [ $num -gt 10 ]; then
    echo "Number is greater than 10"
fi

Taking Arguments for the Script

Bash scripts can take arguments from the command line, allowing you to customize their behavior for different use cases. Here’s an example:

#!/bin/bash

# Take two arguments from the command line
echo "First argument: $1"
echo "Second argument: $2"

You could then run this script with two arguments:

./script.sh arg1 arg2

Default Values

You can also set default values for arguments in case they’re not provided. Here’s an example:

#!/bin/bash

# Set default values for the first two arguments
arg1=${1:-default1}
arg2=${2:-default2}

echo "First argument: $arg1"
echo "Second argument: $arg2"

You could then run this script with only one argument:

./script.sh arg1

Heredoc

Heredoc allows you to define a block of text as a variable, which can be useful for creating templates or multi-line strings. Here’s an example:

#!/bin/bash

# Define a Heredoc block as a variable
myvar=$(cat << EOF
This is a multi-line string.
It can contain any characters, including "quotes" and 'apostrophes'.
EOF
)

# Print the variable
echo "$myvar"

Boolean Logic

Bash supports boolean logic through the use of the “&&” and “||” operators. Here are a few examples:

#!/bin/bash

# Boolean AND
if [ $a -gt 10 ] && [ $a -lt 20 ]; then
    echo "a is between 10 and 20"
fi

# Boolean OR
if [ $a -lt 5 ] || [ $a -gt 20 ]; then
    echo "a is less than 5 or greater than 20"
fi

Redirection

Bash supports redirection of input and output, allowing you to read input from files and redirect output to files. Here are a few examples:

#!/bin/bash

# Read input from a file
while read line; do
    echo "Line: $line"
done < input.txt

# Redirect output to a file
echo "Output" > output.txt

Reading Input

Bash supports reading input from the user, which can be useful for interactive scripts. Here’s an example:

#!/bin/bash

# Ask the user for input
read -p "Enter your name: " name

# Print the input
echo "Hello, $name!"

Special Variables

Bash includes a number of special variables that provide information about the environment, such as the current working directory and the number of arguments passed to the script. Here are a few examples:

#!/bin/bash

# Current working directory
echo "Current directory: $PWD"

# Number of arguments
echo "Number of arguments: $#"

# Script name
echo "Script name: $0"

# Last argument
echo "Last argument: ${!#}"

Variable Substitutions

Bash supports variable substitutions, which allow you to manipulate variables in various ways. Here are a few examples:

#!/bin/bash

# Replace a substring
str="Hello, World!"
echo ${str/Hello/Hi} # Output: Hi, World!

# Remove a substring
str="Hello, World!"
echo ${str//o/} # Output: Hell, Wrld!

# Replace with default value if variable is empty
echo ${var:-default}

# Replace with default value if variable is unset
echo ${var:=default}

# Replace with default value if variable is empty or unset
echo ${var:-default}

# Return error if variable is empty or unset
echo ${var:?error}

Using Bash for Pen Testing and Red Teaming

Now that we’ve covered the basics, let’s take a look at how Bash can be used for pen testing and red teaming.

One of the most common use cases for Bash is automating tasks. For example, you might write a script to scan a network for open ports or brute force a password. Here’s an example script that uses nmap to scan for open ports on a given IP address:

#!/bin/bash

# Scan for open ports on the target IP address
nmap $1

You could then run this script with the target IP address as a parameter:

./scan.sh 192.168.0.1

Another common use case for Bash is manipulating files and directories. For example, you might write a script to search for a specific file on a target system or download sensitive data. Here’s an example script that searches for a file called “passwords.txt” on a target system:

#!/bin/bash

# Search for a file called "passwords.txt"
find / -name "passwords.txt" 2>/dev/null

You could then run this script on the target system to search for the file:

./search.sh

Bash can also be used to automate password cracking. For example, you might write a script to brute force a password using a dictionary attack. Here’s an example script that reads in a list of passwords from a file and tries them one by one:

#!/bin/bash

# Read in a list of passwords from a file
passwords=$(cat passwords.txt)

# Loop through the passwords and try them one by one
for password in $passwords; do
    echo "Trying password: $password"
    echo $password | sudo -S echo "" 2>/dev/null
    if [ $? -eq 0 ]; then
        echo "Password found: $password"
        exit 0
    fi
done

echo "Password not found"

You could then run this script with sudo privileges to try and brute force the password:

sudo ./crack.sh

In addition to these examples, Bash can be used for a wide range of other pen testing and red teaming tasks. Whether you’re looking to automate common tasks, exploit vulnerabilities, or manipulate data, Bash is an essential tool in the hacker’s toolkit.

Putting it together

Let’s say that you’ve been tasked with creating a script that automates the process of scanning a target network for open ports, and then attempting to exploit any vulnerabilities found on those ports. Here’s an example script that uses all of the Bash Scripting Language features we’ve covered:

#!/bin/bash

# Take the target IP address as an argument
target=$1

# Scan for open ports using nmap and save the output to a file
nmap -oN scan.txt $target

# Loop through the open ports and attempt to exploit any vulnerabilities
while read line; do
    # Extract the port number from the nmap output
    port=$(echo $line | cut -d '/' -f 1)

    # If the port is open, attempt to exploit any vulnerabilities
    if echo $line | grep -q 'open'; then
        # Check if there's a Metasploit module for the service running on this port
        if msfconsole -q -x "search name:$(echo $line | cut -d '/' -f 3 | cut -d ' ' -f 1)" | grep -q 'found'; then
            # If there's a Metasploit module, attempt to exploit the vulnerability
            msfconsole -q -x "use $(echo $line | cut -d '/' -f 3 | cut -d ' ' -f 1); set RHOSTS $target; set RPORT $port; run"
        else
            # If there's no Metasploit module, try a generic exploit
            if [ $port -eq 21 ]; then
                # FTP exploit
                echo "FTP exploit for port $port"
            elif [ $port -eq 22 ]; then
                # SSH exploit
                echo "SSH exploit for port $port"
            else
                # Generic exploit
                echo "Generic exploit for port $port"
            fi
        fi
    fi
done < <(grep -E '^[0-9]+/' scan.txt)

# Clean up the scan output file
rm scan.txt

Let’s break down what’s happening in this script:

  • The script takes the target IP address as an argument.
  • The script uses nmap to scan the target for open ports and saves the output to a file.
  • The script loops through the open ports found by nmap.
  • For each open port, the script extracts the port number from the nmap output.
  • If the port is open, the script checks if there’s a Metasploit module for the service running on that port.
  • If there’s a Metasploit module, the script attempts to exploit the vulnerability using Metasploit.
  • If there’s no Metasploit module, the script attempts a generic exploit based on the port number.
  • The script cleans up the scan output file.

As you can see, this script makes use of several Bash Scripting Language features, including taking arguments for the script, file input/output, conditional tests, loop structures, variable substitutions, and executing commands using command substitution. By combining these features, we can create a powerful and flexible script that automates the process of scanning for and exploiting vulnerabilities on a target network.

Conclusion

Bash Scripting is a powerful and versatile language that every pen tester and red teamer should have in their arsenal. With its support for variables, operators, control structures, and functions, Bash makes it easy to automate tasks, manipulate data, and exploit vulnerabilities.

In this article, we covered the basics of Bash Scripting, including variables and data types, operators, control structures, and functions. We also looked at how Bash can be used for pen testing and red teaming, with specific code examples for common tasks like scanning for open ports, manipulating files and directories, and password cracking.

Whether you’re a seasoned hacker or just starting out, mastering Bash Scripting Language is essential for success in the world of pen testing and red teaming. So what are you waiting for? Start coding!