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

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

## 56 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# SMTP Protocol Client

8#

9# Author:

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

11# Alberto Solino (@agsolino)

12#

13# Description:

14# SMTP client for relaying NTLMSSP authentication to mailservers, for example Exchange

15#

16 import smtplib

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 = ["SMTPRelayClient"]

27

28 class SMTPRelayClient(ProtocolClient):

29 PLUGIN_NAME = "SMTP"

30

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

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

33

34 def initConnection(self):

35 self.session = smtplib.SMTP(self.targetHost,self.targetPort)

36 # Turn on to debug SMTP messages

37 # self.session.debuglevel = 3

38 self.session.ehlo()

39

40 if 'AUTH NTLM' not in self.session.ehlo_resp:

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

42 return False

43 return True

44

45 def sendNegotiate(self,negotiateMessage):

46 negotiate = base64.b64encode(negotiateMessage)

47 self.session.putcmd('AUTH NTLM')

48 code, resp = self.session.getreply()

49 if code != 334:

50 LOG.error('SMTP Client error, expected 334 NTLM supported, got %d %s ' % (code, resp))

51 return False

52 else:

53 self.session.putcmd(negotiate)

54 try:

55 code, serverChallengeBase64 = self.session.getreply()

56 serverChallenge = base64.b64decode(serverChallengeBase64)

57 challenge = NTLMAuthChallenge()

58 challenge.fromString(serverChallenge)

59 return challenge

60 except (IndexError, KeyError, AttributeError):

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

62 raise

63

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

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

66 respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)

67 token = respToken2['ResponseToken']

68 else:

69 token = authenticateMessageBlob

70 auth = base64.b64encode(token)

71 self.session.putcmd(auth)

72 typ, data = self.session.getreply()

73 if typ == 235:

74 self.session.state = 'AUTH'

75 return None, STATUS_SUCCESS

76 else:

77 LOG.error('SMTP: %s' % ''.join(data))

78 return None, STATUS_ACCESS_DENIED

79

80 def killConnection(self):

81 if self.session is not None:

82 self.session.close()

83 self.session = None

84

85 def keepAlive(self):

86 # Send a NOOP

87 self.session.noop()