SQL injection/Blind/Timing based extraction
Timing based extraction
|If not on a LAN when this technique is utilized, buggy and unpredictable results will be attained.|
SQL timing attacks are a form of blind SQL injection that allow an attacker to determine the character retrieved based on the time it takes to load a page, for example when retrieving the letter "A" the page would take 65 seconds to load (65 is the ascii value of "A"). These attacks can be optimized by retrieving a nibble at a time (half a byte, four bits) or even made more stealthy by retrieving a word per request (two bytes). Timing-based extraction attacks are more stealthy than boolean enumeration because they require less requests (one request per target value up to a QWORD versus eight requests per byte), however they take much longer to conduct. Sometimes, timing attacks may be the only option in a Full blind SQL injection attack.
This testing is ideal when:
- It is taking place on a relatively low latency network
- There is access to a consistent latency and the remote page has a consistent load time (may not vary by more than 0.5 seconds)
Single byte exraction takes less queries to perform the same results, and leaves a smaller log footprint.
- A timer will need to be used to see how long it takes the remote server to serve the page.
Examples of timing-based single-byte exfiltration:
- Extracting the first character of the database name in a single request:
AND sleep(ascii(SUBSTRING(@@DATABASE,1,1))) -- MySQL AND pg_sleep(ascii(SUBSTRING(current_database,1,1))) IS NULL -- PostgreSQL
- By timing these (in seconds) the integer value of the ascii code of the first character of the database will be attained.
Sometimes, a retrieving a single byte per request may be too slow or too fast, depending on the situation, however, this attack can also retrieve varying sizes of data, for example, a full word could be retrieved or a nibble at a time. The time required to perform these attacks can vary, retrieving a full word would take upto 65,535 seconds (18 hours) but would only require a single query per two bytes. A nibble would only require up to 16 seconds per nibble, thirty-two seconds per byte (sixty-four seconds per word), but requires more requests and is much less evasive.
- To retrieve a full word the request would be:
id=1 AND sleep(conv(SUBSTRING(hex(version()),1,4),16,10))
- For a nibble:
id=1 AND sleep(conv(SUBSTRING(hex(version),1,1),16,10))
This query converts the string to to hex, and takes out the first nibble (up to 0xf), and sleeps for that many seconds, whereas the word query takes the first two bytes (four nibbles). The advantage of retrieving a nibble is speed, but retrieving a word is much more stealthy (it might take weeks (even years) to complete a single query). One SQL query every couple hours is obviously less detectable than one SQL query every 10 seconds, and could easily be mistaken for a random scanner. In this case, there is a trade off between speed and stealth and an astute attacker will determine the best solution for his situation. In most cases, retrieving a full byte per query is the best solution, however this can change depending on the sensitivity of the target (and countermeasures in place).