Wargame: Natas
Level: 18
Category: Web Exploitation
Description
A login page shows the password only to admin users. The source code reveals that PHP session IDs are assigned as sequential integers up to a maximum of 640. The goal is to find the admin’s session ID.
Overview
- The server assigns
PHPSESSIDvalues as integers in the range[1, 640]. - One of these session IDs belongs to the admin user.
- We iterate all 640 possible values, sending each as the
PHPSESSIDcookie with a login attempt. - When we hit the admin session, the response contains “You are an admin” followed by the next password.
Background: Session Brute Force
- Session tokens should be cryptographically random and have a large enough space to prevent enumeration.
- A session space of 640 integers is trivially exhausted with automated requests.
- Even with rate limiting, sequential IDs leak ordering information that aids targeted guessing.
- The fix is to use a CSPRNG to generate session tokens (PHP’s default session ID generation does this).
Solution
Step 1: Read the Source
- View the page source to confirm
maxid = 640and that sessions are stored as plain integers. - The admin session is pre-existing on the server; we just need to find its ID.
Step 2: Iterate All Session IDs
- For each integer from 1 to 640, send a POST login request with
PHPSESSIDset to that integer.
for session_id in range(1, 641):
cookies = {"PHPSESSID": str(session_id)}
r = requests.post(
url,
auth=HTTPBasicAuth("natas18", password),
data={"username": "natas19", "password": "idk"},
cookies=cookies,
)
if "You are an admin" in r.text:
break
Step 3: Extract the Password
- The matching response body contains the natas19 password.
Password
8LMJEhKFbMKIL2mxQKjv0aEDdk7zpT0s