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}