Secret Life of Hashes Divulged – Length Extension Attack Explained
Autor: Bikramaditya Guha | Publicado: 2016-05-23T01:14:00-07:00



















Sounds
interesting!! Doesn’t it? Well, it sounds to me and so I want it penned down.
Let’s see how this goes. 

If you feel
you’ve nailed it after reading through the entire blog, then I can consider
diving deep into the blogging world. It’s my second post within 24 hours and I
already feel I was born for it. Let’s not bore you guys with my shit, and learn
something about a new form of cryptographic attack called the Hash Length
Extension Attack, instead.

It all started
when I was at Goa in India (an exotic place to be in for sure) a year ago for
the null conference. I know, when I say Goa, the only thought that comes to
your mind is the beaches – pristine blue with golden sand and perhaps a bottle
of Goa’s favorite chilled beer “Kings”.&nbsp;
The thought of not attending the conference crossed my mind, but then my
Boss gave me an intensive look and there I was, (‘Coz my employer paid for the
trip). I already knew that I was going to hate it but things changed at the
blink of an eye the moment I entered the conference. One of the trainings at
this conference was about an attack called a Hash Length Extension Attack. This
was the first time I've heard it and it kept me on my toes for the entire
session. 

Half way down
the session, I realized that the attack is not only super awesomely cool, but
also conceptually easy to understand and perform. To make your job much easier,
there are various modules available over the internet such as HashPump and hash_extender. There’s
another module which I like personally, is the one from Stephen Bradshaw called
hlextend. This module can be found at GitHub.

As per
Wikipedia, the basic definition of this attack goes by: 

“In cryptography and computer security, a
length extension attack is a type of attack where an attacker can use Hash
(message1) and the length of message1 to calculate Hash (message1 ∥ message2). This attack can be
used to sign a message when a Merkle–Damgard based hash is misused as a message
authentication code, allowing for inclusion of extra information.

This attack can be done on hashes with
construction H (secret ∥
message) when message and the length of secret is known. Algorithms like MD5,
SHA-1, and SHA-256 that are based on the Merkle–Damgard construction are
susceptible to this kind of attack.”

Before we
begin, a quick go-through on how Hashing works:

<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->Hash functions operate on fixed block sizes

<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->Input data is split into fix-sized parts equal
to the block size

<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->If any of these parts is smaller than block size
(mostly the last part), the missing bytes are padded

<!--[if !supportLists]-->ü&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->PKCS7

<!--[if !supportLists]-->ü&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->Bit Padding

<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->The hash value represents the internal state of
the hash function

<!--[if !supportLists]-->ü&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->You can simply continue adding data + padding
and hash again using the internal state

The Attack:

Let’s assume a
web application which uses a known hash generated from an unknown secret value
tied to a user entered input. The basic purpose of doing so is to check the
integrity of the entered value to avoid any form of manipulation. For example,
let’s assume the desired SHA1 hash value generated with an unknown secret
length for a valid parameter value ‘student’
is ‘204036A1EF6E7360E536300EA78C6AEB4A9333DD’.
So, if we try to access the below mentioned URL, we get all the details of a
student. 





<!--[if gte vml 1]><v:shapetype
 id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe">
 
 
<v:shape id="Text_x0020_Box_x0020_2" o:spid="_x0000_s1027"
 type="#_x0000_t202" style='position:absolute;left:0;text-align:left;
 margin-left:.75pt;margin-top:75.75pt;width:538.5pt;height:33.45pt;z-index:2;
 visibility:visible;mso-wrap-distance-top:3.6pt;mso-wrap-distance-bottom:3.6pt;
 mso-position-horizontal-relative:margin' fillcolor="#333">
 <v:fill color2="black" rotate="t" focusposition=".5,.5" focussize="" focus="100%"
  type="gradientRadial"/>
 
 
  <![if !mso]>
  

    <![endif]>
    
    
<b
    style='mso-bidi-font-weight:normal'>Manipulated URL:
    http://127.0.0.1/index.php?param=/../../../../etc/passwd&amp;hash=
    204036A1EF6E7360E536300EA78C6AEB4A9333DD 

<![if !mso]>
   

<![endif]>
 
<![endif]--><!--[if !vml]--><!--[endif]-->Cool! I guess that’s what the
application was supposed to do. <!--[if gte vml 1]><v:shape id="_x0000_s1026"
 type="#_x0000_t202" style='position:absolute;left:0;text-align:left;
 margin-left:.75pt;margin-top:.75pt;width:538.5pt;height:20.7pt;z-index:1;
 visibility:visible;mso-wrap-distance-top:3.6pt;mso-wrap-distance-bottom:3.6pt;
 mso-position-horizontal-relative:margin;mso-position-vertical-relative:text'
 fillcolor="#333">
 <v:fill color2="black" rotate="t" focusposition=".5,.5" focussize="" focus="100%"
  type="gradientRadial"/>
 
 
  <![if !mso]>
  

    <![endif]>
    
    
<b
    style='mso-bidi-font-weight:normal'>Valid URL:
    http://127.0.0.1/index.php?param=student&amp;hash=
    204036A1EF6E7360E536300EA78C6AEB4A9333DD 

<![if !mso]>
   

<![endif]>
 
<![endif]--><!--[if !vml]--><!--[endif]-->It’s a valid request after all. Let’s see
what happens if we try to play with the ‘param’
value. Let’s try to access the ‘/etc/passwd/’
file using path traversal. What do you think will happen?





















Oops!! File not
found. 

Of course! And
did you think it was that easy? So what do you think happened?&nbsp; 

Well, the
requested file did not match the above SHA1 hash value since it belonged to ‘student’. In order to perform this
attack successfully, we would need a valid SHA1 hash value for the ‘/../../../../etc/passwd’ file, combined
with an unknown length of the secret value. 

And how do you
think we get that? Well, the first thing we need to do is to guess the length
of the secret value. Without which it won’t be possible to generate a valid
hash. In such cases, brute forcing the value by trying multiple different
lengths can sometimes be possible, depending on the application. 

Let’s first see
what all data we already have that might come in handy:

Known Data: student

Hash of known Data: 204036A1EF6E7360E536300EA78C6AEB4A9333DD

Extended Data: /../../../../etc/passwd

Hash of Extended Data:
&lt;unknown&gt;

Length of secret: &lt;unknown&gt;

Great!!

If I have to
explain it in simple words, the application creates a sha1 hash value of '204036A1EF6E7360E536300EA78C6AEB4A9333DD',
by concatenating an unknown secret of length ‘X’ and known data of 'student'.
You wish to append the text '/../../../../etc/passwd'
after 'student' and also provide a
valid hash back to the application that it will produce when it concatenates
your provided value (which will include the string 'student' followed by '/../../../../etc/passwd')
with its secret.

I hope by now
you already know what our ultimate goal is. Ready for some action!!! Here we
go……

The goal is to
read the /etc/passwd file, via
bypassing the hash integrity check on the param parameter. This is what the
script below will automate using the hlextend module to generate the extended
hash values.

And the
output:



<!--[if gte vml 1]><v:shape
 id="_x0000_s1031" type="#_x0000_t202" style='position:absolute;left:0;
 text-align:left;margin-left:0;margin-top:78.55pt;width:533.25pt;height:320.25pt;
 z-index:6;visibility:visible;mso-wrap-distance-top:3.6pt;
 mso-wrap-distance-bottom:3.6pt;mso-position-horizontal:left;
 mso-position-horizontal-relative:margin' fillcolor="#999">
 <v:fill color2="black" rotate="t" focusposition=".5,-52429f" focussize=""
  colors="0 #cbcbcb;26214f #c3c3c3;1 black" focus="100%" type="gradientRadial"/>
 
  <![if !mso]>
  

    <![endif]>
    
    
<span
    style='color:white'>   
    root:x:0:0:root:/root:/bin/bash

<span
    style='color:white'>   
    daemon:x:1:1:daemon:/usr/sbin:/bin/sh

<span
    style='color:white'>   
    bin:x:2:2:bin:/bin:/bin/sh

<span
    style='color:white'>   
    sys:x:3:3:sys:/dev:/bin/sh

<span
    style='color:white'>   
    sync:x:4:65534:sync:/bin:/bin/sync

<span
    style='color:white'>   
    games:x:5:60:games:/usr/games:/bin/sh

<span
    style='color:white'>   
    man:x:6:12:man:/var/cache/man:/bin/sh

<span
    style='color:white'>   
    lp:x:7:7:lp:/var/spool/lpd:/bin/sh

<span
    style='color:white'>   
    mail:x:8:8:mail:/var/mail:/bin/sh

<span
    style='color:white'>   
    news:x:9:9:news:/var/spool/news:/bin/sh

<span
    style='color:white'>   
    uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh

<span
    style='color:white'>    proxy:x:13:13:proxy:/bin:/bin/sh

<span
    style='color:white'>   
    www-data:x:33:33:www-data:/var/www:/bin/sh

<span
    style='color:white'>   
    backup:x:34:34:backup:/var/backups:/bin/sh

<span
    style='color:white'>   
    list:x:38:38:Mailing List Manager:/var/list:/bin/sh

<span
    style='color:white'>   
    irc:x:39:39:ircd:/var/run/ircd:/bin/sh

<span
    style='color:white'>   
    gnats:x:41:41:Gnats Bug-Reporting System
    (admin):/var/lib/gnats:/bin/sh

<span
    style='color:white'>   
    nobody:x:65534:65534:nobody:/nonexistent:/bin/sh

<span
    style='color:white'>   
    libuuid:x:100:101::/var/lib/libuuid:/bin/sh

<span
    style='color:white'>   
    dhcp:x:101:102::/nonexistent:/bin/false

<span
    style='color:white'>   
    syslog:x:102:103::/home/syslog:/bin/false

<span
    style='color:white'>   
    klog:x:103:104::/home/klog:/bin/false

<span
    style='color:white'>&nbsp;

<![if !mso]>
   

<![endif]>
 
<![endif]--><!--[if !vml]--><!--[endif]-->Once we access the above displayed URL:







You may notice
that the new value produced above contains a lot of additional data (in this
case, a 0x80 followed by a number of 0x00s and a message length, which is the
length of the key plus the original message, appended at the end) between the 'student' and the '/../../../../etc/passwd' - this is hex encoded padding data used by
the hash algorithm that needs to be integrated into the hashed data in order
for the attack to work - So strictly speaking you can't
specify the EXACT value to append, only what comes after the padding, but under
the right circumstances you can make the application ignore this extra padding.

So in short, if
the hash algorithm used is vulnerable, it is possible to achieve this without
knowing the secret value as long as you know (or can guess, perhaps by brute
force) the length of that secret value. This is called a hash length extension
attack.


Happy Hacking my Friends!!!