Difficulty: easy

Category: crypto

Author: xnull

Description:

### Signed API

This API uses MD5 signatures to authenticate requests. You have a valid signature for "user=guest", but you need admin access.

The signature is created as MD5(secret + data), where the secret is unknown to you.

**Hint:** The server expects data as a hex string. It does `bytes.fromhex(data)` to decode it. Don't convert the hex to bytes and URL encode, just send the hex directly.

Scenario

We got a signed URL at https://<UUID>.ctf.endolum.io:1337/api?data=user=guest&signature=191c15a2b6652068b0fb37f084f4fb98 and we need to get user=admin in the data parameter in order to get the flag.

Solution

We’ll use hash_extender and a python script to get the flag:

import subprocess
import sys
import re
import requests
from urllib.parse import quote
from rich import print

HASH_EXTENDER = "./hash_extender"

base = sys.argv[1].rstrip("/") if len(sys.argv) > 1 else "http://localhost:3000"
original = "user=guest"
sig = "191c15a2b6652068b0fb37f084f4fb98"
append = ";user=admin"

out = subprocess.run(
    [
        HASH_EXTENDER,
        "--data", original,
        "--signature", sig,
        "--append", append,
        "--secret-min", "8",
        "--secret-max", "32",
        "--format", "md5"
    ],
    capture_output=True,
    text=True
).stdout.splitlines()

for line in out:
    s = re.search(r"New signature:\s*([0-9a-f]+)", line)
    if s:
        new_sig = s.group(1)
    m = re.search(r"New string:\s*(.+)", line)
    if m:
        new_data = m.group(1)
        url = f"{base}/api?data={quote(new_data)}&signature={new_sig}"
        print(requests.get(url).json().get("flag", "."), end="")
# ............ENDLM{3d1c153ba27b9170eecd9643ce3d0a8f564d6e43d3b4ae4c}...........

Flag: ENDLM{3d1c153ba27b9170eecd9643ce3d0a8f564d6e43d3b4ae4c}