Dreamhack/Dreamhack Wargame (Challenge)

[151] IT 비전공자 [dreamhack]Password in the gift box문제 풀기

imaginefuture-1 2025. 2. 10. 09:21

https://www.gamehouse.com/blog/leet-speak-cheat-sheet/#anchor2

 

Leet Speak Cheat Sheet - GameHouse

Having a tough time understanding your gamer friends? Then this Leet Speak Cheat Sheet will help you cheat your way from n00b to l33t.

www.gamehouse.com

 

새로운 문자다..eeeeeeee = 333333333요런 느낌

 

 

 

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}}}")

 

the, iskey 모든 경우의 수 집어넣어야함

여기서 중복되는거 빼고 딕셔너리로 만들어줘 e = 3,&,£,€,ë,[-,|=-
h = #,/-/,[-],]-[,)-(,(-),:-:,|~|,|-|,]~[,}{,!-!,1-1
,\-/
,I+I
/-\

k =
>|
|<
/<
1<
|c
|(
|{
i =

1
[]
|
!
eye
3y3
][
s =
5
$
z
§
ehs
es
2
y = 
j
/
Ч
7
\|/
¥
\//

t =

7
+
-|-
']['
†
"|"
~|~

 

여기서 중복을 제거하고 딕셔너리 형태로 정리해줄게.

leet_dict = {
    "e": ["3", "&", "£", "€", "ë", "[-", "|=-"],
    "h": ["#", "/-/", "[-]", "]-[", ")-(", "(-)", ":-:", "|~|", "|-|", "]~[", "}{", "!-!", "1-1", "\-/", "I+I", "/-\\"],
    "k": [">|", "|<", "/<", "1<", "|c", "|(", "|{"],
    "i": ["1", "[]", "|", "!", "eye", "3y3", "]["],
    "s": ["5", "$", "z", "§", "ehs", "es", "2"],
    "y": ["j", "`/", "Ч", "7", "\|/", "¥", "\//"],
    "t": ["7", "+", "-|-", "']['", "†", '"|"', "~|~"]
}

이제 이 leet_dict을 활용해서 leet-speak 변환 조합을 만들고 적용하면 돼! 🚀

 

 

import re
import itertools

# leet-speak 변환 딕셔너리
leet_dict = {
    "e": ["3", "&", "£", "€", "ë", "[-", "|=-"],
    "h": ["#", "/-/", "[-]", "]-[", ")-(", "(-)", ":-:", "|~|", "|-|", "]~[", "}{", "!-!", "1-1", "\-/", "I+I", "/-\\"],
    "k": [">|", "|<", "/<", "1<", "|c", "|(", "|{"],
    "i": ["1", "[]", "|", "!", "eye", "3y3", "]["],
    "s": ["5", "$", "z", "§", "ehs", "es", "2"],
    "y": ["j", "`/", "Ч", "7", "\|/", "¥", "\//"],
    "t": ["7", "+", "-|-", "']['", "†", '"|"', "~|~"]
}

# "the"와 "iskey"의 모든 조합 생성
def generate_leet_variants(word):
    letter_choices = [leet_dict[c] for c in word]
    return ["".join(variant) for variant in itertools.product(*letter_choices)]

leet_start_candidates = generate_leet_variants("the")
leet_end_candidates = generate_leet_variants("iskey")

print(f"총 {len(leet_start_candidates)}개의 'the' 변환 가능성")
print(f"총 {len(leet_end_candidates)}개의 'iskey' 변환 가능성")

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

    try:
        dream = ''.join(chr(byte) for byte in xor_for_dream.to_bytes((xor_for_dream.bit_length() + 7) // 8, 'big'))
    except ValueError:
        print("[ERROR] XOR 변환 오류")
        return None

    print(f"[DEBUG] XOR 결과 (dream): {dream}")

    # dream 내부에서 "the" 변형 또는 "iskey" 변형이 포함된 부분을 찾기
    found_start = [start for start in leet_start_candidates if start in dream]
    found_end = [end for end in leet_end_candidates if end in dream]

    if found_start and found_end:
        print(f"[DEBUG] 찾은 the 패턴: {found_start[0]}")
        print(f"[DEBUG] 찾은 iskey 패턴: {found_end[0]}")
        
        LEET_START_STRING = found_start[0]
        LEET_END_STRING = found_end[0]

        pw_key = dream.split(LEET_START_STRING, 1)[-1].split(LEET_END_STRING, 1)[0]
        print(f"[DEBUG] 추출된 pw_key: {pw_key}")

        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

        try:
            password_raw = ''.join(chr(byte) for byte in xor_for_password.to_bytes((xor_for_password.bit_length() + 7) // 8, 'big'))
        except ValueError:
            print("[ERROR] 패스워드 XOR 변환 오류")
            return None

        print(f"[DEBUG] XOR 결과 (password_raw): {password_raw}")

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

        return password
    else:
        print("[ERROR] 'the' 또는 'iskey' 변형을 찾지 못함")
        return None

puzzle = "4448175452265f0367565e360a6c583670214532507c252f63155f2c671c2f59046d10525a344e0623734f517a2f55641877355f386a06063875564369085f016034535b2467614e0f73131604163b5845314f17620346375a7b11162d6146261f633029617c583d7e7c586b24690c54041f4f016126505e2629566e6a3c4f57"

password = find_password(puzzle)

if password:
    print(f"flag is DH{{{password}}}")
else:
    print("[ERROR] 패스워드 추출 실패")

 

브포..성공!

 

DH{zeWplY4ANnQe8Y1oPvduDZuGFXgWJj1S23dVQ2LNpQQODLp2zJTs}