Tags: aes-cbc aes cbc cbc-bit-flipping 

Rating:

md5Converter
============

### Info
- Original Link: [http://md5convert.whitehat.vn:12345](http://md5convert.whitehat.vn:12345)
- Flag: `AceBear{fl1pp1ng_and_fake_HMAC_SECRET__for_a_warm_Up_Challenge___^_^}`

### What do we have?

![The landing page](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/01%20-%20the%20link.png)
- We arrive at a landing page that allows us to submit a secret

![We submit some data](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/02%20-%20submit%20some%20data.png)
- We submit the word "test" and get presented with a page that shows us a link to our secret

![We click the link](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/03%20-%20click%20the%20link.png)
- We click the link and and it shows what appears to be an MD5 of our secret

### Let's solve it

![Vew page source](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/04%20-%20view%20page%20source.png)
- We can view the source of the landing page and scroll right to teh bottom to find something interesting, a potential link

![View page source of secret link](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/05%20-%20source%20of%20secret%20link.png)
- We visit the secret URL and view the page source
- Bingo, we've found something hopefully useful!
- The full snapshot of the code can be seen [here](https://github.com/ash47/CTF-WriteUps/blob/master/AceBear%20Security%20Contest%202019/md5Converter/some_thing_interesting.html)
- It's clear we're dealing with a website written in Python, the full code of which is here

![Found the flag location](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/06%20-%20flag%20location.png)
- A quick review of the source code reveals a helpful comment that tells us WHERE the flag is hidden, it's hidden in a file called `flag` that we need to find

![Function to get the flag](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/07%20-%20function%20to%20get%20flag.png)
- This is the function that allows us to retrieve files, based on the AES encrypted string
- There must be a flaw SOMEWHERE in this function that allows us to ultimately secure the flag

![Raw create secret](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/08%20-%20raw%20create%20secret.png)
- We can see the RAW request to create a secret here
- Creating a secret here results in the server sharing us a URL with a `file` and `sign` parameter

![Reading the code for clues](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/09%20-%20reading%20the%20code.png)
- At point `1` We can see that a random sessionID is created using the Python random library, it's unlikely we can attack this
- That random sessionID is then run through the MD5 algorithm generating an md5 in the form of `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
- The md5 is appended to the string `md5_`
- This results in a file called `md5_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` being created
- At point `2` we can see that the filename from above is concated with `|` and then a HMAC of the filename itself
- This means, we ultimately need to change this to read `flag|<HMAC of flag>` within the AES encrypted payload
- At this point, lets see how the AES encryption is done, maybe it's the standard Python library, maybe it's not

![AES Encryption Function](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/10%20-%20aes%20encryption%20function.png)
- On line `17` we can see that an IV is randomly generated
- We can see that the payload is encrypted using this IV and some key that we don't really know
- Line `19` shows that the IV and the encrypted payload are both returned
- BINGO! We can manipulate the IV to change the contents of the decrypted plaintext using MAGIC, let me explain

![Classic AES CBC Diagram](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/11%20-%20classic%20aes%20cbc%20diagram.png)
- This is a classic diagram of how AES CBC works, let me give you the simple mans explanation
- AES is a block cipher, meaning that it breaks all of your data into fixed blocks, and encrypts them block by block
- We will look at this from the perspective of decryption, as it's more relevant for our use case
- The first block is decrypted using the key, which results in some garbage text, then, that garbage text is XORed with the IV which results in the original plaintext
- Regardless of what key is used, the plaintext is directly related to the IV
- We know that the first 4 characters of the string are going to be md5_
- If we modify the first 4 characters of our IV, we can directly change what md5_ translates into, not only that, we can do it in a very predictable manor, so much so, that we can convert these 4 characters into `flag` trivially
- We know that the next character should also be a pipe symbol `|` and then the HMAC

![Logic Bug](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/12%20-%20bad%20logic.png)
- Here it is, a huge logic flaw in the entire process, can you spot it?
- We split the AES decrypted string on the pipe `|` character
- The first part is the filename, and the second part is the SECRET that is used to generate the HMAC :O
- What if we did `flag||`, that would mean the file would be `flag` and then the HMAC secret would be `<blank>`, we can compute the HMAC of `flag` and a blank secret, we have the HMAC generation function as part of this code, that is EASY
- Trouble is, we only know the first `4` characters of the plaintext, the next 32 characters are random
- The characters can be `0-9a-f` -- that's `16` possible characters
- We need to guess `2` characters, and there is `16` choices for each -- `16 x 16 = 256` -- We can solve this with 256 guesses :O That's reasonable!
- I was able to calcualte the HMAC for the `flag` and a blank IV, it came out to be `f7101d3ad5cb2622672fb15e079d8db3`, the python code was provided via that source code above, it's trivially to do

![Prepare Burp](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/13%20-%20prepare%20burp.png)
- I wrote a quick NodeJS program which generates all `256` possibilities, the source code of which can be seen [here](https://github.com/ash47/CTF-WriteUps/blob/master/AceBear%20Security%20Contest%202019/md5Converter/md5_convert.js)
- I loaded up BURP and set the target payload position to be the `file` parameter, and plugged in our known HMAC
- Press GO and hope for the best

![Flag Obtained](https://raw.githubusercontent.com/ash47/CTF-WriteUps/master/AceBear%20Security%20Contest%202019/md5Converter/14%20-%20flag%20obtained.png)
- It made it's way through our possible guesses, and guess number `92` look different
- BINGO, that's our flag!

### Something Extra
- I really enjoyed this puzzle and felt super fullfilled when I solved it

Original writeup (https://github.com/ash47/CTF-WriteUps/blob/master/AceBear%20Security%20Contest%202019/md5Converter/README.md).