SANS Penetration Testing

Modern Web Application Penetration Testing Part 2, Hash Length Extension Attacks

By: Adrien de Beaupre

I will be teaching SANS SEC642: Advanced Web App Penetration Testing, Ethical Hacking, and Exploitation Techniques at many events this year, I am also the co-author for the course. AKA the most advanced web app pentest course on the planet, probably the galaxy! This is one of the many techniques that I will be exploring in this series of posts.

I had the opportunity to sit with my friend Ron Bowes @iagox86 a while back to talk about SEC642 content and the state of web application penetration testing in general. He mentioned hash length extension attacks, and that coincidentally he had written the absolute best tool to exploit it! Definitely something that we could consider adding. Ron has also done writeups for CTF challenges that can be solved using his tool.

So I have some of the ingredients that we can talk about. We have a topic, we have a tool, and all that we need is a vulnerable application. We found a couple that had been used in CTFs, and one that also included some other interesting crypto challenges called CryptOMG by SpiderLabs. They published the solutions to the first and second challenges on their blog. This is the solution to the fifth challenge which is a hash length extension attack, and of course we will use hash_extender to do so. Installing CryptOMG is covered in Appendix A.

Opening up the new site in a browser and we see this:


The challenge appears to be a Local File Include (LFI) to see the contents of /etc/passwd.

Selecting Challenge 5 and we see the following:


Selecting SHA1 as the Algorithm and clicking on the test link proxying through Burp gives us the parameters that we presumable have to play with to succeed.



algo=sha1, file=test, and hash=dd03bd22af3a4a0253a66621bcb80631556b100e


Sending the same GET request to repeater and we see the following response:


We now have a baseline request that gives us a 200 response code, and presumably the contents of the file called test in the HTML.

If this were HMAC we would need the secret. Brute forcing that might take a while, so let's try a hash extension attack. Without knowing the secret we can append to the file name parameter and try a directory traversal with a LFI attack. We just need to be able to create a valid hash. So our attack will look something like this:

algo=sha1, file=test/../../../../etc/passwd, and hash=??

The problem is that we do not know the secret, and also do not know the length of the secret. This is what we need to append our data to the input parameter, assuming that they did something like this to create the hash:


Where they concatenate something that we can control with something that we do not to generate a hash. The magic of this attack is that we can append to the filename and still generate a valid hash without knowing the secret! However we do have to guess the length of the secret, or brute force it. In this case we are going to assume that the secret length lies between 10 and 40 bytes.

Enter hash_extender to the rescue. Downloading it from git and making it is quick and easy. The instructions are in Appendix B.

Running the following should give us some file names and hashes to try!

./hash_extender -f sha1 --data 'test' -s dd03bd22af3a4a0253a66621bcb80631556b100e --append '../../../../../../../../../etc/passwd' --secret-min=10 --secret-max=40 --out-data-format=html --table > hashesnsignatures.out

(I had intended to put a crazy one liner in there, but Ron is way cooler and more l33t than me). The first time I tried it I had not put enough ../ in and got a 200 response code without the file contents. 9 seemed like a good number. If we are not successful we see a 404 response code and the HTML does not contain the file that we are looking for:


Running the results from hash_extender through Burp Intruder we get a hit. This was done with the hashes in one file, the strings in another, with both used as payloads to Pitchfork.



As it turns out the length of the secret was 34 bytes. Let's see what we have!



Success! Without knowing a 34 character secret password we are still able to grab the contents of /etc/passwd through the hash extension attack.


This is one of the many practical attack techniques that we teach in the SANS course SEC642.

Also see:

Modern Web Application Penetration Testing Part 1, XSS and XSRF Together


Cheers, Adrien de Beaupré Inc.
Certified SANS Instructor
Co-author of SANS SEC642: Advanced Web App Penetration Testing, Ethical Hacking, and Exploitation Techniques




Appendix A: Installing CryptOMG: (Using Ubuntu 14.04; apache, mysql, and php5 are already installed)

# cd /var/www/html

# git clone

# apt-get install libmcrypt4 php5-mysql php5-mcrypt

— edit /var/www/html/includes/ for mysql database settings

# php5enmod mcrypt

# service apache2 restart


Appendix B: Installing hash_extender: (again using Ubuntu, but in this case the Samurai WTF VM)

samurai@samuraiwtf:~/Downloads$ git clone

Cloning into 'hash_extender'...

remote: Counting objects: 587, done.

remote: Total 587 (delta 0), reused 0 (delta 0), pack-reused 587

Receiving objects: 100% (587/587), 153.34 KiB | 0 bytes/s, done.

Resolving deltas: 100% (396/396), done.

Checking connectivity... done.

samurai@samuraiwtf:~/Downloads$ cd hash_extender

samurai@samuraiwtf:~/Downloads/hash_extender$ make

[CC] buffer.o

[CC] formats.o

[CC] hash_extender.o

[CC] hash_extender_engine.o

[CC] test.o

[CC] util.o

[LD] hash_extender

[CC] hash_extender_test.o

[LD] hash_extender_test


samurai@samuraiwtf:~/Downloads/hash_extender$ ./hash_extender

hash_extender: -data or -file is required




By Ron Bowes <ron @>

See LICENSE.txt for license information.

Usage: ./hash_extender <-data=<data>|-file=<file>> -signature=<signature> -format=<format> [options]


-d -data=<data>

The original string that we're going to extend.


The format the string is being passed in as. Default: raw.

Valid formats: raw, hex, html, cstr


As an alternative to specifying a string, this reads the original string

as a file.

-s -signature=<sig>

The original signature.


The format the signature is being passed in as. Default: hex.

Valid formats: raw, hex, html, cstr

-a -append=<data>

The data to append to the string. Default: raw.


Valid formats: raw, hex, html, cstr

-f -format=<all|format> [REQUIRED]

The hash_type of the signature. This can be given multiple times if you

want to try multiple signatures. 'all' will base the chosen types off

the size of the signature and use the hash(es) that make sense.

Valid types: md4, md5, ripemd160, sha, sha1, sha256, sha512, whirlpool

-l -secret=<length>

The length of the secret, if known. Default: 8.



Try different secret lengths (both options are required)



Output the string in a table format.


Output data format.

Valid formats: none, raw, hex, html, html-pure, cstr, cstr-pure, fancy


Output signature format.

Valid formats: none, raw, hex, html, html-pure, cstr, cstr-pure, fancy


-h -help

Display the usage (this).


Run the test suite.

-q -quiet

Only output what's absolutely necessary (the output string and the


The arguments you probably want to give are (see above for more details):

-d <data>

-s <original signature>

-a <data to append>

-f <hash format>

-l <length of secret>



SANS Note:

Adrien de Beaupre is teaching, SANS SEC642: Advanced Web App Penetration Testing, Ethical Hacking, and Exploitation Techniques in Bethesda, MD in November, and London in November. Or you can take the course any time - online (pause, play, rewind) for 4-months of access to materials: SEC642: Ondemand


SANS Pen Test HackFest 2017


  • 2-Day Penetration Testing & Ethical Hacking Summit w/ 20+ Speakers
  • 3-Nights of SANS NetWars CtF w/ Coin-A-Palooza, your chance to earn up to five SANS Pen Test Challenge Coins
  • 1-Night of SANS CyberCity Missions - Hack/Defend a Modern City
  • Special Field Trip Experience for all Summit Attendees
  • 9 SANS Training Courses - 6-days of amazing SANS Training


Post a Comment


* Indicates a required field.