Write-Ups

Hackim18 – Web1

Description

The objective of this challenge is to find a way to get logged in as the user “administrator”..

This is the demo application for our new session management system based on military cryptography (namely CBC-MAC). You can log in as any user (except ‘administrator’) with the password ‘Password1’. We blocked access to ‘administrator’ account for security reasons.

Resolution

Let’s log in with the username “test” and see how the authentication system keeps track of the currently logged in user.

There are 2 cookies encoded in base64. One just needs to decode them to see their real value and get a better understanding of what’s going on.

>>> "dGVzdC0trPGLxEtxTi8=".decode("base64")
'test--\xac\xf1\x8b\xc4KqN/'
>>> "bOHCrEKzfso=".decode("base64")
'l\xe1\xc2\xacB\xb3~\xca'

Excellent ! So the “auth” cookie is just the username followed by “–” and 8 bytes which corresponds to the output of the CBC-MAC algorithm.
The “iv” cookie is, like its name says, the initialization vector used by the CBC-MAC algorithm to produce the above result.

A little bit of crypto

CBC-MAC (Cipher Block Chaining Message Authentication Code) uses blocks of fixed length to encrypt a message and output only the last block of the resulting ciphertext.
This is the one present at the end of the “auth” cookie and its size is 8 bytes.

Unlike other block ciphers, CBC-MAC uses a fixed IV, usually zero. The IV and the plaintext are then xored together. Since the IV and the plaintext can be modified, one can forge a first block that will output the same authentication code !
More information about why it’s insecure to have a variable IV is described in this blog post.

Ok, it’s possible to change the first 8 bytes of the plaintext without repercussions on the authentication code but “administrator” is 13 bytes long. Logging in with a username which is 13 bytes long and ends with “rator” will solve the problem. The less change needed, the quicker, that’s why using “Administrator” is a good choice, only the first letter will have to be changed.

> iv = "Gzb5ZaA8QUo=".decode("base64")
>>> iv
'\x1b6\xf9e\xa0<AJ'
>>> auth = "QWRtaW5pc3RyYXRvci0tzyp2t0HMVVI=".decode("base64")
>>> auth
'Administrator--\xcf*v\xb7A\xccUR'

Before changing the first letter, the current value of the first byte of the first block must be calculated.

>>> ord('A')^0x1b
 90

The first letter of the username needs to be replaced with ‘a’, therefore the first byte of the IV needs to be changed to produce the same result as before:

>>> ord('a')^90
59
>>> chr(59)
';'

Now, the new values just have to be encoded in base64 and changed in the browser.

>> 'administrator--\xcf*v\xb7A\xccUR'.encode("base64")
'YWRtaW5pc3RyYXRvci0tzyp2t0HMVVI=\n'
>>> ';6\xf9e\xa0<AJ'.encode('base64')
'Ozb5ZaA8QUo=\n'

Validation can be done with the flag: hackim18{‘cbc_it_is_easy_as_one_two_three’}

Leave a Reply

Your email address will not be published.