Exemple #1
0
    def test_pretty_xml_handler(self):
        # Test that a normal, non-XML log record is passed through unchanged
        stream = io.StringIO()
        stream.isatty = lambda: True
        h = PrettyXmlHandler(stream=stream)
        self.assertTrue(h.is_tty())
        r = logging.LogRecord(
            name='baz', level=logging.INFO, pathname='/foo/bar', lineno=1, msg='hello', args=(), exc_info=None
        )
        h.emit(r)
        h.stream.seek(0)
        self.assertEqual(h.stream.read(), 'hello\n')

        # Test formatting of an XML record. It should contain newlines and color codes.
        stream = io.StringIO()
        stream.isatty = lambda: True
        h = PrettyXmlHandler(stream=stream)
        r = logging.LogRecord(
            name='baz', level=logging.DEBUG, pathname='/foo/bar', lineno=1, msg='hello %(xml_foo)s',
            args=({'xml_foo': b'<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>'},), exc_info=None)
        h.emit(r)
        h.stream.seek(0)
        self.assertEqual(
            h.stream.read(),
            "hello \x1b[36m<?xml version='1.0' encoding='utf-8'?>\x1b[39;49;00m\n\x1b[94m"
            "<foo\x1b[39;49;00m\x1b[94m>\x1b[39;49;00mbar\x1b[94m</foo>\x1b[39;49;00m\n\n"
        )
    def test_wrap(self):
        # Test payload wrapper with both delegation, impersonation and timezones
        MockTZ = namedtuple('EWSTimeZone', ['ms_id'])
        MockAccount = namedtuple('Account', ['access_type', 'primary_smtp_address', 'default_timezone'])
        content = create_element('AAA')
        api_version = 'BBB'
        account = MockAccount(DELEGATE, '*****@*****.**', MockTZ('XXX'))
        wrapped = wrap(content=content, api_version=api_version, account=account)
        self.assertEqual(
            PrettyXmlHandler.prettify_xml(wrapped),
            b'''<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Header>
    <t:RequestServerVersion Version="BBB"/>
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="XXX"/>
    </t:TimeZoneContext>
  </s:Header>
  <s:Body>
    <AAA/>
  </s:Body>
</s:Envelope>
''')
        account = MockAccount(IMPERSONATION, '*****@*****.**', MockTZ('XXX'))
        wrapped = wrap(content=content, api_version=api_version, account=account)
        self.assertEqual(
            PrettyXmlHandler.prettify_xml(wrapped),
            b'''<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Header>
    <t:RequestServerVersion Version="BBB"/>
    <t:ExchangeImpersonation>
      <t:ConnectingSID>
        <t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
      </t:ConnectingSID>
    </t:ExchangeImpersonation>
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="XXX"/>
    </t:TimeZoneContext>
  </s:Header>
  <s:Body>
    <AAA/>
  </s:Body>
</s:Envelope>
''')
    def test_push_message_responses(self):
        # Test SendNotification
        ws = SendNotification(protocol=None)
        with self.assertRaises(ValueError):
            # Invalid status
            ws.get_payload(status="XXX")
        self.assertEqual(
            PrettyXmlHandler.prettify_xml(ws.ok_payload()),
            b"""\
<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Body>
    <m:SendNotificationResult>
      <m:SubscriptionStatus>OK</m:SubscriptionStatus>
    </m:SendNotificationResult>
  </s:Body>
</s:Envelope>
""",
        )
        self.assertEqual(
            PrettyXmlHandler.prettify_xml(ws.unsubscribe_payload()),
            b"""\
<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Body>
    <m:SendNotificationResult>
      <m:SubscriptionStatus>Unsubscribe</m:SubscriptionStatus>
    </m:SendNotificationResult>
  </s:Body>
</s:Envelope>
""",
        )
Exemple #4
0
def parse_configs() -> Configs:
    """Parse command line arguments and return configs"""
    # process command line args
    args = docopt(__doc__, version='calcatime {}'.format(__version__))

    # extended debug?
    if args.get('--debug'):
        import logging
        from exchangelib.util import PrettyXmlHandler
        logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])

    # determine calendar provider
    calprovider = get_provider(args.get('-c', None))

    # determine credentials
    username = args.get('-u', None)
    password = args.get('-p', None)
    if not username or not password:
        raise Exception('Calendar access credentials are required.')

    # get domain if provided
    domain = args.get('-d', None)

    # determine grouping attribute, set defaults if not provided
    grouping_attr = args.get('--by', None)
    if not grouping_attr:
        if calprovider.supports_categories:
            grouping_attr = 'category'
        else:
            grouping_attr = 'title'

    # determine if zeros need to be included
    include_zero = args.get('--include-zero', False)

    # determine output type, defaults to csv
    json_out = args.get('--json', False)

    # determine requested time span
    start, end = parse_timerange_tokens(args.get('<timespan>', []))

    return Configs(calendar_provider=calprovider,
                   username=username,
                   password=password,
                   range_start=start,
                   range_end=end,
                   domain=domain,
                   grouping_attr=grouping_attr,
                   include_zero=include_zero,
                   output_type='json' if json_out else 'csv')
Exemple #5
0
def gal(dump, search, verbose):
    """
        Dump GAL using EWS.
        The slower technique used by https://github.com/dafthack/MailSniper
        default searches from "aa" to "zz" and prints them all.
        EWS only returns batches of 100
        There will be doubles, so uniq after.
    """

    if verbose:
        logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])

    credentials = Credentials(tbestate.username, tbestate.password)
    username = tbestate.username

    if tbestate.exch_host:
        config = Configuration(server=tbestate.exch_host,
                               credentials=credentials)
        account = Account(username,
                          config=config,
                          autodiscover=False,
                          access_type=DELEGATE)
    else:
        account = Account(username,
                          credentials=credentials,
                          autodiscover=True,
                          access_type=DELEGATE)

    atoz = [
        ''.join(x) for x in itertools.product(string.ascii_lowercase, repeat=2)
    ]

    if search:
        for names in ResolveNames(
                account.protocol).call(unresolved_entries=(search, )):
            click.secho(f'{names}')
    else:
        atoz = [
            ''.join(x)
            for x in itertools.product(string.ascii_lowercase, repeat=2)
        ]
        for entry in atoz:
            for names in ResolveNames(
                    account.protocol).call(unresolved_entries=(entry, )):
                click.secho(f'{names}')

    click.secho(f'-------------------------------------\n', dim=True)
Exemple #6
0
def brute(verbose, userfile, password):
    """
        Do a brute force.
        Made for horrizontal brute forcing mostly.
        Unless an exchange host is provided it will try autodiscover for each.
        Provide an exchange host to be faster.
    """
    if verbose:
        logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])

    if not tbestate.exch_host:
        click.secho(
            f'[*] Set an exchange host for a faster bruting experience',
            fg='yellow')

    usernames = open(userfile, "r")

    for username in usernames:
        username = username.strip()
        # config = Configuration()
        credentials = Credentials(username=username, password=password)
        try:
            if tbestate.exch_host:
                config = Configuration(server=tbestate.exch_host,
                                       credentials=credentials)
                # pylint: disable=unused-variable
                account = Account(username, config=config, autodiscover=False)

            else:
                # pylint: disable=unused-variable
                account = Account(username,
                                  credentials=credentials,
                                  autodiscover=True)
            click.secho(f'[+] Success {username}:{password}', fg='green')
        except exchangelib.errors.UnauthorizedError:
            click.secho(
                f'[-] Failure {username}:{password} - exchangelib.errors.UnauthorizedError',
                dim=True,
                fg='red')
        except exchangelib.errors.TransportError:
            click.secho(
                f'[-] Failure {username}:{password} - exchangelib.errors.TransportError',
                dim=True,
                fg='red')
    click.secho(f'-------------------------------------\n', dim=True)
Exemple #7
0
    def __init__(self):
        # Set Timezone to local Timezone
        self._tz = EWSTimeZone.localzone()

        # set start and end time of Calendarentry
        self.init_time()

        # Logger
        logging.basicConfig(level=logging.WARNING,
                            handlers=[PrettyXmlHandler()])

        # Config Parser
        config = configparser.ConfigParser()
        config.read('config.txt')
        try:
            LoginData = config["Credentials"]
        except KeyError as error:
            print('The key ' + str(error) +
                  ' were not found in the config file')
            exit()

        _Login = {
            "user": LoginData['user'],
            "password": LoginData['password'],
            "Primary_SMTP_Adress": LoginData['Primary SMTP Adress']
        }

        # Credentials and account
        self._credentials = Credentials(username=_Login["user"],
                                        password=_Login["password"])

        # Autodiscover fails w/o mail_config. See issue #337 on github exchangelib
        self._mailConfig = Configuration(server='outlook.office365.com',
                                         credentials=self._credentials)

        self._account = Account(
            default_timezone=self._tz,
            primary_smtp_address=_Login["Primary_SMTP_Adress"],
            config=self._mailConfig,
            credentials=self._credentials,
            autodiscover=False,
            access_type=DELEGATE)

        # Init Database
        self._db = exchange_database.exchange_database()
Exemple #8
0
def oof(user_name: str, pwd: str, account: str, from_addr: str):
    """
    
    Various out of office shenanigans
    
    :param user_name: 
    :param pwd: 
    :param account:
    :param from_addr:
    :return: 
    """
    logging.basicConfig(level=logging.INFO, handlers=[PrettyXmlHandler()])
    creds = Credentials(user_name, pwd)
    config = Configuration(server=account, credentials=creds)
    account = Account(primary_smtp_address=from_addr,
                      autodiscover=False, access_type=DELEGATE, config=config)
    current_settings = account.oof_settings
    print(current_settings)
Exemple #9
0
def cli(config, username, password, dump_config, verbose, user_agent,
        outlook_agent, table_width, exch_host):
    """
        \b
        thumsc-ews for Exchange Web Services
            by @_cablethief from @sensepost of @orangecyberdef
    """
    # logging.basicConfig(level=logging.WARNING)

    if verbose:
        logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])

    BaseProtocol.USERAGENT = "thumbscr-ews/" + \
                             __version__ + " (" + BaseProtocol.USERAGENT + ")"

    if outlook_agent and user_agent:
        click.secho(f'CANNOT USE TWO USERAGENTS AT ONCE!!!', fg='red')
        click.secho(f'Please use only --user-agent or --outlook-agent.',
                    fg='red')
        quit()

    if outlook_agent:
        user_agent = "Microsoft Office/14.0 (Windows NT 6.1; Microsoft Outlook 14.0.7145; Pro)"

    if user_agent:
        BaseProtocol.USERAGENT = user_agent

    # set the mq configuration based on the configuration file
    if config is not None:
        with open(config) as f:
            config_data = yamllib.load(f, Loader=yamllib.FullLoader)
            tbestate.dictionary_updater(config_data)

    # set configuration based on the flags this command got
    tbestate.dictionary_updater(locals())

    # If we should be dumping configuration, do that.
    if dump_config:
        click.secho('Effective configuration for this run:', dim=True)
        click.secho('-------------------------------------', dim=True)
        click.secho(f'Username:               {tbestate.username}', dim=True)
        click.secho(f'Password:               {tbestate.password}', dim=True)
        click.secho(f'User-Agent:             {tbestate.user_agent}', dim=True)
        click.secho('-------------------------------------\n', dim=True)
Exemple #10
0
def autodiscover(verbose):
    """
        Authenticate and go through autodiscover.
    """

    try:
        tbestate.validate(['username', 'password'])
        credentials = Credentials(tbestate.username, tbestate.password)

        if verbose:
            logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])

        primary_address, protocol = discover(tbestate.username, credentials=credentials)

        click.secho(f'Autodiscover results:', bold=True, fg='yellow')
        click.secho(f'{primary_address.user}', fg='bright_green')
        click.secho(f'{protocol}', fg='bright_green')
    except exchangelib.errors.AutoDiscoverFailed:
        click.secho(f'Autodiscover failed, try with -v for more information:', bold=True, fg='red')
Exemple #11
0
def get_exchange_email(from_addr: str, account: str, pwd: str, user_name: str, num_emails: int):
    """

    Gets email with Exchange

    :param from_addr: 
    :param account:
    :param pwd:
    :param user_name:
    :param num_emails:
    :return: 
    """
    logging.basicConfig(level=logging.INFO, handlers=[PrettyXmlHandler()])
    if not num_emails:
        num_emails = 10
    else:
        pass
    creds = Credentials(user_name, pwd)
    config = Configuration(server=account, credentials=creds)
    account = Account(primary_smtp_address=from_addr,
                      autodiscover=True, access_type=DELEGATE, config=config)
    for item in account.inbox.all().order_by('-datetime_received')[:int(num_emails)]:
        print(item.subject, item.sender, item.datetime_received)
Exemple #12
0
def cli():
    parser = ArgumentParser()
    parser.add_argument("-N",
                        "--offset",
                        help="offset day integer.",
                        type=int,
                        default=1)
    parser.add_argument("--date",
                        help="Date formats. (YYYY-MM-DD)",
                        type=valid_date)
    parser.add_argument("-d",
                        "--debug",
                        help="debug mode",
                        action="store_true")
    args = parser.parse_args()
    if args.debug:
        basicConfig(
            format="%(asctime)s:%(name)s:%(levelname)s:%(message)s",
            level=DEBUG,
            handlers=[PrettyXmlHandler()],
        )
    else:
        basicConfig(level=INFO)
    main(date=args.date, n=args.offset)
Exemple #13
0
    def test_wrap(self):
        # Test payload wrapper with both delegation, impersonation and timezones
        MockTZ = namedtuple("EWSTimeZone", ["ms_id"])
        MockAccount = namedtuple(
            "Account", ["access_type", "identity", "default_timezone"])
        content = create_element("AAA")
        api_version = "BBB"
        account = MockAccount(access_type=DELEGATE,
                              identity=None,
                              default_timezone=MockTZ("XXX"))
        wrapped = wrap(content=content,
                       api_version=api_version,
                       timezone=account.default_timezone)
        self.assertEqual(
            PrettyXmlHandler.prettify_xml(wrapped),
            b"""<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Header>
    <t:RequestServerVersion Version="BBB"/>
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="XXX"/>
    </t:TimeZoneContext>
  </s:Header>
  <s:Body>
    <AAA/>
  </s:Body>
</s:Envelope>
""",
        )
        for attr, tag in (
            ("primary_smtp_address", "PrimarySmtpAddress"),
            ("upn", "PrincipalName"),
            ("sid", "SID"),
            ("smtp_address", "SmtpAddress"),
        ):
            val = f"{attr}@example.com"
            account = MockAccount(access_type=DELEGATE,
                                  identity=Identity(**{attr: val}),
                                  default_timezone=MockTZ("XXX"))
            wrapped = wrap(
                content=content,
                api_version=api_version,
                account_to_impersonate=account.identity,
                timezone=account.default_timezone,
            )
            self.assertEqual(
                PrettyXmlHandler.prettify_xml(wrapped),
                f"""<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Header>
    <t:RequestServerVersion Version="BBB"/>
    <t:ExchangeImpersonation>
      <t:ConnectingSID>
        <t:{tag}>{val}</t:{tag}>
      </t:ConnectingSID>
    </t:ExchangeImpersonation>
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="XXX"/>
    </t:TimeZoneContext>
  </s:Header>
  <s:Body>
    <AAA/>
  </s:Body>
</s:Envelope>
""".encode(),
            )
Exemple #14
0
import logging
import os
import random
import unittest.util
from unittest import TestLoader, TestSuite

from exchangelib.util import PrettyXmlHandler


class RandomTestSuite(TestSuite):
    def __iter__(self):
        tests = list(super().__iter__())
        random.shuffle(tests)
        return iter(tests)


# Execute test classes in random order
TestLoader.suiteClass = RandomTestSuite
# Execute test methods in random order within each test class
TestLoader.sortTestMethodsUsing = lambda _, x, y: random.choice((1, -1))
# Make sure we're also random in multiprocess test runners
random.seed()

# Always show full repr() output for object instances in unittest error messages
unittest.util._MAX_LENGTH = 2000

if os.environ.get("DEBUG", "").lower() in ("1", "yes", "true"):
    logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])
else:
    logging.basicConfig(level=logging.CRITICAL)
Exemple #15
0
def delegatecheck(email_list, verbose, full_tree, folder):
    """
        Check if the current user has access to the provided mailboxes
        By default will check if access to inbox or not. Can check for other access with --full-tree
    """

    if verbose:
        logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])

    credentials = Credentials(tbestate.username, tbestate.password)

    if tbestate.exch_host:
        config = Configuration(server=tbestate.exch_host,
                               credentials=credentials)
        account = Account(tbestate.username, config=config, autodiscover=False)
    else:
        account = Account(tbestate.username,
                          credentials=credentials,
                          autodiscover=True)

    ews_url = account.protocol.service_endpoint
    ews_auth_type = account.protocol.auth_type
    # primary_smtp_address = account.primary_smtp_address
    # This one is optional. It is used as a hint to the initial connection and avoids one or more roundtrips
    # to guess the correct Exchange server version.
    version = account.version

    config = Configuration(service_endpoint=ews_url,
                           credentials=credentials,
                           auth_type=ews_auth_type,
                           version=version)

    emails = open(email_list, "r")

    for email in emails:
        email = email.strip()
        try:
            delegate_account = Account(primary_smtp_address=email,
                                       config=config,
                                       autodiscover=False,
                                       access_type=DELEGATE)
            # We could also print the full file structure, but you get all the public folders for users.
            if full_tree:
                # pylint: disable=maybe-no-member
                click.secho(
                    f'[+] Success {email} - Access to some folders.\n{delegate_account.root.tree()}',
                    fg='green')
            elif folder:
                folders = delegate_account.root.glob(folder)
                if len(folders.folders) == 0:
                    click.secho(f'[-] Failure {email} - No folder found',
                                dim=True,
                                fg='red')
                else:
                    for current_folder in delegate_account.root.glob(folder):
                        pl = []
                        for p in current_folder.permission_set.permissions:
                            if p.permission_level != "None":
                                pl.append(p.permission_level)
                        click.secho(
                            f'[+] Success {email} - Could access {current_folder} - Permissions: {pl}',
                            fg='green')
            else:
                #delegate_account.inbox
                pl = []
                for p in delegate_account.inbox.permission_set.permissions:
                    if p.permission_level != "None":
                        pl.append(p.permission_level)
                click.secho(
                    f'[+] Success {email} - Could access inbox - Permissions: {pl}',
                    fg='green')
        except exchangelib.errors.ErrorItemNotFound:
            click.secho(f'[-] {email} - Failure inbox not accessible',
                        dim=True,
                        fg='red')
        except exchangelib.errors.AutoDiscoverFailed:
            click.secho(f'[-] {email} - Failure AutoDiscoverFailed',
                        dim=True,
                        fg='red')
        except exchangelib.errors.ErrorNonExistentMailbox:
            click.secho(f'[-] {email} - Failure ErrorNonExistentMailbox',
                        dim=True,
                        fg='red')
        except exchangelib.errors.ErrorAccessDenied:
            click.secho(f'[-] {email} - Failure ErrorAccessDenied',
                        dim=True,
                        fg='red')
        except exchangelib.errors.ErrorImpersonateUserDenied:
            click.secho(f'[-] {email} - Failure ErrorImpersonateUserDenied',
                        dim=True,
                        fg='red')

    click.secho(f'-------------------------------------\n', dim=True)
Exemple #16
0
    def test_wrap(self):
        # Test payload wrapper with both delegation, impersonation and timezones
        MockTZ = namedtuple('EWSTimeZone', ['ms_id'])
        MockAccount = namedtuple(
            'Account', ['access_type', 'identity', 'default_timezone'])
        content = create_element('AAA')
        api_version = 'BBB'
        account = MockAccount(access_type=DELEGATE,
                              identity=None,
                              default_timezone=MockTZ('XXX'))
        wrapped = wrap(content=content,
                       api_version=api_version,
                       timezone=account.default_timezone)
        self.assertEqual(
            PrettyXmlHandler.prettify_xml(wrapped),
            b'''<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Header>
    <t:RequestServerVersion Version="BBB"/>
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="XXX"/>
    </t:TimeZoneContext>
  </s:Header>
  <s:Body>
    <AAA/>
  </s:Body>
</s:Envelope>
''')
        for attr, tag in (
            ('primary_smtp_address', 'PrimarySmtpAddress'),
            ('upn', 'PrincipalName'),
            ('sid', 'SID'),
            ('smtp_address', 'SmtpAddress'),
        ):
            val = '*****@*****.**' % attr
            account = MockAccount(access_type=DELEGATE,
                                  identity=Identity(**{attr: val}),
                                  default_timezone=MockTZ('XXX'))
            wrapped = wrap(
                content=content,
                api_version=api_version,
                account_to_impersonate=account.identity,
                timezone=account.default_timezone,
            )
            self.assertEqual(
                PrettyXmlHandler.prettify_xml(wrapped),
                '''<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <s:Header>
    <t:RequestServerVersion Version="BBB"/>
    <t:ExchangeImpersonation>
      <t:ConnectingSID>
        <t:{tag}>{val}</t:{tag}>
      </t:ConnectingSID>
    </t:ExchangeImpersonation>
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="XXX"/>
    </t:TimeZoneContext>
  </s:Header>
  <s:Body>
    <AAA/>
  </s:Body>
</s:Envelope>
'''.format(tag=tag, val=val).encode())
Exemple #17
0
def gal(dump, search, verbose, full, output):
    """
        Dump GAL using EWS.
        The slower technique used by https://github.com/dafthack/MailSniper
        default searches from "aa" to "zz" and prints them all.
        EWS only returns batches of 100
        There will be doubles, so uniq after.
    """

    if verbose:
        logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])

    credentials = Credentials(tbestate.username, tbestate.password)
    username = tbestate.username

    try:
        if tbestate.exch_host:
            config = Configuration(server=tbestate.exch_host, credentials=credentials)
            account = Account(username, config=config, autodiscover=False, access_type=DELEGATE)
        else:
            account = Account(username, credentials=credentials, autodiscover=True, access_type=DELEGATE)

    except exchangelib.errors.ErrorNonExistentMailbox as neb:
        print(f'[!] Mailbox does not exist for user: {username}')
        exit()
    except exchangelib.errors.UnauthorizedError as err:
        print(f'[!] Invalid credentials for user: {username}')
        exit()
    except exchangelib.errors.TransportError:
        print(f'[!] Can not reach target Exchange server: {tbestate.exch_host}')
        exit()
    except Exception as err:
        print(f'[!] Something went wrong: {err}')


    atoz = [''.join(x) for x in itertools.product(string.ascii_lowercase, repeat=2)]

    if search:
        for names in ResolveNames(account.protocol).call(unresolved_entries=(search,)):
            if output:
                click.secho(f'{names}')
                output.write(f'{names}\n')
            else:
                click.secho(f'{names}')

    elif full:
        atoz = [''.join(x) for x in itertools.product(string.ascii_lowercase, repeat=2)]
        for entry in atoz:
            for names in ResolveNames(account.protocol).call(unresolved_entries=(entry,)):
                stringed = str(names)
                found = re.findall(r'[\w.+-]+@[\w-]+\.[\w.-]+', stringed)
                for i in found:
                    if output:
                        click.secho(f'{i}')
                        output.write(f'{i}\n')
                    else:
                        click.secho(f'{i}')
    else:
        atoz = [''.join(x) for x in itertools.product(string.ascii_lowercase, repeat=2)]
        for entry in atoz:
            for names in ResolveNames(account.protocol).call(unresolved_entries=(entry,)):
                if output:
                    click.secho(f'{names}')
                    output.write(f'{names}\n')
                else:
                    click.secho(f'{names}')


    click.secho(f'-------------------------------------\n', dim=True)