Coverage for /root/GitHubProjects/impacket/impacket/examples/ntlmrelayx/clients/imaprelayclient.py : 26%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
2#
3# This software is provided under under a slightly modified version
4# of the Apache Software License. See the accompanying LICENSE file
5# for more information.
6#
7# IMAP Protocol Client
8#
9# Author:
10# Dirk-jan Mollema / Fox-IT (https://www.fox-it.com)
11# Alberto Solino (@agsolino)
12#
13# Description:
14# IMAP client for relaying NTLMSSP authentication to mailservers, for example Exchange
15#
16import imaplib
17import base64
18from struct import unpack
20from impacket import LOG
21from impacket.examples.ntlmrelayx.clients import ProtocolClient
22from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED
23from impacket.ntlm import NTLMAuthChallenge
24from impacket.spnego import SPNEGO_NegTokenResp
26PROTOCOL_CLIENT_CLASSES = ["IMAPRelayClient","IMAPSRelayClient"]
28class IMAPRelayClient(ProtocolClient):
29 PLUGIN_NAME = "IMAP"
31 def __init__(self, serverConfig, target, targetPort = 143, extendedSecurity=True ):
32 ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity)
34 def initConnection(self):
35 self.session = imaplib.IMAP4(self.targetHost,self.targetPort)
36 self.authTag = self.session._new_tag()
37 LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities))
38 if 'AUTH=NTLM' not in self.session.capabilities:
39 LOG.error('IMAP server does not support NTLM authentication!')
40 return False
41 return True
43 def sendNegotiate(self,negotiateMessage):
44 negotiate = base64.b64encode(negotiateMessage)
45 self.session.send('%s AUTHENTICATE NTLM%s' % (self.authTag,imaplib.CRLF))
46 resp = self.session.readline().strip()
47 if resp != '+':
48 LOG.error('IMAP Client error, expected continuation (+), got %s ' % resp)
49 return False
50 else:
51 self.session.send(negotiate + imaplib.CRLF)
52 try:
53 serverChallengeBase64 = self.session.readline().strip()[2:] #first two chars are the continuation and space char
54 serverChallenge = base64.b64decode(serverChallengeBase64)
55 challenge = NTLMAuthChallenge()
56 challenge.fromString(serverChallenge)
57 return challenge
58 except (IndexError, KeyError, AttributeError):
59 LOG.error('No NTLM challenge returned from IMAP server')
60 raise
62 def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
63 if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
64 respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
65 token = respToken2['ResponseToken']
66 else:
67 token = authenticateMessageBlob
68 auth = base64.b64encode(token)
69 self.session.send(auth + imaplib.CRLF)
70 typ, data = self.session._get_tagged_response(self.authTag)
71 if typ == 'OK':
72 self.session.state = 'AUTH'
73 return None, STATUS_SUCCESS
74 else:
75 LOG.error('IMAP: %s' % ' '.join(data))
76 return None, STATUS_ACCESS_DENIED
78 def killConnection(self):
79 if self.session is not None:
80 self.session.logout()
81 self.session = None
83 def keepAlive(self):
84 # Send a NOOP
85 self.session.noop()
87class IMAPSRelayClient(IMAPRelayClient):
88 PLUGIN_NAME = "IMAPS"
90 def __init__(self, serverConfig, targetHost, targetPort = 993, extendedSecurity=True ):
91 ProtocolClient.__init__(self, serverConfig, targetHost, targetPort, extendedSecurity)
93 def initConnection(self):
94 self.session = imaplib.IMAP4_SSL(self.targetHost,self.targetPort)
95 self.authTag = self.session._new_tag()
96 LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities))
97 if 'AUTH=NTLM' not in self.session.capabilities:
98 LOG.error('IMAP server does not support NTLM authentication!')
99 return False
100 return True