> For the complete documentation index, see [llms.txt](https://docs.cooku222.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cooku222.kr/security/misc/dreamhack/dreamhack-password-in-the-gift-box.md).

# \[Dreamhack] Password in the gift box

{% embed url="<https://www.gamehouse.com/blog/leet-speak-cheat-sheet/#anchor2>" %}

그럼 코드를 보자.

chall.py

```
import re

LEET_START_STRING = "" # "the" in leet-speak alphabets
LEET_END_STRING = "" # "iskey" in leet-speak alphabets

def find_password(puzzle):
    puzzle_numeric = int(puzzle, 16)

    dream_key = "DH{}"

    extended_dream_key = dream_key * 32

    extended_dream_key_numeric = int.from_bytes(extended_dream_key.encode(), 'big')

    xor_for_dream = puzzle_numeric ^ extended_dream_key_numeric

    dream = ''.join(chr(byte) for byte in xor_for_dream.to_bytes((xor_for_dream.bit_length() + 7) // 8, 'big'))

    pw_key =  dream.split(LEET_START_STRING, 1)[-1].split(LEET_END_STRING, 1)[0]

    extended_pw_key = pw_key * 32

    extended_pw_key_numeric = int.from_bytes(extended_pw_key.encode(), 'big')

    xor_for_password = puzzle_numeric ^ extended_pw_key_numeric

    password_raw = ''.join(chr(byte) for byte in xor_for_password.to_bytes((xor_for_password.bit_length() + 7) // 8, 'big'))

    password = ''.join(char for char in password_raw if char.isalnum())
    
    return password

puzzle = "4448175452265f0367565e360a6c583670214532507c252f63155f2c671c2f59046d10525a344e0623734f517a2f55641877355f386a06063875564369085f016034535b2467614e0f73131604163b5845314f17620346375a7b11162d6146261f633029617c583d7e7c586b24690c54041f4f016126505e2629566e6a3c4f57"

password = find_password(puzzle)

print(f"flag is DH{{{password}}}")
```

&#x20;\
&#x20;\
exploit.py

```
import itertools

t = [r"7", r"+", r"-|-", r"']['", r"†", r'"|"', r"~|~"]
h = [r"#", r"/-/", r"[-]", r"]-[", r")-(", r"(-)", r":-:", r"|~|", r"|-|", r"]~[", r"}{", r"!-!", r"1-1", r"\-/", r"I+I", r"/-\\"]

e = [r"3", r"&", r"£", r"€", r"ë", r"[-", r"|=-"]

i = [r"1", r"[]", r"|", r"!", r"eye", r"3y3", r"]["]
s = [r"5", r"$", r"z", r"§", r"ehs", r"es", r"2"]
k = [r">|", r"|<", r"/<", r"1<", r"|c", r"|(", r"|{"]
y = [r"j", r"`/", r"Ч", r"7", r"\\|/", r"¥", r"\\//"]

msg = r"""l)n$~#%KN$#K4i>O4^R']$Q#TT$@%k/|5{g;4,>g.\?N"|"}{|=->-@$|$|(&`/3K;hk@^@%y4j&K=J3jki)=[[+KT%4#@:4#`!w)@W4|%n+#ba-.t4*"""

# Check all leet variants for "the"
for c in itertools.product(t, h, e):
    combo = "".join(c)
    if combo in msg:
        print(f"[FOUND] the: {combo}")

# Check all leet variants for "iskey"
for c in itertools.product(i, s, k, e, y):
    combo = "".join(c)
    if combo in msg:
        print(f"[FOUND] iskey: {combo}")
```

-> 이 코드로 the, iskey의 leet 변수를 알아낸 후 기존 코드에 다시 집어 넣는다.\
-> 주어진 문자열 msg 안에서 leet-speak로 표현된 "the"와 "iskey" 문자열의 조합을 brute-force로 찾는 로직\
\- the -> leet 조합\
\- iskey -> 다양한 leet 조합 -> 둘 중 실제 메시지(msg) 안에 포함된 leet 조합이 있는지 검사한다.

<figure><img src="https://blog.kakaocdn.net/dna/bc1w8G/btsOEPCRlyK/AAAAAAAAAAAAAAAAAAAAAFdUFxnkTpSEt8xylqQK8Yqj6U4bccRY2QlP4b7dySVD/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&#x26;expires=1782831599&#x26;allow_ip=&#x26;allow_referer=&#x26;signature=1fElce7aHT9JeNaupQsTHLsRTPk%3D" alt="" height="70" width="218"><figcaption><p>조합 결과</p></figcaption></figure>

```
import re

LEET_START_STRING = '"|"}{|=-' # "the" in leet-speak alphabets
LEET_END_STRING = "|$|(&`/" # "iskey" in leet-speak alphabets

def find_password(puzzle):
    puzzle_numeric = int(puzzle, 16)

    dream_key = "DH{}"

    extended_dream_key = dream_key * 32

    extended_dream_key_numeric = int.from_bytes(extended_dream_key.encode(), 'big')

    xor_for_dream = puzzle_numeric ^ extended_dream_key_numeric

    dream = ''.join(chr(byte) for byte in xor_for_dream.to_bytes((xor_for_dream.bit_length() + 7) // 8, 'big'))

    pw_key =  dream.split(LEET_START_STRING, 1)[-1].split(LEET_END_STRING, 1)[0]

    extended_pw_key = pw_key * 32

    extended_pw_key_numeric = int.from_bytes(extended_pw_key.encode(), 'big')

    xor_for_password = puzzle_numeric ^ extended_pw_key_numeric

    password_raw = ''.join(chr(byte) for byte in xor_for_password.to_bytes((xor_for_password.bit_length() + 7) // 8, 'big'))

    password = ''.join(char for char in password_raw if char.isalnum())
    
    return password

puzzle = "4448175452265f0367565e360a6c583670214532507c252f63155f2c671c2f59046d10525a344e0623734f517a2f55641877355f386a06063875564369085f016034535b2467614e0f73131604163b5845314f17620346375a7b11162d6146261f633029617c583d7e7c586b24690c54041f4f016126505e2629566e6a3c4f57"

password = find_password(puzzle)

print(f"flag is DH{{{password}}}")
```

-> 플래그를 뱉는다. \
-> DH{zeWplY4ANnQe8Y1oPvduDZuGFXgWJj1S23dVQ2LNpQQODLp2zJTs}&#x20;

<br>


---

# 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:

```
GET https://docs.cooku222.kr/security/misc/dreamhack/dreamhack-password-in-the-gift-box.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
