Bash Introduction for Hackers part 2

(869 views)

Welcome to Bash Intro for Hackers Part 2! This material was prepared by our instructor Saeed Dehqan for our Wireless Network Attacks course as a foundational topic for anyone wanting to automate their pentesting tasks. Check out the course while you're here!

Arrays

In scripts, you may want to save a set of items instead of a variable. You can use arrays for this purpose. In bash, in order to define the arrays, we put the values in parentheses with spaces. Below we have an empty array called a and then we defined another array called b. We use a zero-based index to extract the value of an array. For example, below, by putting index 2, we extract the third value from array b:

#!/bin/bash

a=()
b=("reason" "logic" "aspect" "ethic")
echo ${b[2]}

Now, if we run the script, As you guess “aspect” will be printed:

We can also set an index of the array by a number:

b[5] = "ground"

You can also use the += operator to add a value to the end of an array:

b+=("rationale")

You can use the @ index to view the entire array:

#!/bin/bash

a=()
b=("reason" "logic" "aspect" "ethic")
b[5]="rationale"
b+=("rationale")
echo ${b[2]}
echo ${b[@]}

The result will be like following figure:

Files

One of your main needs in bash is to work with text files. The main key in this field is the < and > characters. For example, the following command saves the specified text in a file called text.txt.

echo "something" > text.txt

With the above command, if there is a file, its content will be replaced, and if there is no file, the specified content will be inserted in it. If you want to empty the contents of a file, you can use the following command structure:

> text.txt

If you want to add a value to the end of the file and keep the previous value, you can use the >> character:

echo "stuff" >> text.txt

So far we have talked about inserting content into a file. How to read the content of a file in a script?
For this purpose, you can use a while loop with the read command. The following syntax structure causes the contents of the text.txt file to be read line by line and stored in the variable text. Then we print the content inside the loop using the echo command.

#!/bin/bash

while read text;
do
 echo $text
done < text.txt

Just as you can use a file as input to a loop, you can use a file as input to a command. A simple example is to use the cat command to read a file:

cat < text.txt

A better example is to save the commands needed to run in a text file and then enter the contents of the file into the command line to use. For example, suppose in a script you want to connect to a specific FTP server, upload a file, and then exit. For this purpose, we first create a text file and save the desired commands in it.

Below we first open mirror.xmission.com with the open FTP server, connect with the anonymous user and none password, upload a file and exit:

As you can see, the connection has been successful but the server didn’t let us upload a new file. If we want to do these commands everyday, it will be very time-consuming:

Condition Structures

An if statement executes our code based on the intended conditions. The structure of the if statement is such that first the if phrase and then the logical expression is inserted:

if [ expr ]
if [[ expr ]]
if (( expr ))
if expr

All four of the above modes can be used. Two parentheses are used to compare integer numbers as we mentioned earlier. The use of each depends on your needs. The if structure is as follows:

if (( 10>5 ))
    then
    echo "true"
    else
    echo "false"
fi

First, the condition in the expression is validated. If the condition is met, the code block will be executed after the then statement. Then if the expression isn’t met, the else block will be executed. Finally, we close the if statement with fi:

If you need more evaluations in the if statement, you can use elif:

n1=10
n2=5
if (( $n1>$n2 ))
    then
    echo "n1 is greater than n2"
elif (( $n1<$n2 ))
    then
    echo "n1 is lower than n2"
else
    echo "n1 is equal to n2"
fi

First, we assign the numeric value 10 to n1 variable and 5 to n2 variable. Then, we use integer numbers to check whether the variable a is greater than 5 or not. If it is greater, a message will be printed.

The result will be like below:

If we change the n1 variable to 4, the elif block will be executed:

If we change the n1 variable to 5, the else block will be executed:

While

The loop is used to repeat an operation to a certain number in programming. For example, if we want to call a function a hundred times, it does not make sense to write a hundred lines of code for such simplicity. There are several ways to create a loop in bash, one of which is while. An example of a simple while loop can be seen below. The general structure of the work is as follows:

#!/bin/bash
i=0
While [ $i -le 10 ]
do
 echo i:$i
 ((i+=1))
done

Here we first create a counter variable named i and the initial value is zero. In the following lines, we define the while condition in such a way that if the value of the variable i is less than or equal to 10, the loop will continue. And if i is greater than 10, the loop ends. Finally, we print the value of the i inside the loop and then add a number to the number:

For

Another type of loop in the bash is the for type, which creates a loop based on a set of indicators, usually one or a specific range. Using this type of loop we get a variable that is in a range. A simple example can be seen below:

#!/bin/bash

i=0
for i in 1 2 3 4 5
do
    echo i:$i
done

At the beginning of the loop, we define the variable i and limit the numbers 1 to 5 to our range. Running this simple script has resulted in the printing of numbers from one to five:

Writing numbers one by one is not rational if we want to use a larger range of numbers. So, as we explained earlier, you can use colly-brackets {} to define the range of numbers or strings:

i=0
for i in {1..5}
do
    echo i:$i
done

The results will be as follows:

Another type of for loop structure that is familiar to you if you have worked with the C language is as follows:

#!/bin/bash

for (( i=1; i<=10; i++ ))
do
 echo $i
done

Here we first define the initial value of the variable i and then place the condition of the loop. Finally, add a number to the i counter (counter also can be: i+=2). All of these items must be in parentheses. It is necessary to have a semicolon ; between each value to be placed:

You can also use the command substitution in the for loop. Note the following example:

#!/bin/bash

for i in $(ls)
do
 echo $i
done

For this purpose, we add the ls command in the range of the replacement loop.

In this way, the results of executing the ls command are printed line by line in the output.

Case

What should we do if you have many different items to test? You can use a long list of if statements, but there is a better way. For this purpose, we use the term case. The case statement validates the value based on a list of specified values. Consider the following example.

#!/bin/bash
$web="example.com"
case $web in
 forest.com) echo "It's forest.";;
 animal|human) echo "Maybe animal or maybe human";;
 example.com) echo "This is a site!";;

*) echo $web;;
esac

First, we define a variable called site and value it. Then we use the $web variable as a basis and put the validation items in a separate line. In each case, we first enter the value to be checked and then add a closed parenthesis ) and add the desired code in case of successful validation. Using the pipe character | we can test several things together. Using the * sign we can test other items not mentioned. Note that at the end of each line we must insert two semicolons. Finally, we close the case with esac (opposite to the case word). When we run, after checking all the modes before the correct mode is checked and at the end, the block is executed accordingly:

Now, let’s change the web variable to the “terrestrial”:

Functions

During the script development process you may notice that a lot of code snippets are repeated. You can use functions to prevent duplicate blocks of code and better organize the script. Creating functions in bash is very simple. Just enter the function keyword with the desired name for the function and enter the function code in parentheses. Here is a simple example of a function in a bash script. After defining the function, in order to call it, it is enough to enter the function name outside the function.

#!/bin/bash

function greet {
 echo "Hi there!"
}

greet

In the above we created a function called greet and called it out of the function:

You can specify arguments for functions. For example, below we add the $1 argument to our function, and outside the function, we add the name argument to the function by calling:

#!/bin/bash

function greet {
 echo "Hi $1"
}

greet Anna

Here we add three more arguments to our function.

function greet {
 echo "Hi $1, $2, and $3"
}

greet Anna Sara Alec

These arguments are entered in the order $1, $2, $3,.. call and are placed in the function.

Arguments

So far we have written scripts that did not accept any input. In the real world, you often need to get user input. For this purpose, we use arguments. If you have read the functions section, you will see that these arguments are exactly the same as the function arguments. Arguments are special variables that are specified by the user while executing the script. They can be almost anything. A file or folder you want to create, a username or a text string to search.

These arguments are inserted at the execution moment after the user script name. Arguments are presented with numbered variables and assigned in order of entry on the command line. As before $1, $2, $3, .. you see the simple example below:

#!/bin/bash

echo $1
echo $2
echo $3

Above we define three arguments for the script and print their value. When assigning arguments by the user, if it contains spaces, it should be enclosed in quotation marks:

If we want to unlimit the number of arguments in a variable, instead of manually assigning each argument to a variable, we can create an array of arguments using $@ and a for loop. You can also count the number of arguments assigned using the $# variable:

#!/bin/bash

for i in $@
do
 echo $i
done
echo "The number of arguments: $#"

In this case, the user can enter any number of arguments into the script:

Flags

If you have worked with the command line tool, you are familiar with flags. Flags are special options that you can use to send information to the program. Flags usually begin with the character Dash. You can use the getopts function to use flags in your script. Suppose we want to create a script that accepts usernames and passwords. You can see the following example.

#!/bin/bash

while getopts u:p: option;
do 
 case $option in
 u) user=$OPTARG;;
 p) pass=$OPTARG;;
 esac
done 

echo "Username: $user"
echo "Password: $pass"

Here we use the getopts function to create a while loop of option strings inside the case. First we enter u:p: which determines our options will be -u and -p. Then, inside the case statement, we put the option variable as the basis for the evaluation and determine the options.

$OPTARG is the value that is sent to the script by the user on the command line. You will see that the values ​​set by us are added:

A good thing about flags is that we do not need to follow the order when importing them.

read

We saw how to enter user input into the script via the command line. But in many cases, setting all the input values ​​in the script is not practical. You can get input from the user while the script is running. If you are familiar with Python, using read is similar to the input function in Python.

Use the read keyword for this purpose. The word read stops the script and receives input from the user and saves it within the variable specified for later use. For example, below we want to get the target IP address from the user and store it in the ip variable:

#!/bin/bash

echo "Target IP Address"
read ip
echo "Target IP Address is: $ip"

Here you get the IP and print it simply:

There are other features as well. Consider the following example:

#!/bin/bash

echo "Please enter a username"
read user
echo "Please enter a password"
read -s pass
read -p "The IP Address?" ip
echo username: $user password: $pass IP Address: $ip

By entering the -s option, the user input is not displayed while typing. This option is usually used while entering the password because we do not want it to be displayed on the console. You can write everything in one line by adding the -p option:

By executing the script, the required items are received from the user and later you can use them in your script to perform operations.

select

Another way to get inputs from the user is to use the select keyword, which works as a menu. To do this, first enter the keyword select, then the name of your variable, and then the word in, then a list of options to select. Then we enter the word do and then the executable content. Here we print only the value selected by the user with the echo command. It is very important to end the loop with the break keyword:

#!/bin/bash

select ogy in "Psychology" "Psychiatry" "Criminology" "Astrology"
do
    echo "Your selected major is $ogy"
    break
done

By executing the above script, a list of selected items is displayed for the user. When the user can enter the desired number, he can determine his selected route.

This feature can also be written using the case structure. Enter a case statement here and create a different output for each option. Note that we have added an option called Exit, which if the user enters, the break is executed and exits the program. The * option also causes other items that are not in the list:

select ogy in "Psychology" "Psychiatry" "Criminology" "Astrology"
do
    case $option in
    "Psychology")  echo "Psychology is the science of mind and behavior.";;
    "Psychiatry")  echo "Psychiatry is the medical specialty devoted to the diagnosis, prevention, and treatment of mental disorders.";;
    "Criminology") echo "Criminology is the study of crime and deviant behaviour.";;
    "Astrology")   echo "Astrology is a pseudoscience that claims to divine information about human affairs and terrestrial events by studying the movements and relative positions of celestial objects";;
    "exit")    break;;
     *)     echo "Not defined"
 esac
done

If we run the script, first enter option 2 to display the output of Psychiatry and then enter another option. Finally, we leave the program:

Exception Management

Although it is very important to get input from the user, you should also manage possible errors. What happens if the user does not enter the options and presses Enter? Is your script working properly in this situation? Let's first give an example that a script needs three arguments to run:

#!/bin/bash

if [ $# -lt 3 ];
then
    cat <<- END
    This script needs three arguments:
    ./exception <TARGET> <PORT> <SCHEME>
    END
else
 echo "$3://$1:$2"
fi

This script first checks the number of arguments with $# and if the number of arguments entered is less than three by here-doc displays text as a guide to the user. If the number of arguments is correct, the script inputs will be printed:

First, we enter without argument. An alert is received. With one argument entered, warning again, but if we enter three arguments, the script will run correctly.

Another way is to create a loop, the result of which the user only has to enter the value, otherwise, the user will receive the error message:

#!/bin/bash

read -p "hostname: " host
while [[ -z "$host" ]]
do 
 read -p "hostname has not been entered!
hostname: " host
done
echo "Entered hostname is $host"

This alert continues until the user enters the requested amount:

The best way is to give this default answer to the user to select:

#!/bin/bash

read -p "hostname: [default:localhost] " host
while [[ -z "$host" ]]
do 
 host="localhost"
done
echo "entered hostname is $host"

If the user presses the enter button, the default option here is localhost. -z option means if the host variable is none:

Another method you can use to validate data is regular expressions:

#!/bin/bash

read -p "hostname: " host
while [[ ! $host =~ [\w\.]+ ]]
do
 read -p "The hostname is incorrect:  $host
hostname: " host
done
echo "Entered hostname is $host"

If our input does not match the specified regular expressions, we will receive a warning message to enter the correct input:

May 6, 2021
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
© HAKIN9 MEDIA SP. Z O.O. SP. K. 2023
What certifications or qualifications do you hold?
Max. file size: 150 MB.
What level of experience should the ideal candidate have?
What certifications or qualifications are preferred?

Download Free eBook

Step 1 of 4

Name(Required)

We’re committed to your privacy. Hakin9 uses the information you provide to us to contact you about our relevant content, products, and services. You may unsubscribe from these communications at any time. For more information, check out our Privacy Policy.