Sitemap
0x7ipher

0x7ipher

Muhammad Saad || Offensive Security || Red Teamer || Cybersecurity Enthusiast

TryHackme Flip Room

5 min readNov 17, 2025

By: Muhammad Saad

Challenge Description : Log in as the admin and capture the flag! If you can…

  • In This Room we will be focusing on AES & CBC.
  • AES (Advanced Encryption Standard) is a symmetric key encryption algorithm, meaning the same key is used for both encrypting and decrypting data. Its purpose is to securely encrypt information so that only someone with the correct key can read it. It supports key sizes of 128-bit, 192-bit, or 256-bit. In simple terms, it takes plain text and a secret key, performs multiple rounds of substitution, permutation, mixing, and key addition, and produces cipher text, which is the encrypted data.
  • CBC (Cipher Block Chaining) is a mode of operation for block ciphers like AES. It works by taking each block of plain text and combining it with the previous block of cipher text before encrypting. This means each block depends on the one before it, making the encryption more secure. An initialization vector (IV) is used for the first block to start the process.

From the Room we got a python file : app-1684527681671.py and we are to connect to port 1337 via TCP by netcat.

Press enter or click to view image in full size

Trying to Login with the given Credentials “admin&password=sUp3rPaSs1” the server would respond

Let’s have a look on the given file app-1684527681671.py, Inside the code, I find the following function:

The decrypt_data() function returns 1 only when the decrypted data contains the exact credentials: admin&password=sUp3rPaSs1

However, we have already tried logging in using
admin / sUp3rPaSs1, and it still fails.
This means the challenge does not expect us to use the credentials directly instead, we must craft a ciphertext that decrypts to this admin string.

Next, the setup() function shows how the server interacts with the user:

This part reveals the intended attack path:

  • The server gives us a leaked ciphertext generated using our own username and password.
  • Then it asks us to submit a ciphertext.
  • That ciphertext is passed to decrypt_data().
  • If the decrypted value contains admin&password=sUp3rPaSs1, we get the flag.

Therefore, the goal is not cracking AES, but flipping bits in the ciphertext (CBC bit‑flipping attack) so that after decryption, the output matches the admin string.

To understand how the vulnerability works, I tried logging in with the following credentials:

username = bdmin
password = sUp3rPaSs1

This creates the message:

access_username=bdmin&password=sUp3rPaSs1

When the server encrypts this message, it returns the following leaked ciphertext:

c0fb51e07c1fc9f46ad9981473c8f6fd137a9b54c4b5b51a98b4a7cb617a32c7a52f02862aebc5d88547eb8160910e89

Immediately afterward, the server prompts us to enter a ciphertext.
If the ciphertext we submit decrypts to the correct admin string, the server will reveal the flag.

  • To proceed with the attack, I first checked the length of the plaintext message: access_username=admin&password=sUp3rPaSs1

The message is 41 bytes long.

  • To align it with AES‑CBC’s block requirements, we need the plaintext length to be a multiple of 16 bytes (because AES has a fixed 128‑bit / 16‑byte block size).
    If we append 7 additional characters, the total becomes: 41 + 7 = 48 bytes
  • This fits perfectly into three 16‑byte blocks: 16 + 16 + 16 = 48 bytes

Since AES‑CBC encrypts the data block‑by‑block, each 16‑byte plaintext block corresponds directly to each 32‑hex‑character (16‑byte) ciphertext block.
This relationship is what allows us to perform a bit‑flipping attack: by modifying specific bytes in the ciphertext, we can control the decrypted output in the next block.

The Process of CBC Decryption :

CBC decrypts each block in two steps:

1. AES decrypt the ciphertext block

First, the block Ci​ is decrypted with the AES key:

Get 0x7ipher’s stories in your inbox

Join Medium for free to get updates from this writer.

intermediate = AES_decrypt(Ci)

2. XOR with previous ciphertext block

Then the result is XORed with the previous ciphertext block:

Pi = intermediate XOR C(i‑1)

For the first block, we use the IV instead of a previous block:

P1 = AES_decrypt(C1) XOR IV

In our case, the plaintext is split into three 16‑byte blocks:

(Here # represents padding.)

The leaked ciphertext is 96 hex characters, which equals 3 ciphertext blocks (each block = 32 hex characters = 16 bytes):

  • The server will only reveal the flag if the decrypted plaintext contains: admin&password=sUp3rPaSs1
  • But our current plaintext is: bdmin&password=sUp3rPaSs1
  • Only one letter differs: b (in “bdmin”) must become a (in “admin”).

In CBC decryption: P2 = AES_decrypt(C2) XOR C1

  • This means any change we make in ciphertext block C1 will directly change the corresponding bytes in plaintext block P2 when the server decrypts it.
  • So to change: bdmin → admin
  • We only need to modify the first byte of Block 2, which is controlled by the first byte of C1.

CBC Bit‑Flipping to Change “b” → “a”

Our blocks are:

The first byte of B2 is controlled by the first byte of C1.

We want:

  • Current plaintext byte: b
    Hex: 0x62
  • Desired plaintext byte: a
    Hex: 0x61

We need to adjust the first byte of C1 to change b → a.

We already checked earlier that:

  • In Block 1:
  • a is 1 byte → C1 = c0 (2 hex characters)
  • In Block 2:
  • b is 1 byte → C2 = 13 (2 hex characters)
  • When we XOR c0 ^ 13, it equals b.
  • The hex value of b is 62, so we can write: c0 ^ 13 = 62 and 0xc0 ^ 0x62 = 13
  • Performing hex on 0xc0 ^ 0x62 gives 0xa2.
    Then further: 0xc0 ^ 0xa2 = 0x62
  • We know that b in hex is 62, but we want a instead.
    The hex of a is 61.
  • To find the correct hex for C1 to produce “ a ” we would find the hex of hex(0xa2 ^ 0x62) which is equals to 0xc3.
  • So the first byte of C1 should definitely be c3: c3fb51e07c1fc9f46ad9981473c8f6fd

Let’s try using this final ciphertext to get the flag:

c3fb51e07c1fc9f46ad9981473c8f6fd137a9b54c4b5b51a98b4a7cb617a32c7a52f02862aebc5d88547eb8160910e89

Press enter or click to view image in full size

The Flag : THM{FliP_DaT_B1t_oR_G3t_Fl1pP3d}

--

--

0x7ipher
0x7ipher

Written by 0x7ipher

Muhammad Saad || Offensive Security || Red Teamer || Cybersecurity Enthusiast