Skip to content

Strategies

ron190 edited this page Jun 9, 2024 · 93 revisions

πŸ’‰jSQL is checking from slowest to fastest strategies in order to identify the best strategy 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 most hazy strategy does not even display anything.

Note

Open a discussion to share about additional strategies.

The following pseudo-code describe the extraction methods from the simplest to the most convoluted.

1. Normal β€” union [select]

Union-based is the standard strategy that extract 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

2. Stacked β€” ; [select]

Strategy is basically identical and as efficient as Normal, though Stacked feature is not proposed by all engines thus less frequently encountered.

select row then show row

β†˜οΈ ~100k chars in 1 request

3. Error β€” cast([select] as numeric)

Database engines may contain buggy syntax processor which can be triggered by a specific forged SQL query. The result appears directly in a 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 Normal strategy is not working.

select row then show row in internal error message

β†˜οΈ ~100 chars in 1 request

4. Blind β€” and [select]=true

For various reasons you may not get the result directly in the response, nevertheless target can show a specific given text for a specific query.

It means you can query the database to get an exact response like Yes or No depending on the text in the response.

Additionally 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

You thus can query the entire SQL result bit-by-bit and char-by-char, even when the target does not return anything directly. However it's significantly slower than Normal or Error.

if Nth bit of char X in row is 1
then 🟒 show page A
else πŸ”΄ show page B

β†˜οΈ Nth bit of ascii(X in row) from 1 to 7 
➑️ pages:🟒;🟒;πŸ”΄;πŸ”΄;πŸ”΄;πŸ”΄;🟒 ➑️ bin:1100001 ➑️ ascii:97 ➑️ char:'a' in 7 requests

5. Time β€” and if([select], sleep())

Last is when the target does not even return anything in the page, no SQL result, no specific text related to the query.

With Time the criteria allowing to query the database for Yes and No is the delay required by the target to load.

Like Blind the entire result is built bit-by-bit. It's also even slower than Blind and depends strongly on the network quality and on target reliability, consequently you may get corrupted chars as the loading time is not strictly reliable.

if Nth bit of char X in row is 1
then 🟒 sleep 5s
else πŸ”΄ do-nothing

β†˜οΈ Nth bit of ascii(X in row) from 1 to 7 
➑️ pages:🟒;🟒;πŸ”΄;πŸ”΄;πŸ”΄;πŸ”΄;🟒 ➑️ bin:1100001 ➑️ ascii:97 ➑️ char:'a' in 7 requests

6. Multibit β€” and id=[select]

Binary 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.

Best use case applicable is when you query a target by id and you get distinct content for every 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

Other strategies (not implemented yet)

  • 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 with Boolean to extract 2 bits directly

Summary

Speed Read
bit(s)
Page
Diff
Show
rows
Show on
INSERT
Show on
UPDATE
Time 🐌🐌🐌 β˜‘οΈ ⬜ ❌ ❌ ❌
Blind 🐌🐌 β˜‘οΈ β˜‘οΈ ❌ ❌ ❌
Multibit 🐌 β˜‘οΈ β˜‘οΈ ❌ ❌ ❌
Error ⚑ ⬜ ⬜ β˜‘οΈ β˜‘οΈ β˜‘οΈ
Stacked ⚑⚑⚑ ⬜ ⬜ β˜‘οΈ ❌ ❌
Normal ⚑⚑⚑ ⬜ ⬜ β˜‘οΈ ❌ ❌

Previous topic: Description, Next topic: Insights