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.
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.
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.
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.
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:
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
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, 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.
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.
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.
Want to start making money as a white hat hacker? Jump-start your hacking career with our 2020 Premium Ethical Hacking Certification Training Bundle from the new Null Byte Shop and get over 60 hours of training from cybersecurity professionals.
Other worthwhile deals to check out: