-
Notifications
You must be signed in to change notification settings - Fork 429
Strategy
💉jSQL
is checking for the slowest to the fastest strategy in order to identify the best usable and to get rows efficiently.
The slowest strategy gets a single character bit-by-bit with 7 requests, the fastest strategy gets large chunks of text with a single query.
The simplest strategy shows the rows directly in the source page, the worst usable strategy does not even display anything.
Note
Create an issue to share additional strategies you know.
Tip
Switch to any confirmed strategy from the menu in the address bar, and compare the process behavior in the logs.
The following pseudo-code describes the extraction methods from the simplest to the most convoluted.
Union-based is the standard strategy that extracts the most chars with the least amount of queries.
Response from the target contains directly the SQL result so the process is really fast.
select row then show row
↘️ ~100k chars in 1 request
Strategy is basically identical and as efficient as Union
, though Stack
feature is not proposed by all engines thus less frequently encountered.
select row then show row
↘️ ~100k chars in 1 request
Database engines may contain buggy syntax processor which can be triggered by a specific forged SQL query. The result appears directly in the error message returned by the database, however with a size reduced significantly.
Error strategy gets the SQL results directly in the response so it's still really efficient, particularly useful when Union
strategy is not working.
select row then show row in internal error message
↘️ ~100 chars in 1 request
You may not get the result directly in the response for various reasons, nevertheless the target may still answer back to your query and display a specific given text for a specific query.
It means you can query the database and confirm or infirm any statement and receive the answer Yes
or No
depending on the text in the response.
Given that each letter can be translated into its ASCII integer code, which in turn can be split into its binary components :
char:'a' ➡️ ascii:97 ➡️ bin:1100001
Then it means you can query the entire results bit-by-bit and char-by-char, even when the target does not return anything directly. It's significantly slower than Union
or Error
, though also faster than Blind bin
as every bits can be fetched in parallel.
if Nth bit of ascii char X in the row is 1
then 🟢 show page A
else 🔴 show page B
↘️ Nth bit of ascii(X in the row) from 1 to 7 is 🟢 or 🔴 ?
➡️ pages:🟢;🟢;🔴;🔴;🔴;🔴;🟢 ➡️ bin:1100001 ➡️ ascii:97 ➡️ char:'a' in 7 requests
As any letter can be translated into its ASCII integer code from a range between 32 and 127, you can apply algorithm binary search instead of Blind bit
for example when database does not provide bitwise feature.
You check that char is up or below the mid range boundary, then continue until the mid boundary is reduced to its minimum and finally identify the char :
char:'a' ➡️ ascii:97 ➡️ bin search 97 in range 32 and 127 ?
32> 🟢mid>=79? >127 ➡️ 79> 🔴mid>=103? >127 ➡️ ... ➡️ 97> 🟢mid>=97? >97
So you query char-by-char but you need to wait for each boundary checks in sequence as it prevents parallel execution.
if char X in range between low and high boundaries
then 🟢 show page A
else 🔴 show page B
↘️ ascii(X in the row) between low and high boundaries is 🟢 or 🔴 ?
➡️ pages:🟢➡️🔴➡️🟢➡️... ➡️ ascii:97 ➡️ char:'a' in 7 requests
When the target does not even return anything in the page, no SQL result, no specific text related to the query, you can still create statement confirmation for Yes
or No
with the delay required by the target to answer.
Like Blind bit
the entire results is built bit-by-bit. And it's also even slower than Blind
and depends strongly on the network quality and on the target reliability, consequently you may get corrupted chars as the loading time is not strictly reliable.
if Nth bit of char X in the row is 1
then 🟢 sleep 5s
else 🔴 do-nothing
↘️ Nth bit of ascii(X in the row) from 1 to 7 is 🟢 or 🔴 ?
➡️ pages:🟢;🟢;🔴;🔴;🔴;🔴;🟢 ➡️ bin:1100001 ➡️ ascii:97 ➡️ char:'a' in 7 requests
Bitwise representation of chars can be processed more efficiently than Blind
if you can get groups of bits, yet the target requires a set of 7 distinct responses to match any of the possible groups of Yes
and No
combination.
Typical use case is a market site loading a page by id and returning a distinct content for each id (eg. ?id=1
, ?id=2
, etc).
if Nth bit-group of char X in row is 000 then 🔴🔴🔴 show page A
else if Nth bit-group of char X in row is 001 then 🔴🔴🟢 show page B
...
else if Nth bit-group of char X in row is 110 then 🟢🟢🔴 show page F
else if Nth bit-group of char X in row is 111 then 🟢🟢🟢 show page G
↘️ Nth bits-group of ascii(X in row) from 1 to 3 ?
➡️ pages:🔴🔴🟢;🟢🔴🔴;🔴🔴🟢 ➡️ bin:1100001 ➡️ ascii:97 ➡️ char:'a' in 3 requests
- DNS: mount a DNS server, inject target with calls to the DNS server subdomain then get result from DNS logs
- Position: get
Boolean
result from a limited chars map, reducing from 7 to 3 queries - Duality: combine
Time
withBlind
to extract 2 bits directly - Ascii: convert each char to ASCII code and open matching page id similarly to
Multibit
Speed | Read bits |
Page Diff |
Show rows |
Show onINSERT
|
Show onUPDATE
|
Show onDELETE
|
|
---|---|---|---|---|---|---|---|
Time bit |
🐌🐌🐌 | ✔ | ❌ | ❌ | ❌ | ❌ | |
Blind bin |
🐌🐌 | ✔ | ❌ | ❌ | ❌ | ❌ | |
Blind bit |
🐌🐌 | ✔ | ✔ | ❌ | ❌ | ❌ | ❌ |
Multibit |
🐌 | ✔ | ✔ | ❌ | ❌ | ❌ | ❌ |
Error |
⚡ | ✔ | ✔ | ✔ | ✔ | ||
Stack |
⚡⚡⚡ | (✔) | ❌ | ❌ | ❌ | ||
Union |
⚡⚡⚡ | ✔ | ❌ | ❌ | ❌ |