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