CBC bit flipping

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

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.


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.

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.
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:


We can see this altered the first part of the Application ID. The next test we flip the second bit:
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:


Iv marked down those bits in the original IV and returned the rest to the original values:


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:
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:

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.

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:
Using the bug in the webpage they would have altered it using the bit flipping technique so that to looked like: