tl;dr
- CTR bit-flipping attack along with CRC recomputation
Challenge Points: 250
No. of solves: 29
Solved by: LS
Challenge Description
I implemented a super secure alternative to JWE and disabled the ‘admin’ account, but our server traffic logs still shows someone reading out their flag. How is that possible?!
IMPLEMENTATION
1 | import hashlib |
ANALYSIS OF THE CHALLENGE
- Provided by a Flask server with predefined key parameters, as follows:
- IV (initial vector): 16 bytes
- Nonce: 42 bytes
- MAC (Message Access Address): 8 bytes
- Key: 32 bytes
- The server uses the “USER_DB” dictionary which securely stores the “azure” and “cthon” user names with their hashed passwords. The password hashing algorithm used here is SHA256.
- There are two endpoints for communication:
- /auth - This endpoint returns an authentication token when the user succeeds.
- /read - Used to decrypt the token to validate the request and obtain the username.
AUTHENTICATION
The certification process has the following conclusions:
/auth?user=username&password=password.After receiving the username and password, the server performs the following tasks:
- Validates the assigned username and password with respect to information in the user database.
- If the authentication is successful, the server proceeds to generate an authentication token using a custom format.
The configuration described above ensures that the authentication system on the Flask server is secure and properly configured. It includes robust mechanisms for verifying user credentials and creating trusted authentication tokens.
TOKEN FORMAT
- The token follows a specific format:
IV || User || NONCE || MAC
- The value of tokens includes:
- IV: The initial vector is used for AES-CTR encryption.
- USER: User data, encrypted using AES-CTR mode.
- NONCE: A random nonce.
- MAC: Message Authentication Code generated using 64-bit CRC
MESSAGE AUTHENTICATION CODE (MAC)
- A MAC is a short piece of data ensuring a message’s integrity, confirming its rightful sender, and preventing unauthorized alterations, bolstering communication security.
ENCRYPTION AND MAC GENERATION
- The
encrypt_token
function manages the encryption of user data using AES-CTR mode, ensuring the confidentiality of the information. - Additionally, the
gen_mac
function computes a 64-bit CRC, serving as the Message Authentication Code (MAC), to authenticate the data.
TOKEN DECRYPTION
- The /read endpoint allows reading files from a user’s directory and requires a valid authentication token.
- The decrypt_token function decrypts the token, verifies the MAC, and returns the user data.
FLAG ACCESS
- When you use the modified token to access
/read/flag.txt
, you unlock the flag.
WORKING OF CRC
- Cyclic Redundancy Check (CRC) serves as a method for error detection and correction, ensuring data integrity during transmission.
- CRC uses a systematic approach to double-check if the data is accurate.
SENDER SIDE
- The sender calculates a CRC value by treating data as a binary number and dividing it by a generator polynomial. This remainder becomes the CRC, appended to the original data before sending it to the receiver.
RECEIVER SIDE
- Upon receiving data, the receiver calculates its CRC value using the sender’s method and compares it with the received CRC value to determine data integrity.
EXAMPLE
- Consider the following scenario with a data bit to be sent as “100100” and a polynomial equation “x^3 + x^2 + 1”:
- Data bit: 100100
- Divisor (k): 1101 (derived from the given polynomial)
- Appending Zeros: (k-1) -> (4-1) -> 3
- Dividend: 100100000
- This process shows how CRC ensures data integrity by detecting errors in transmitted data.
PROPERTY OF CRC
- The MAC is generated using CRC on the concatenation of IV, user_bytes, and nonce and then it is being encrypted in AES-CTR mode.
- Contrary to a typical bit-flipping attack scenario, where altering bits would invalidate the CRC, CRC exhibits a unique property.
- After flipping bits on the CTR mode encrypted token, the CRC becomes invalid. However, CRC’s specific computational nature allows for the derivation of a new CRC from the old one.
- This property, illustrated by the formula:
1
CRC(A ⊕ B ⊕ (00...)) = CRC(A) ⊕ CRC(B) ⊕ CRC(00...)
AES-CTR MODE
- AES-CTR uses an Initialization Vector (IV) and a counter to create a pseudorandom key stream, which is XORed with plaintext blocks for encryption, allowing parallel processing for secure and efficient data encryption.
CHALLENGE OBJECTIVE:
- The challenge at hand revolves around exploiting the CRC64-based MAC encrypted in AES-CTR mode through a bit-flipping attack.
- The goal is to manipulate the user data in the token while ensuring a valid CRC64-based MAC.
- Creating a payload that, when XORed with the original token, results in a modified token with a valid MAC is the primary objective.
SOLUTION
- Discovered a user’s password from a hint given in the source code :
Other accounts. File a ticket similar to QDB-244321 to add or modify passwords. - Upon investigating ticket QDB-244321, the password for the “azure” account was found here.
- To get the token, append the username and the password to the url.
- To change the user, utilize XOR operations, effectively changing the user to “admin” while preserving the CRC integrity.
- Xor the token with the xor(“admin”, “azure”) which will give us “admin” back.
1
payload = xor(b'\x00'*16+xor(b'admin', b'azure')+b'\x00'*50, token)
- Next, to manipulate the CRC value without invalidating it, XOR two MAC values:
1
mac = xor(gen_mac(b'\x00'*16+xor(b'admin', b'azure')+b'\x00'*42), gen_mac(b'\x00'*63))
- This XOR operation leveraged the linear property of CRC, simplifying the expression to
crc("admin") ⊕ crc("azure")
.1
crc("admin") ⊕ crc("azure") ⊕ crc(b'\x00'* 5) = crc("admin") ⊕ crc("azure")
- As a result, the calculated MAC for the “admin” user was obtained.
1
crc("azure") ⊕ crc("admin") ⊕ crc("azure") = crc("admin")
- Finally, submitting this payload with the modified MAC value provided access to the flag.
SCRIPT
1 | import fastcrc |