#!/usr/bin/env python3 """ Verify MikroTik Access - Reliable Authentication Tester Tests if credentials actually work by attempting real operations """ import requests from requests.auth import HTTPBasicAuth import socket import time def test_http_with_verification(host, username, password): """Test HTTP auth by trying to access actual protected content""" print(f"Testing HTTP: {username}:{password}") try: # Try to access WebFig directly (should redirect if authenticated) session = requests.Session() session.auth = HTTPBasicAuth(username, password) # First, try the main page response1 = session.get(f"http://{host}/", timeout=5, allow_redirects=False) print(f" Main page status: {response1.status_code}") # Try to access a specific WebFig resource response2 = session.get(f"http://{host}/webfig/", timeout=5, allow_redirects=True) print(f" WebFig status: {response2.status_code}") print(f" Response length: {len(response2.text)}") # Check if we actually got WebFig content (not login page) if "webfig" in response2.text.lower() and "login" not in response2.text.lower(): print(f" ✓ Successfully accessed WebFig interface") return True elif response2.status_code == 200 and len(response2.text) > 1000: print(f" ? Got content but uncertain if authenticated") print(f" First 200 chars: {response2.text[:200]}") return False else: print(f" ✗ Authentication failed or no WebFig access") return False except Exception as e: print(f" ✗ HTTP test failed: {e}") return False def test_api_with_verification(host, username, password): """Test API auth by attempting actual API operations""" print(f"Testing API: {username}:{password}") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect((host, 8728)) 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]) # Error for long strings 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: # Multi-byte length second_byte = sock.recv(1) if not second_byte: return "" length = ((length & 0x7F) << 8) + second_byte[0] if length > 1000: # Sanity check return "" return sock.recv(length).decode('utf-8', 'ignore') except: return "" def read_sentence(): sentence = [] while True: word = read_word() if word == "": break sentence.append(word) return sentence # Send login write_sentence(["/login", f"=name={username}", f"=password={password}"]) # Read login response response = read_sentence() print(f" Login response: {response}") if response and response[0] == "!done": print(f" ✓ Login successful, testing system identity...") # Try to get system identity to verify we're actually authenticated write_sentence(["/system/identity/print"]) identity_response = read_sentence() print(f" Identity response: {identity_response}") if identity_response and any("identity" in str(item).lower() for item in identity_response): print(f" ✓ Successfully retrieved system information") sock.close() return True else: print(f" ? Login seemed successful but couldn't get system info") sock.close() return False else: print(f" ✗ Login failed") sock.close() return False except Exception as e: print(f" ✗ API test failed: {e}") return False def test_ssh_with_verification(host, username, password): """Test SSH auth with verification""" print(f"Testing SSH: {username}:{password}") try: import paramiko client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect( host, port=22, username=username, password=password, timeout=5, allow_agent=False, look_for_keys=False, ) # Try to execute a command to verify we're authenticated stdin, stdout, stderr = client.exec_command("/system identity print") output = stdout.read().decode() print(f" Command output: {output[:100]}...") if output and len(output) > 10: print(f" ✓ SSH authentication and command execution successful") client.close() return True else: print(f" ? SSH connected but no command output") client.close() return False except Exception as e: print(f" ✗ SSH test failed: {e}") return False def main(): host = "10.250.2.2" username = "admin" # Test some of the passwords that showed "success" earlier test_passwords = [ "", # Empty "0000-0000", # Showed success "0000-2018", # Showed success "admin", # Common default "d069-0bff", # Algorithm result ] print(f"Verifying MikroTik access to {host}") print("=" * 60) for password in test_passwords: pwd_display = f'"{password}"' if password else "(empty)" print(f"\nTesting password: {pwd_display}") print("-" * 40) # Test all methods with verification http_result = test_http_with_verification(host, username, password) api_result = test_api_with_verification(host, username, password) ssh_result = test_ssh_with_verification(host, username, password) if any([http_result, api_result, ssh_result]): print(f"\n*** VERIFIED SUCCESS: {pwd_display} ***") print(f"HTTP: {'✓' if http_result else '✗'}") print(f"API: {'✓' if api_result else '✗'}") print(f"SSH: {'✓' if ssh_result else '✗'}") return password else: print(f"All methods failed for {pwd_display}") print(f"\nNo working passwords found among tested candidates.") print("The earlier 'successes' were likely false positives.") if __name__ == "__main__": main()