Automation has been a buzz word for quite some time now, but the principles behind it are as strong as ever. For a hacker or pentester, Bash scripting is one form of automation that cannot be ignored. Virtually any command that can be run from the terminal can be scripted — and should be, in many cases — to save valuable time and effort. And a Bash script just happens to be great for recon.
Step 1: Start the Script
To get started, create a Bash script and name it whatever you like. I'll call mine recon.sh. Using your favorite text editor, make the first line look like this:
#!/bin/bash
This is called a shebang, or hashbang, and simply points to the system's interpreter for Bash.
Next, we'll make sure the user supplies input to the script, and if not, prints a usage example and exits. Use a conditional if-then block:
if [ -z "$1" ]
then
echo "Usage: ./recon.sh <IP>"
exit 1
fi
The $1 is the argument we will pass to the script, and the -z option returns true if the string is null. So basically, this says if no argument is passed, print the usage example and exit. The argument we'll use is an IP address.
Step 2: Scan the Host
The next section will run an Nmap scan on the host IP address we supply. First, we'll print a heading for Nmap just to keep things pretty and organized:
printf "\n----- NMAP -----\n\n" > results
We use printf here because it handles newlines (\n) more reliably than echo. This is being written to a text file called results — it will first create the file since it doesn't exist yet, and it will overwrite the file in the future with subsequent scans.
Next, we will print a message and actually run the command:
echo "Running Nmap..."
nmap $1 | tail -n +5 | head -n -3 >> results
The nmap command takes the argument we supplied the script, the IP address, and appends the results to our output file. The tail and head commands remove some lines from the beginning and end of the Nmap output — this is just my personal preference and makes it look a little cleaner in my opinion.
Step 3: Enumerate HTTP
The next section will take the results of the Nmap scan and attempt to enumerate HTTP if certain criteria are met. We will run Gobuster to scan for directories and WhatWeb to get some information about the web server.
We'll use a while loop to read each line from our results file, and if it finds an open port running HTTP, it will kick off Gobuster and WhatWeb:
while read line
do
if [[ $line == *open* ]] && [[ $line == *http* ]]
then
echo "Running Gobuster..."
gobuster dir -u $1 -w /usr/share/wordlists/dirb/common.txt -qz > temp1
echo "Running WhatWeb..."
whatweb $1 -v > temp2
fi
done < results
If an open HTTP port is found, the code in the if-then block will run. Gobuster takes the IP address we supplied as the -u option and uses a wordlist specified by the -w option. We will also use the -q and -z options here to disable the banner and hide the progress — again, just to keep the output tidy. This will write to a temporary file that will be utilized later in the script.
WhatWeb simply takes the IP address we supplied and writes the output to a second temporary file. The -v option here gives us verbose results. When the while loop exhausts all lines of the results file, it completes, and the script moves on to the next section.
Step 4: Display the Results
The next block of code will determine if the temporary files from earlier exist, and if so, will append the output to the main results file:
if [ -e temp1 ]
then
printf "\n----- DIRS -----\n\n" >> results
cat temp1 >> results
rm temp1
fi
if [ -e temp2 ]
then
printf "\n----- WEB -----\n\n" >> results
cat temp2 >> results
rm temp2
fi
The -e option checks if the file exists — if it does, the code after then runs. It prints another heading, writes the contents of the temporary file to our results, and removes the temporary file.
Finally, the last line of our script will simply display the results on our screen:
cat results
Step 5: Review the Script
The entire script should now look like this:
#!/bin/bash
if [ -z "$1" ]
then
echo "Usage: ./recon.sh <IP>"
exit 1
fi
printf "\n----- NMAP -----\n\n" > results
echo "Running Nmap..."
nmap $1 | tail -n +5 | head -n -3 >> results
while read line
do
if [[ $line == *open* ]] && [[ $line == *http* ]]
then
echo "Running Gobuster..."
gobuster dir -u $1 -w /usr/share/wordlists/dirb/common.txt -qz > temp1
echo "Running WhatWeb..."
whatweb $1 -v > temp2
fi
done < results
if [ -e temp1 ]
then
printf "\n----- DIRS -----\n\n" >> results
cat temp1 >> results
rm temp1
fi
if [ -e temp2 ]
then
printf "\n----- WEB -----\n\n" >> results
cat temp2 >> results
rm temp2
fi
cat results
Step 6: Run the Script
Now we should be ready to run our recon script. In my example, I'm using Metasploitable 2 as the target.
First, make the script executable:
~# chmod +x recon.sh
If we try to run it without an argument, it gives us the usage example:
~# ./recon.sh
Usage: ./recon.sh <IP>
Simply supply the IP address and run it again:
~# ./recon.sh 10.10.0.50
Running Nmap...
Running Gobuster...
Running WhatWeb...
/usr/lib/ruby/vendor_ruby/target.rb:188: warning: URI.escape is obsolete
----- NMAP -----
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
512/tcp open exec
513/tcp open login
514/tcp open shell
1099/tcp open rmiregistry
1524/tcp open ingreslock
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
5432/tcp open postgresql
5900/tcp open vnc
6000/tcp open X11
6667/tcp open irc
8009/tcp open ajp13
8180/tcp open unknown
----- DIRS -----
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/.bash_history (Status: 200)
/cgi-bin/ (Status: 403)
/dav (Status: 301)
/phpMyAdmin (Status: 301)
/index (Status: 200)
/index.php (Status: 200)
/test (Status: 301)
/twiki (Status: 301)
/phpinfo (Status: 200)
/phpinfo.php (Status: 200)
----- WEB -----
WhatWeb report for http://10.10.0.50
Status : 200 OK
Title : Metasploitable2 - Linux
IP : 10.10.0.50
Country : RESERVED, ZZ
Summary : WebDAV[2], X-Powered-By[PHP/5.2.4-2ubuntu5.24], Apache[2.2.8], PHP[5.2.4-2ubuntu5.24], HTTPServer[Ubuntu Linux][Apache/2.2.8 (Ubuntu) DAV/2]
Detected Plugins:
[ Apache ]
The Apache HTTP Server Project is an effort to develop and
maintain an open-source HTTP server for modern operating
systems including UNIX and Windows NT. The goal of this
project is to provide a secure, efficient and extensible
server that provides HTTP services in sync with the current
HTTP standards.
Version : 2.2.8 (from HTTP Server Header)
Google Dorks: (3)
Website : http://httpd.apache.org/
[ HTTPServer ]
HTTP server header string. This plugin also attempts to
identify the operating system from the server header.
OS : Ubuntu Linux
String : Apache/2.2.8 (Ubuntu) DAV/2 (from server string)
[ PHP ]
PHP is a widely-used general-purpose scripting language
that is especially suited for Web development and can be
embedded into HTML. This plugin identifies PHP errors,
modules and versions and extracts the local file path and
username if present.
Version : 5.2.4-2ubuntu5.24
Google Dorks: (2)
Website : http://www.php.net/
[ WebDAV ]
Web-based Distributed Authoring and Versioning (WebDAV) is
a set of methods based on the Hypertext Transfer Protocol
(HTTP) that facilitates collaboration between users in
editing and managing documents and files stored on World
Wide Web servers. - More Info:
http://en.wikipedia.org/wiki/WebDAV
Version : 2
[ X-Powered-By ]
X-Powered-By HTTP header
String : PHP/5.2.4-2ubuntu5.24 (from x-powered-by string)
HTTP Headers:
HTTP/1.1 200 OK
Date: Wed, 19 Jun 2019 18:03:39 GMT
Server: Apache/2.2.8 (Ubuntu) DAV/2
X-Powered-By: PHP/5.2.4-2ubuntu5.24
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html
It tells us what's running (ignore the ruby error for WhatWeb) and prints out a nice display of the results when it is done.
Expanding the Script
In its current state, this Bash script isn't complicated. It runs an Nmap scan, and if an open HTTP port is found, it kicks off Gobuster and WhatWeb. While useful, this could be expanded in many ways.
First of all, we're only running a basic Nmap scan. We could scan additional ports, run the default scripts, enable OS detection, and more. Basically, anything you can do from the command line you can put in the script. The same thing goes for Gobuster and WhatWeb.
We could also expand the script to enumerate other services besides HTTP. Things like SMB, SSH, and FTP could all be good candidates to add in there. Again, Bash scripting is powerful because it is possible to automate many of the functions typically used in a command-line form.
Wrapping Up
In this tutorial, we created a Bash script to automate some of the activities used in the reconnaissance phase of a penetration test. The script took an IP address as an argument, ran an Nmap scan on the target, and if an open HTTP port was found, kicked off Gobuster and WhatWeb. Bash Scripting is extremely powerful, and even this simple script saved us a ton of time and typing.
Just updated your iPhone to iOS 18? You'll find a ton of hot new features for some of your most-used Apple apps. Dive in and see for yourself:
1 Comment
Really appreciate this. I've a few linux boxes and this will help with repetitive
tasks.
Share Your Thoughts