10 Programing With Bash And Create A Script For Hacking, Free Hacking Complete Course Step By Step
Free Hacking Complete Course Step By Step
Programming For Scripts
In this blog we will look at some basic examples of computer programming. We will look at writing programs to automate various useful tasks in multiple programming languages. Even though we use prebuilt software for the majority of this book, it is useful to be able to create your own programs.
Bash Scripting
In this section we’ll look at using Bash scripts to run several commands at once. Bash scripts, or shell scripts, are files that include multiple terminal commands to be run. Any command we can run in a terminal can be run in a script.
Ping
We’ll call our first script pingscript.sh. When it runs, this script will perform a ping sweep on our local network that sends Internet Control Message Protocol (ICMP) messages to remote systems to see if they respond. We’ll use the ping tool to determine which hosts are reachable on a network.
(Although some hosts may not respond to ping requests and may be up despite not being “pingable,” a ping sweep is still a good place to start.) By default, we supply the IP address or hostname to ping. For example, to ping our Windows XP / 7 / 8 target, enter the bold code in Listing.
root@kali:~/# ping 192.168.20.10
PING 192.168.20.10 (192.168.20.10) 56(84) bytes of data.
64 bytes from 192.168.20.10: icmp_req=1 ttl=64 time=0.090 ms
64 bytes from 192.168.20.10: icmp_req=2 ttl=64 time=0.029 ms
64 bytes from 192.168.20.10: icmp_req=3 ttl=64 time=0.038 ms
64 bytes from 192.168.20.10: icmp_req=4 ttl=64 time=0.050 ms
^C
--- 192.168.20.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999 ms
rtt min/avg/max/mdev = 0.029/0.051/0.090/0.024 ms
We can tell from the ping output that the Windows XP / 7 / 8 target is up and responding to ping probes because we received replies to our ICMP requests. (The trouble with ping is that it will keep running forever unless you stop it with ctrl-C.)
A Simple Bash Script
Let’s begin writing a simple Bash script to ping hosts on the network. A good place to start is by adding some help information that tells your users how to run your script correctly.
#!/bin/bash
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
The first line of this script tells the terminal to use the Bash interpreter. The next two lines that begin with echo simply tell the user that our ping script will take a command line argument (network), telling the script which network to ping sweep (for example, 192.168.20). The echo command will simply print the text in quotes.
Note : This script implies we are working with a class C network, where the first three octets
of the IP address make up the network.
After creating the script, use chmod to make it executable so we can run it.
root@kali:~/# chmod 744 pingscript.sh
Running Our Script
Previously, when entering Linux commands, we typed the command name at the prompt. The filesystem location of built-in Linux commands as well as pentest tools added to Kali Linux are part of our PATH environmental variable. The PATH variable tells Linux which directories to search for executable files. To see which directories are included in our PATH, enter echo $PATH.
root@kali:~/# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Notice in the output that the /root directory is not listed. That means that we won’t be able to simply enter pingscript.sh to run our Bash script. Instead we’ll enter ./pingscript.sh to tell the terminal to run the script from our current directory. As shown next, the script prints the usage information.
root@kali:~/# ./pingscript.sh
Usage: ./pingscript.sh [network]
example: ./pingscript.sh 192.168.20
Adding Functionality with if Statements
Now let’s add in a bit more functionality with an if statement, as shown in Listing.
#!/bin/bash
if [ "$1" == "" ] (1)
then (2)
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
fi (3)
Typically a script needs to print usage information only if the user uses it incorrectly. In this case, the user needs to supply the network to scan as a command line argument. If the user fails to do so, we want to inform the user how to run our script correctly by printing the usage information.
To accomplish this, we can use an if statement to see if a condition is met. By using an if statement, we can have our script echo the usage information only under certain conditions—for example, if the user does not supply a command line argument.
The if statement is available in many programming languages, though the syntax varies from language to language. In Bash scripting, an if statement is used like this: if [condition], where condition is the condition that must be met.
In the case of our script, we first see whether the first command line argument is null (1). The symbol $1 represents the first command line argument in a Bash script, and double equal signs (==) check for equality. After the if statement, we have a then statement (2). Any commands between the then statement and the fi (if backward) (3) are executed only if the conditional statement is true—in this case, when the first command line argument to the script is null.
When we run our new script with no command line argument, the if statement evaluates as true, because the first command line argument is indeed null, as shown here.
root@kali:~/# ./pingscript.sh
Usage: ./pingscript.sh [network]
example: ./pingscript.sh 192.168.20
As expected we see usage information echoed to the screen.
A for Loop
If we run the script again with a command line argument, nothing happens. Now let’s add some functionality that is triggered when the user runs the script with the proper arguments, as shown in Listing.
#!/bin/bash
if [ "$1" == "" ]
then
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
else (1)
for x in `seq 1 254`; do (2)
ping -c 1 $1.$ (3)
done w
fi
After our then statement, we use an else statement (1) to instruct the script to run code when the if statement evaluates as false—in this case, if the user supplies a command line argument. Because we want this script to ping all possible hosts on the local network, we need to loop through the numbers 1 through 254 (the possibilities for the final octet of an IP version 4 address) and run the ping command against each of these possibilities.
An ideal way to run through sequential possibilities is with a for loop (2). Our for loop, for x in `seq 1 254`; do, tells the script to run the code that follows for each number from 1 to 254. This will allow us to run one set of instructions 254 times rather than writing out code for each instance. We denote the end of a for loop with the instruction done (3).
Inside the for loop, we want to ping each of the IP addresses in the network. Using ping’s man page, we find that the -c option will allow us to limit the number of times we ping a host. We set -c to 1 so that each host will be pinged just once.
To specify which host to ping, we want to concatenate the first command line argument (which denotes the first three octets) with the current iteration of the for loop. The full command to use is ping -c 1 $1.$x. Recall that the $1 denotes the first command line argument, and $x is the current iteration of the for loop. The first time our for loop runs, it will ping 192.168.20.1, then 192.168.20.2, all the way to 192.168.20.254. After iteration 254, our for loop finishes.
When we run our script with the first three octets of our IP address as the command line argument, the script pings each IP address in the network as shown in Listing.
root@kali:~/# ./pingscript.sh 192.168.20
PING 192.168.20.1 (192.168.20.1) 56(84) bytes of data.
64 bytes from 192.168.20.1: icmp_req=1 ttl=255 time=8.31 ms (1)
--- 192.168.20.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 8.317/8.317/8.317/0.000 ms
PING 192.168.20.2(192.168.20.2) 56(84) bytes of data.
64 bytes from 192.168.20.2: icmp_req=1 ttl=128 time=166 ms
--- 192.168.20.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 166.869/166.869/166.869/0.000 ms
PING 192.168.20.3 (192.168.20.3) 56(84) bytes of data.
From 192.168.20.13 icmp_seq=1 Destination Host Unreachable (2)
--- 192.168.20.3 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
--snip--
Your results will vary based on the systems in your local network. Based on this output, I can tell that in my network, the host 192.168.20.1 is up, and I received an ICMP reply (1). On the other hand, the host 192.168.20.3 is not up, so I received a host unreachable notification (2).
Streamlining the Results
All this information printed to screen is not very nice to look at, and anyone who uses our script will need to sift through a lot of information to determine which hosts in the network are up. Let’s add some additional functionality to streamline our results.
In the previous blog we covered grep, which searches for and matches specific patterns. Let’s use grep to filter the script’s output, as shown in Listing.
#!/bin/bash
if [ "$1" == "" ]
then
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
else
for x in `seq 1 254`; do
ping -c 1 $1.$x | grep "64 bytes" (1)
done
fi
Here we look for all instances of the string 64 bytes (1), which occurs when an ICMP reply is received when pinging a host. If we run the script with this change, we see that only lines that include the text 64 bytes are printed to the screen, as shown here.
root@kali:~/# ./pingscript.sh 192.168.20
64 bytes from 192.168.20.1: icmp_req=1 ttl=255 time=4.86 ms
64 bytes from 192.168.20.2: icmp_req=1 ttl=128 time=68.4 ms
64 bytes from 192.168.20.8: icmp_req=1 ttl=64 time=43.1 ms
--snip--
We get indicators only for live hosts; hosts that do not answer are not printed to the screen.
But we can make this script even nicer to work with. The point of our ping sweep is to get a list of live hosts. By using the cut command discussed in Future Blogs, we can print the IP addresses of only the live hosts, as shown in Listing.
#!/bin/bash
if [ "$1" == "" ]
then
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
else
for x in `seq 1 254`; do
ping -c 1 $1.$x | grep "64 bytes" | cut -d" " -f4 (1)
done
fi
We can use a space as the delimiter and grab the fourth field, our IP address, as shown at (1).
Now we run the script again as shown here.
root@kali:~/mydirectory# ./pingscript.sh 192.168.20
192.168.20.1:
192.168.20.2:
192.168.20.8:
--snip--
Unfortunately, we see a trailing colon at the end of each line. The results would be clear enough to a user, but if we want to use these results as input for any other programs, we need to delete the trailing colon. In this case, sed is the answer.
The sed command that will delete the final character from each line is sed 's/.$//', as shown in Listing.
#!/bin/bash
if [ "$1" == "" ]
then
echo "Usage: ./pingscript.sh [network]"
echo "example: ./pingscript.sh 192.168.20"
else
for x in `seq 1 254`; do
ping -c 1 $1.$x | grep "64 bytes" | cut -d" " -f4 | sed 's/.$//'
done
fi
Now when we run the script, everything looks perfect, as shown here.
root@kali:~/# ./pingscript.sh 192.168.20
192.168.20.1
192.168.20.2
192.168.20.8
--snip--
NOTE : Of course, if we want to output the results to a file instead of to the screen, we can use the >> operator, covered in Future Blogs, to append each live IP address to a file. Try automating other tasks in Linux to practice your Bash scripting skills.
In our last blog we learn How Use Kali Linux Command Line, our next tops will be learn about Programing With Python and Create Script For Hacking attacks which we will attack. If you have not followed us yet, then do so so that you do not miss the upcoming topics. Click Here To Read Our Blogs From Getting Started.
Comments
Post a Comment