Hacktheboo 2024 - Hybrid unifier [crypto]
Writeup for Hybrid unifier challenge at Hacktheboo 2024
Difficulty : easy
Team : crampting
Source files will be on HTB challenges platform
Author : r4sti
TL;DR
We got a server that we can contact through API endpoints.
It send us its public key.
We send it our mischievous pubic key
A session key is generated from it.
As our key is malicious, the session key is either 1 or -1.
We ask the server for a challenge which is a string encrypted with AES with the session key and we got to decrypt it and send the hash back to the server.
Then we contact the server by encrypting our request in AES and get the flag.
Introduction
The challenge is kind of a key exchange to securely generate a symmetric cryptographic key.
Then when the key exchange is done, we are supposed to interact with the server by encrypting communication with AES.
Solving
Key exchange
I didn’t save the whole source code but i will do without for the moment.
To initiate a secure session
- /api/request-session-parameters
- /api/init-session
After the secure session is initalized
- /api/request-challenge
- /api/dashboard
Creating a session initialize a Session()
object with 384 bits.
sending a post request to /request-session-parameters
give us the generator $g$ and the prime number $p$ :
POST /api/request-session-parameters HTTP/1.1
gives {"g":"0x2","p":"0xf4ac926dddb699f4cb03c005a9f6f89c7505ab5282a3557d2aaf41e822372edd69c2a9d4906a943340bfd87fc08f9743"}
Then we can init a session with /api/init-session
in JSON by sending our public key, here is the challenge source code part:
|
|
The key is generated with : $ B^{a} \mod \ p $
Where $B$ is the client public key, $a$ is the server private key.
It is how diffie-hellman key exchange is set up.
Here is a descriptive image :
Diffie-hellman is based on modular arithmetics and thus got some interesting properties. i.e, number greater than the modulo get substracted by the modulo until they got below the modulo.
It means that with modulo p: $ p+1 = p+1-p = p $
For example :
$ a \equiv a - a \equiv 0 \mod a $
$ a + 1 \equiv 1 \mod a $
$ a - 1 \equiv -1 \mod a $
$ (a + 1) \equiv 1 \mod a $ so $ (a + 1)^{n} \equiv (1)^{n} \equiv 1 \mod p $
(There is a nice course about it on cryptohack)
So, by sending to server a public key = $ p - 1 $ or $ p + 1 $, the session key will either be -1 or 1:
With client_public_key = -1:
$$ B^{a} \equiv (p-1)^{a} \equiv (-1)^{a} \equiv -1 \ OR \ 1 \mod p $$(it depends of the parity of $a$)
With client_public_key = 1: $$ B^{a} \equiv (p+1)^{a} \equiv 1^{a} \equiv 1 \mod p $$
For the challeng I used client_public_key = p-1 because i didn’t think to just use $p+1$.
The vulneribility is that the server doesn’t check the public key i send to him.
Exploiting
Now we got the key (-1 or 1), we can just use the same functions as the server to encrypt our communication (the communication is AES CBC encrypted, and then encoded with base64).
- We need to contact
/api/request-challenge
- Decode and decrypt it
- contact
/api/dashboard with
with a JSON with the data encrypted in AES - Get the flag
|
|
flag : HTB{good_job_in_alpha_testing_our_protocol___take_this_flag_as_a_gift_04c9f4b66afa55c164aa347e25d18148
Conclusion
It’s a nice way to understand diffie-hellman key exchange and how the choice of the key can be messed up.
Well there is another solve which was to do a classic Diffie-Hellman key exchange but my dumb ahh didn’t think about it first.