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

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

12#

13# Author:

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

15# Alberto Solino (@agsolino)

16#

17 import smtplib

18 import base64

19 from struct import unpack

20

21 from impacket import LOG

22 from impacket.examples.ntlmrelayx.clients import ProtocolClient

23 from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED

24 from impacket.ntlm import NTLMAuthChallenge

25 from impacket.spnego import SPNEGO_NegTokenResp

26

27 PROTOCOL_CLIENT_CLASSES = ["SMTPRelayClient"]

28

29 class SMTPRelayClient(ProtocolClient):

30 PLUGIN_NAME = "SMTP"

31

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

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

34

35 def initConnection(self):

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

37 # Turn on to debug SMTP messages

38 # self.session.debuglevel = 3

39 self.session.ehlo()

40

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

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

43 return False

44 return True

45

46 def sendNegotiate(self,negotiateMessage):

47 negotiate = base64.b64encode(negotiateMessage)

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

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

50 if code != 334:

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

52 return False

53 else:

54 self.session.putcmd(negotiate)

55 try:

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

57 serverChallenge = base64.b64decode(serverChallengeBase64)

58 challenge = NTLMAuthChallenge()

59 challenge.fromString(serverChallenge)

60 return challenge

61 except (IndexError, KeyError, AttributeError):

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

63 raise

64

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

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

67 respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)

68 token = respToken2['ResponseToken']

69 else:

70 token = authenticateMessageBlob

71 auth = base64.b64encode(token)

72 self.session.putcmd(auth)

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

74 if typ == 235:

75 self.session.state = 'AUTH'

76 return None, STATUS_SUCCESS

77 else:

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

79 return None, STATUS_ACCESS_DENIED

80

81 def killConnection(self):

82 if self.session is not None:

83 self.session.close()

84 self.session = None

85

86 def keepAlive(self):

87 # Send a NOOP

88 self.session.noop()