08 Time-Based Blind SQLi - Linear, Binary, and Async Extraction

A practical comparison of linear, binary, and asynchronous techniques fortime-based blind SQL injection. This article focuses on request efficiency,timing behavior, and performance trade-offs.

As programming languages used for back-end development have matured, frameworks for these languages have emerged to abstract away common application concerns such as routing, authentication, database access, and input handling. One widely adopted abstraction is Object-Relational Mapping (ORM), which allows developers to interact with databases using language-level objects rather than raw SQL queries.

When used correctly, ORMs can significantly reduce the likelihood of injection vulnerabilities by providing parameterized query interfaces and automatic input handling. However, incorrect usage, misuse of raw queries, or improper sanitization can still expose applications to injection attacks. As a result, SQL injection remains a persistent and relevant attack vector, and it continues to appear in the OWASP Top Ten for 2025arrow-up-right.

In the OSWE course and labs, students are exposed to SQL injection vulnerabilities that go beyond simple first-order attacks. These include error-based, boolean-based blind, and time-based blind SQL injection, all of which require more careful reasoning and scripting to exploit effectively.

Examples of these attack styles include:

Error:     ' OR 1=CAST((SELECT table_name FROM information_schema.tables)AS INT)--
Boolean:   ' AND (SELECT SUBSTRING((SELECT database()),1,1))='t'--
Time:      ' AND IF(1=1,SLEEP(5),0)--

When crafting payloads for automated exploitation, performance matters. Extracting a single character from a secret value may require dozens of requests. As the length of the target string increases, extraction time can grow quickly—especially when rate limits, logging, or intrusion detection are in place.

For simplicity, the discussion here focuses on ASCII-based extraction. Unicode introduces additional complications that are outside the scope of this article.

The Cost of Linear Brute-Force Extraction

Consider a time-based blind SQL injection vulnerability in a users table where we want to extract the password for the user with id = 1. A naïve approach might test each character individually.

For example, testing whether the first character of the password is 'a':

?id=1' AND (SELECT CASE WHEN (ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))=97) THEN pg_sleep(3) ELSE 0 END)--

If we assume the password contains only alphanumeric characters, our search space spans ASCII values 48 (0) to 122 (z): 75 possible values per character.

In the worst case, extracting a 32-character password using this linear approach could require:

75 guesses × 32 characters = 2400 requests

With even a modest 0.1s response time per request, this quickly becomes impractical. While brute-forcing may still succeed if rate limits are lax and logs are ignored, it is inefficient and noisy.

Binary Search: Fewer Requests, Same Delay Cost

A more efficient strategy is binary search. Instead of testing for equality, we test whether a character is greater than or less than a midpoint value.

Each request halves the remaining search space. With a known ASCII range, this reduces extraction to roughly 7 requests per character.

However, an important observation emerges: Every true comparison still sleeps.

While binary search dramatically reduces the number of requests, it does not necessarily reduce wall-clock time when each successful comparison incurs a fixed delay. A linear search might complete many fast failures before hitting a slow success, while a binary search guarantees several slow responses per character.

Binary search is therefore more request-efficient, but not always time-efficient.

Why Async Changes Everything

This is where asynchronous execution fundamentally alters the economics of time-based attacks.

Rather than extracting characters sequentially, we can launch independent binary searches for every position in the token at once. Each position becomes its own task, and while one request is sleeping, others continue executing.

The result is not fewer total requests, but a better utilization of time.

Conceptually:

  • Each token position is an independent binary search

  • Requests overlap instead of blocking

  • Slow sleeps are hidden behind concurrent work

To demonstrate these differences cleanly, a deliberately simplified server was implemented. Rather than connecting to a real database, the server stores a randomly generated token in memory and exposes endpoints that behave like a vulnerable database backend.

This approach avoids unnecessary complexity while preserving the timing behavior relevant to blind SQL injection.

Key characteristics:

  • Token stored in memory

  • Fixed sleep delay for true conditions

  • Request counter for measurement

  • Token rotation via reset endpoint

Example Payloads in the Client

A linear equality test for position 5:

where a binary request would be:

Observing Async Extraction in Practice

One of the most instructive aspects of the async approach is how results arrive out of order:

This behavior reinforces several important concepts:

  • Completion order does not match token order

  • Faster positions finish first

  • Reconstruction occurs by index, not arrival order

  • Async execution trades determinism for speed

Results Summary

Blind SQLi server implmentation

Blind SQLi client implementation

Last updated