Lukas' Notes

A vulnerable login form prints only Sent or Address not found. There is no table, no error, no echo of what the database returned. It looks useless — but a single binary answer per request is enough to read out the entire database.

The trick is to fold the data we want into the question, not into the answer. Suppose we want the password of the user whose mail starts with marco. We do not ask the page to show the password — it cannot. We ask it to answer one yes/no question: is the next character equal to my guess? The form already answers yes/no on every request, so it becomes an oracle.

Mechanically, the comparison is injected into a condition the page already evaluates. To run it case-sensitively and position-by-position, we ask the database

' OR BINARY '<guess>' = MID(password, <pos>, 1)
    AND mail LIKE 'marco%' -- -

If the page answers Sent, the guess was right and we move to the next position. Otherwise we try the next candidate. The SQL MID selects one character, BINARY forces a byte comparison, and the OR/AND shape turns the comparison into a predicate the query actually executes.

Two refinements matter in practice. First, the oracle gives no information about the number of columns, so when an ordinary UNION SELECT is available you probe its width with null columns first — but for blind injection the comparison is folded into a boolean, so column counting is unnecessary. Second, you cut the number of requests by replacing the linear scan with a binary search over the alphabet: each comparison halves the remaining candidate space instead of removing one character.

When the page refuses even this — it shows the same text no matter what — the oracle disappears, but timing replaces it. A SLEEP() whose execution the form never sees still changes how long the request takes, so a slow answer means yes and a fast answer means no. The totally blind variant keeps the same one-bit-per-request structure; it only swaps the channel from content to time.

The corrected mental model: a side channel is not a leak you read off, it is a question you learn to ask. Once you can phrase any predicate about the database as a yes/no condition inside the query, the page’s binary behaviour — however coarse — is enough to reconstruct the data bit by bit.