Friday 2 May 2014

Bypassing encrypted session tokens using CBC bit flipping technique.

In the last few weeks I have been studying Web Application hacking. Yesterday and today have been focused on session management. After struggling to understand how CBC bit flipping works, it was real "holy sh*t" moment when it finally hit me. This technique is awesome and was a lot of fun working it out and then applying my knowledge on an actual vulnerable web app. This post will cover the technique and not the discovery of these tokens. I have only just learnt this so I am still unsure of the best techniques to reveal if a token is encrypted and ran through CBC.

I will be using the vulnerable web application called Mutillidae to demonstrate this attack. Mutillidae is a free vulnerable web app maintained by Jeremy Druin and I believe it was initially started by Adrian Crenshaw. Its purpose is to aid in teaching and learning pentesting. It has been very useful in aiding me in performing and practising various web app hacks. More info and download can be found at:
https://www.owasp.org/index.php/OWASP_Mutillidae_2_Project

What is a session token?
A session token is a string of data that is used to maintain a HTTP session between you and the web browser. HTTP itself cannot maintain a session so there needs to be some way for the server to know that you have logged in. Without maintaining your session you would have to sign into a web page every time you refreshed or visited a new page within the same site. Sessions tokens are similar to cookies although they are somewhat different in the way they are handled. Cookies and tokens both serve the same purpose. The vulnerabilities that occur with maintaining sessions is that if an attacker is able to steal your session token or cookie they can simply connect to the website using your token and bypass the authentication process. Another way is to simple guess the token. An example would be a token using your username as its data. An attacker would only need to replace his token with your username an login as you. One method of defence that is commonly used to protect tokens is to encrypt them so they are unreadable and cannot be guessed. 

What is CBC bit flipping?
CBC stands for cipher block chaining. Taken from Wiki:
Each block of plaintext is XORed with the previous ciphertext block before being encrypted. This way, each ciphertext block depends on all plaintext blocks processed up to that point. To make each message unique, an initialization vector must be used in the first block.

Say you want to use AES encryption for your tokens. If your message you want to encrypt is "password" then each time you encrypt the word "password" it will always result in the same encrypted output. This poses a security risk as an attacker can reverse engineer this by simply encrypting a list of words and then comparing them to the encrypted values thus revealing the token. The attacker can then create his own token, encrypt it and use it to login as another user. CBC is a way of randomizing the output of the encrypted value. It works by using an IV or initialization vector. The IV is a random value that is used against each block of your encrypted value. The first block of plain text is XORed with the IV and then that value is XORed with the next block and it keeps doing this until each block is XORed with the last one. It looks like this:


XOR is a simple technique of switching bits. It works by comparing the bits of two values. In our case the IV and the plain text for the first block and the ciphertext and the plain text from then on. If they are both 0 then it remains 0. If it is 0-1 then it becomes 1. if it is 1-1, it becomes 0. Simple enough. More info can be found at: http://en.wikipedia.org/wiki/XOR_cipher

Because reversing XOR essentially requires flipping the bit, this is how we can attack it. This attack does not decrypt the original encryption but simply alters the cipher-text so it is un-xored down the chain. Say your token is called "admin". It is encrypted and ran through CBC to come out like this. aaabbbccc999. This is now our token that maintains our session. Now say an attacker named john logs in and gets sent the token cccbbbccc1111. The attacker can flip the bits one at a time and send them to the server and monitor the results. ffcbbbccc1111 is sent to the server and his user name changes from john to *ohn. So now he knows the first bit of the token ff converts to *. He now finds the value of 'a' and sends the token 7bcbbbccc1111 and it responds with 'aohn'. The attacker now has the first part of the username he wishes to login as. He simple keeps flipping the bits of the token until he has one that converts to "admin". Say it has come out to 7bdc995465. He would then just send a request to the server using that token and be logged in as admin. 

Demonstration
In Mutilidae version 2.6.10 there is a page called User Privilege Level. This is designed to practise the CBC bit flip attack. It is located under: OWASP 2013, Broken authentication and session management, Privilege escalation, view user privileges. 

As you can see the goal of this challenge is to change the user and group to 000. The first thing we need is the IV. How do we get the IV with nothing presented to us? We need to use a proxy that sits in-between us and the server. I will be using burp suite for this. Burp suite is tool used to aid in web app pentesting. You need to configure your browser to go through the burp proxy. Setting up burp is out of scope for this post. Information on setting up burp can be found at:

Once burp is setup and intercepting traffic simply refresh the page and trap it in burp.


If you look closely you can see the IV has been sent along with the request. 
6bc24fc1ab650b25b4114e93a98f1eba
A useful tool included in burp suite is the repeater. The repeater keeps a copy of this request and lets us alter it and send it to the server multiple times without having to manually keep refreshing the page and capturing a new request. Right click and choose send to repeater. Also note down the IV in notepad or something. With the request in the repeater tab, navigate to the repeater tab and click GO.


In the response view of the repeater open the tab "Render". This allows us to review the rendered response of the request we just sent. This is where we can start flipping the bits in the IV. Note is sais User is root. I believe this is a bug as it should only say that when we set the User ID and Group ID to 000. Start by changing each bit of the IV to FF and monitoring the response keep doing so until you are able to change the output of the user and group field. Example:
FFc24fc1ab650b25b4114e93a98f1eba
We can see this altered the first part of the Application ID. The next test we flip the second bit:
FFFF4fc1ab650b25b4114e93a98f1eba
FFFFFFc1ab650b25b4114e93a98f1eba
FFFFFFFFab650b25b4114e93a98f1eba
FFFFFFFFFF650b25b4114e93a98f1eba
This is where we find our user ID field has changed. The value is now User ID : e00 
Ok so we know the bit we need to alter to change the part of the user ID field. Note this down as we will need it later. Continue flipping bits until you get to the part of the Group ID that needs changing. 
At this point we find the correct value:
FFFFFFFFFFFFFFFFb4114e93a98f1eba
Iv marked down those bits in the original IV and returned the rest to the original values:
6bc24fc1FF650bFFb4114e93a98f1eba




So we have found the bits we need to alter to change the correct parts of the User and Group ID. The next step is to alter them in a way that returns them as a zero. We see that the User ID we sent FF and it returned 'e'.The FF we sent was a hex value and it the 'e' is a literal so the 'e' needs to be converted to HEX. Use the burp decoder to decode 'e' into HEX(even though its hinted right next it :P) 'e' decodes to HEX value 65. Now we simply reverse to XOR by XORing FF with 65. Im using an online calculator to do this:
The XORed value returns HEX value 9a.

This gives us our cipher used. To get the literal value 0 needed in the User ID we get the HEX value of zero which is 30 and XOR it with 9a. The return HEX value is aa. Replace the original token with aa. it now looks like this:
6bc24fc1aa650bFFb4114e93a98f1eba
When sending this to the server we get:

To get the Group ID to zero we apply the same technique. Because FF is returning the weird '?' symbol I altered it until I had something better to work with. In this case I swapped FF with 22 so the group ID returned 6. Convert 6 to HEX(36) and XOR it with 22. This gives us HEX value 14. Now XOR the HEX value of 0(30) with 14. This gives us the final value of 24 Our final result looks like:
6bc24fc1aa650b24b4114e93a98f1eba. Sending this to the server we receive our desired User and Group ID. I believe this is where Mutilidae should inform us we are logged in as root. 
This technique requires a bit(see what i did there ;) ) to get used to. Essentially we are working backward and decrypting the cipher. When we have decrypted the cipher we can work forward to produce the desired outcome. We are NOT decrypting the actual encryption. We are only modifying the cipher so it is decrypted to the values we want. Its a case of XORing backwards then XORing forward.
When I first learnt this, I struggled to understand how we can use this is the real world. The book I am currently reading gave me a perfect example of when this may come in handy. Excerpt:

One application observed by the authors contained a file upload/download
function. Having uploaded a file, users were given a download link containing
a filename parameter. To prevent various attacks that manipulate file paths, the
application encrypted the filename within this parameter. However, if a user
requested a file that had been deleted, the application displayed an error mes-
sage showing the decrypted name of the requested file. This behavior could be
leveraged to find the plaintext value of any encrypted string used within the
application, including the values of session tokens. The session tokens were
found to contain various meaningful values in a structured format that was
vulnerable to the type of attack described in this section. Because these values
included textual usernames and application roles, rather than numeric identi-
fiers, it would have been extremely difficult to perform a successful exploit using
only blind bit flipping. However, using the filename decryptor function, it was
possible to systematically manipulate bits of a token while viewing the results.
This allowed the construction of a token that, when decrypted, specified a valid
user and administrative role, enabling full control of the application.

In this example the author found a section of a website that decrypted its encryption. This allowed them to decrypt their token. It might have looked something like this:
john:342_normal_user.
Using the bug in the webpage they would have altered it using the bit flipping technique so that to looked like:
admin:000_super_user




3 comments:

  1. Website flipping is the art of buying, improving and selling websites. The term comes from the property industry where investors will buy a property, renovate it to add value, and then sell it at a higher price. More about this you can find at Flipping On Steroids

    ReplyDelete
  2. What a ride! It took me awhile to work this out, but I am glad I did. Thank you!

    ReplyDelete
  3. nice blog buddy!! keep it up

    ReplyDelete