Nahamcon 2025 Flagdle
This challenge is just the wordle game using the flag format instead.However we have unlimited attempts. We can use chatgpt to write a python program to send the request using python
import requests
URL = "http://challenge.nahamcon.com:32123/guess"
def send_guess(guess):
if not guess.startswith("flag{") or not guess.endswith("}") or len(guess) != 38:
raise ValueError("Guess must be in format flag{[32 hex characters]}")
response = requests.post(URL, json={"guess": guess})
if response.ok:
data = response.json()
result = data.get("result", "")
print(f"Guess: {guess}")
print(f"Feedback: {result}") # Properly decoded emojis
else:
print("Error:", response.status_code, response.text)
# Example usage
send_guess("flag{1234567890abcdef0000000000000000}")
This gives us the result. Guess: flag{1234567890abcdef0000000000000000} Feedback: 🟨🟨⬛🟩🟨🟨🟩🟨🟨⬛🟨🟨🟨🟨🟨⬛⬛⬛⬛🟩⬛🟩 The python program can have further logic added and automate the attempts
import requests
import time
import random
URL = "http://challenge.nahamcon.com:32123/guess"
HEX_CHARS = "0123456789abcdef"
def send_guess(guess):
response = requests.post(URL, json={"guess": guess})
if response.ok:
return response.json().get("result", "")
else:
print("Error:", response.status_code, response.text)
return None
def count_matches(feedback):
return sum(1 for c in feedback if c in ['🟩', '🟨'])
def phase1_find_char_frequencies():
print("🔍 Starting Phase 1: Character Frequency Discovery")
char_counts = {}
for c in HEX_CHARS:
guess = f"flag}"
feedback = send_guess(guess)
if feedback:
match_count = count_matches(feedback)
char_counts[c] = match_count
print(f"{c}: {match_count} matches -> {feedback}")
time.sleep(0.5) # avoid hammering server
print("\n✅ Phase 1 Complete!")
print("Discovered character counts:")
for k, v in sorted(char_counts.items()):
print(f"{k}: {v}")
return char_counts
def solve_positions(char_freq):
print("\n🚀 Starting Phase 2: Position Deduction")
known_chars = []
for c, count in char_freq.items():
known_chars.extend([c] * count)
if len(known_chars) != 32:
raise ValueError("Total known characters ≠ 32! Phase 1 might be incomplete.")
random.shuffle(known_chars)
guess = known_chars.copy()
confirmed = [''] * 32
confirmed_mask = [False] * 32
attempts = 0
while not all(confirmed_mask):
guess_str = "flag{" + ''.join(guess) + "}"
feedback = send_guess(guess_str)
if feedback is None:
continue
attempts += 1
print(f"[{attempts}] {guess_str} -> {feedback}")
for i in range(32):
if feedback[i] == '🟩' and not confirmed_mask[i]:
confirmed[i] = guess[i]
confirmed_mask[i] = True
# Shuffle only unconfirmed positions
unconfirmed_indices = [i for i, confirmed_flag in enumerate(confirmed_mask) if not confirmed_flag]
remaining_chars = [guess[i] for i in unconfirmed_indices]
random.shuffle(remaining_chars)
for idx, i in enumerate(unconfirmed_indices):
guess[i] = remaining_chars[idx]
time.sleep(0.5)
flag = "flag{" + ''.join(confirmed) + "}"
print("\n🎉 Flag Found!")
print(f"✅ {flag}")
return flag
if __name__ == "__main__":
char_freq = phase1_find_char_frequencies()
solve_positions(char_freq)
running this gives the following output
with the final result of
the flag being flag{bec42475a614b9c9ba80d0eb7ed258c5}