> For the complete documentation index, see [llms.txt](https://ir0nstone.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ir0nstone.gitbook.io/notes/writeups/ctfs/htb-cybersanta-2021/crypto/meet-me-halfway.md).

# Meet Me Halfway

## Contents

We are given `challenge.py`, which does the following:

* Creates two keys
  * Key1 is `cyb3rXm45!@#` + 4 random bytes from `0123456789abcdef`
  * Key2 is 4 random bytes from `0123456789abcdef` + `cyb3rXm45!@#`
* Encrypts the flag with Key1 using AES-ECB
* Encrypts the *encrypted* flag with Key2 using AES-ECB

We can use a **meet-in-the-middle** attack to retreive both keys. The logic here is simple. Firstly, there are `16` possible characters for each of the 4 random bytes, which is easily bruteforceable ($$16^4$$).

We can also encrypt a given input and get the result - I choose to send `12345678` as the hex-encoded plaintext and receive . For these keys, the encrypted flag is given as:

```
43badc9cfb6198e97e5c0085eba941043982169877c2ec51995b5527d32244ebf3af4453e73408786a9eb39cd7fbb731afd940617e7ad1484ac017a7c0c3798cdb4a96ed96e816cf2a09fd4b39715064d0bba8bbf37e5d713f0af6a850985644
```

## The Attack

Now we have a known plaintext and ciphertext, we can use both one after the other and bruteforce possible keys. Note that the encryption looks like this:

![The Encryption Method](https://github.com/ir0nstone/pwn-notes/blob/master/.gitbook/assets/double_aes%20\(1\).png)

We do not know what the intermediate value `x` is, but we can use brute force to calculate it by

* Looping through all possibilities for `key1` and saving the encrypted version of `12345678`
* Looping through all possibilities for `key2` and saving the **decryption** of `449e2eb...`
* Finding the intersection between the encryption with `key1` and the decryption with `key2`

Once we find this intersection, we can use that to work back and calculate `key1` and `key2`, which we can then utilise to decrypt the flag.

## Solve Script

```python
from itertools import permutations

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad


key_start = b'cyb3rXm45!@#'
alphabet = b'0123456789abcdef'

enc_flag = bytes.fromhex('43badc9cfb6198e97e5c0085eba941043982169877c2ec51995b5527d32244ebf3af4453e73408786a9eb39cd7fbb731afd940617e7ad1484ac017a7c0c3798cdb4a96ed96e816cf2a09fd4b39715064d0bba8bbf37e5d713f0af6a850985644')

known_text = pad(bytes.fromhex("12345678"), 16)
known_ciphertext = bytes.fromhex('449e2eb3a7f793184ef41a8042739307')

# brute all encryptions
encryption_table = {}           # key : value -> encryption result : key

for key in permutations(alphabet, 4):
    key = key_start + bytes(key)
    cipher = AES.new(key, AES.MODE_ECB)
    encrypted_custom = cipher.encrypt(known_text)
    encryption_table[encrypted_custom] = key


# brute all decryptions
decryption_table = {}           # key : value -> decryption result : key

for key in permutations(alphabet, 4):
    key = bytes(key) + key_start
    cipher = AES.new(key, AES.MODE_ECB)
    decrypted_custom = cipher.decrypt(known_ciphertext)
    decryption_table[decrypted_custom] = key


# find the intersection between the keys of decryption_table and encryption_table
# if there is an intersection, we can cross-reference the AES key we used
encryption_table_set = set(encryption_table.keys())
decryption_table_set = set(decryption_table.keys())

intersection = encryption_table_set.intersection(decryption_table_set).pop()
encryption_key = encryption_table[intersection]     # set the encryption key now we know which it is
decryption_key = decryption_table[intersection]     # set the decryption key now we know which it is

# now decrypt flag_enc twice
cipher1 = AES.new(encryption_key, AES.MODE_ECB)
cipher2 = AES.new(decryption_key, AES.MODE_ECB)

flag = cipher2.decrypt(enc_flag)
flag = cipher1.decrypt(flag).decode().strip()

print(flag)
```

And we get the flag as `HTB{m337_m3_1n_7h3_m1ddl3_0f_3ncryp710n}`!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ir0nstone.gitbook.io/notes/writeups/ctfs/htb-cybersanta-2021/crypto/meet-me-halfway.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
