[TetCON CTF 2015] Crypto200 with The POODLE Attack

Tetcon is one of the biggest security conferences in Viet Nam. There are various talks which speak both in Vietnamese and English. In this year, the first time, organizers decided to host a hacking challenge – Capture The Flag (CTF) !

While CTF was running, I solved 3 tasks, such as: getit, next and “Who let the dog out?”.

First two tasks is not quite hard. You should try it yourself. In this post, I would like to talk about  “Who let the dog out?”. It’s about cryptography attack. In particular, it is the POODLE attack. And the author of this task is Thai Duong (thaidn), one of experts who find out this attack.

Task description:

Source: http://pastebin.com/Mr6PJBwn (my mirror: https://l4w.io/files/CTFs/tetcon-2015/crypto200.py)
Server: http://crypto-class.appspot.com/tetcon

Look at the source-code:

So we could choose prefix and suffix of plaintext.

We passes ciphertext as GET paramater c

If any errors or exceptions occur, the server will return 403.

The input data which passes to encrypt function will be encrypted with AES-CBC MODE. Moreover, it’s using HMAC.

We knew what block_size = 16, FLAG size = 32, hmac size = 16.

curl "http://crypto-class.appspot.com/tetcon?p1=AAAAAAAAAAAAAAAA&p2=AAAAAAAAAAAAAAAA"



Since HMAC checks integrity of the message (iv + msg), we couldn’t modify or inject anything. And if HMAC isn’t same as result derives from its calculation, code will throw exception and the server will return 403 as I mentioned earlier.

The vulnerability might be in somewhere else. Dig more.

You could see that the the padding function random_pad is not using PKCS7 method or something like that.

No matter what the content of the padding bytes is, as long as the last byte must specify padding size.

What if we do following steps:

  1. Append a block FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF{XX} before padding block with {XX} is a byte we need to bruteforce (why? wait a bit, i will tell you).
  2. Replace padding block into BLOCK[0] (I mean AAA… block, because IV isn’t encrypted).


Ok, Let’s think about it.

What will happen ?

88754146ca526818f5d61a14b4b3fc5d will be decrypt as padding block. This is how AES CBC MODE decrypt our data.

More details:


(yeah, my paint skills is noob, i know :D)

Then, we bruteforce XX with a byte in range from 0x1 to 0xFF. Thus, with an average of 256 tries to bruteforce with XX, there is once time, you will be able to get 200 HTTP status code. Why ? (In this case, XX was 0xC5)

As we discussed earlier, If you try to modify-inject data, it will fail and throw exception. But, assume that last byte which specifies padding-size is 31. random_unpad function will return data[0:-31]. It means that the block which we appended to encrypted data will be skipped!.

Ok. Get back to our situation, XX was 0xC5 and the server responses 200 HTTP status code. We can tell that padding-size was 31. The block ffffffffffffffffffffffffffffffc5 was skipped.

Well, then what could we do with that ?.

Remember that 88754146ca526818f5d61a14b4b3fc5d was decrypted as padding block so 0x5d will be decrypted then XOR with 0xC5 = 31 ?! right ?

=> The last byte of decrypted data is 0xDA (0xC5 ^ 31)

Yeah, If you understand what i just said, then you can know what is P[0][15] ? (P=Plaintext).
P[0] = Decrypt(88754146ca526818f5d61a14b4b3fc5d)
Since this block is C[0] so we use IV to XOR.
IV = 0acbad9b05fbc03551afdf147446a49b
=> P[0][15] = Decrypt(C[0])[15] ^ IV[15] = 0xDA ^ 0x9B = 0x41

chr(0x41) => A

Replace 88754146ca526818f5d61a14b4b3fc5d into C[1] (16 bytes FLAG encrypted), and do it again, we would get 16th byte of FLAG.

Since we could choose prefix-suffix of plaintext. we probably leak the whole plaintext of encrypted data. Especially, we could leak FLAG.




1 t t
1 e te
1 t tet
1 c tetc
1 o tetco
1 n tetcon
1 { tetcon{
1 { tetcon{{
1 p tetcon{{p
1 o tetcon{{po
1 o tetcon{{poo
1 d tetcon{{pood
1 l tetcon{{poodl
1 e tetcon{{poodle
1   tetcon{{poodle
1 v tetcon{{poodle v
2 s tetcon{{poodle vs
2   tetcon{{poodle vs
2 s tetcon{{poodle vs s
2 s tetcon{{poodle vs ss
2 l tetcon{{poodle vs ssl
2 v tetcon{{poodle vs sslv
2 3 tetcon{{poodle vs sslv3
2 : tetcon{{poodle vs sslv3:
2   tetcon{{poodle vs sslv3:
2 1 tetcon{{poodle vs sslv3: 1
2   tetcon{{poodle vs sslv3: 1
2 – tetcon{{poodle vs sslv3: 1 –
2   tetcon{{poodle vs sslv3: 1 –
2 0 tetcon{{poodle vs sslv3: 1 – 0
2 } tetcon{{poodle vs sslv3: 1 – 0}
2 } tetcon{{poodle vs sslv3: 1 – 0}}
Flag: tetcon{{poodle vs sslv3: 1 – 0}}


Yeah, and this was how the POODLE attack SSLv3 ;). You can read it further more at:

Thank you for your reading. Sorry for my english. I’m not good at it :(.

Shout-out to NN, my friends, my bros who always support me :).


I’ve finished as winner 1st, and got ~$940 prize :D.


  1. daehee
    January 9, 2015

    amazing! this post is really helpful to understand the poodle attack

  2. guest
    January 13, 2015


  3. thanks
    January 13, 2015

    Thank you for this.

    January 20, 2015

    Good writeup!

Leave a Reply

Your email address will not be published. Required fields are marked *