/
checkEWS.py
138 lines (117 loc) · 4.73 KB
/
checkEWS.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
import ssl
import sys
import base64
import re
import binascii
try:
from http.client import HTTPConnection, HTTPSConnection, ResponseNotReady
except ImportError:
from httplib import HTTPConnection, HTTPSConnection, ResponseNotReady
from impacket import ntlm
# https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getfolder-operation
# getfolder-operation
POST_BODY = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>Default</t:BaseShape>
</m:FolderShape>
<m:FolderIds>
<t:DistinguishedFolderId Id="inbox"/>
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
'''
def checkEWS(host, port, mode, domain, user, data):
ews_url = "/EWS/Exchange.asmx"
if port ==443:
try:
uv_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
session = HTTPSConnection(host, port, context=uv_context)
except AttributeError:
session = HTTPSConnection(host, port)
else:
session = HTTPConnection(host, port)
# Use impacket for NTLM
ntlm_nego = ntlm.getNTLMSSPType1(host, domain)
#Negotiate auth
negotiate = base64.b64encode(ntlm_nego.getData())
# Headers
headers = {
"Authorization": 'NTLM %s' % negotiate.decode('utf-8'),
"Content-type": "text/xml; charset=utf-8",
"Accept": "text/xml",
"User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36"
}
session.request("POST", ews_url, POST_BODY, headers)
res = session.getresponse()
res.read()
if res.status != 401:
print('Status code returned: %d. Authentication does not seem required for URL'%(res.status))
return False
try:
if 'NTLM' not in res.getheader('WWW-Authenticate'):
print('NTLM Auth not offered by URL, offered protocols: %s'%(res.getheader('WWW-Authenticate')))
return False
except (KeyError, TypeError):
print('No authentication requested by the server for url %s'%(ews_url))
return False
print('[*] Got 401, performing NTLM authentication')
# Get negotiate data
try:
ntlm_challenge_b64 = re.search('NTLM ([a-zA-Z0-9+/]+={0,2})', res.getheader('WWW-Authenticate')).group(1)
ntlm_challenge = base64.b64decode(ntlm_challenge_b64)
except (IndexError, KeyError, AttributeError):
print('No NTLM challenge returned from server')
return False
if mode =='plaintext':
password1 = data;
nt_hash = ''
elif mode =='ntlmhash':
password1 = ''
nt_hash = binascii.unhexlify(data)
else:
print('[!]Wrong parameter')
return False
lm_hash = ''
ntlm_auth, _ = ntlm.getNTLMSSPType3(ntlm_nego, ntlm_challenge, user, password1, domain, lm_hash, nt_hash)
auth = base64.b64encode(ntlm_auth.getData())
headers = {
"Authorization": 'NTLM %s' % auth.decode('utf-8'),
"Content-type": "text/xml; charset=utf-8",
"Accept": "text/xml",
"User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36"
}
session.request("POST", ews_url, POST_BODY, headers)
res = session.getresponse()
body = res.read()
if res.status == 401:
print('[!] Server returned HTTP status 401 - authentication failed')
return False
else:
print('[+] Valid:%s %s'%(user,data))
#print(body)
return True
if __name__ == '__main__':
if len(sys.argv)!=7:
print('[!]Wrong parameter')
print('checkEWS')
print('Use to check the valid account of Exchange Web Service(Support plaintext and ntlmhash)')
print('Author:3gstudent')
print('Reference:https://github.com/dirkjanm/PrivExchange/blob/master/privexchange.py')
print('Usage:')
print('%s <host> <port> <mode> <domain> <user> <password>'%(sys.argv[0]))
print('<mode>:')
print('- plaintext')
print('- ntlmhash')
print('Eg.')
print('%s 192.168.1.1 443 plaintext test.com user1 password1'%(sys.argv[0]))
print('%s test.com 80 ntlmhash test.com user1 c5a237b7e9d8e708d8436b6148a25fa1'%(sys.argv[0]))
sys.exit(0)
else:
checkEWS(sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])