Azure AD Connect Health Feed

Use the Microsoft Azure AD Connect Health Feed integration to get indicators from the feed.

Data Enrichment & Threat Intelligence · Microsoft Azure AD Connect Health Feed · Feed

Details

IDAzure AD Connect Health Feed
ProviderMicrosoft
CategoryData Enrichment & Threat Intelligence
From Version5.5.0
Docker Imagedemisto/btfl-soup:1.0.1.10120494
Supported ModulesAgentix XSIAM

README

Use the Microsoft Azure AD Connect Health Feed integration to get indicators from the feed.
This integration was integrated and tested with version 1 of Azure AD Connect Health Feed

Configure Azure AD Connect Health Feed in Cortex

Parameter Description Required        
feed Fetch indicators False        
feedReputation Indicator Reputation False        
feedReliability Source Reliability True        
tlp_color The Traffic Light Protocol (TLP) designation to apply to indicators fetched from the feed. More information about the protocol can be found at https://us-cert.cisa.gov/tlp False   feedExpirationPolicy   False
feedExpirationInterval   False        
feedFetchInterval Feed Fetch Interval False        
url The Microsoft Azure endpoint URL True        
feedTags Tags False        
feedBypassExclusionList Bypass exclusion list False        
insecure Trust any certificate (not secure) False        
proxy Use system proxy settings False        

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

azure-ad-health-get-indicators


Gets indicators from the feed.

Base Command

azure-ad-health-get-indicators

Input

Argument Name Description Required
limit The maximum number of results to return. The default value is 10. Optional

Context Output

There is no context output for this command.

Command Example


#### Context Example

{}
```

Human Readable Output

Indicators from Microsoft Azure Feed

value type
https://login.microsoftonline.com URL
https://secure.aadcdn.microsoftonline-p.com URL
https://login.windows.net URL

Configuration parameters

  • feed — Fetch indicators
  • feedReputation — Indicator Reputation
  • feedReliability — Source Reliability (required)
  • tlp_color — Traffic Light Protocol Color
  • feedExpirationPolicy
  • feedExpirationInterval
  • feedFetchInterval — Feed Fetch Interval
  • url — The Microsoft Azure endpoint URL (required)
  • feedTags — Tags
  • feedBypassExclusionList — Bypass exclusion list
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (1)

  • azure-ad-health-get-indicators

    Gets indicators from the feed.

import demistomock as demisto
from CommonServerPython import *

from typing import Any
from collections.abc import Callable

import urllib3
from bs4 import BeautifulSoup
import re

# disable insecure warnings
urllib3.disable_warnings()

INTEGRATION_NAME = "Microsoft Azure AD Connect Health Feed"
PATTERN = re.compile(r"(https?:/{2}|\*\*\.|\*\.)([\w-]+\.)+\w{2,3}")  # guardrails-disable-line


class Client(BaseClient):
    """
    Client to use in the Microsoft Azure Feed integration. Overrides BaseClient.
    """

    def __init__(self, base_url: str, verify: bool = False, proxy: bool = False):
        """
        Implements class for Microsoft Azure feeds.
        :param url: the Azure endpoint URL
        :verify: boolean, if *false* feed HTTPS server certificate is verified. Default: *false*
        :param proxy: boolean, if *false* feed HTTPS server certificate will not use proxies. Default: *false*
        """
        super().__init__(base_url, verify=verify, proxy=proxy)

    def build_iterator(self) -> list:
        """Retrieves all entries from the feed.
        Returns:
            A list of objects, containing the indicators.
        """
        result = []
        r = self._http_request("GET", url_suffix="", full_url=self._base_url, resp_type="text")

        soup = BeautifulSoup(r, "html.parser")

        global PATTERN
        scraped_indicators = list(  # type: ignore # noqa
            {
                PATTERN.match(cell.text).group(0)  # type: ignore # noqa
                for cell in soup.select(  # type: ignore # noqa
                    "tbody tr td code"
                )
                if PATTERN.match(cell.text)
            }
        )
        for indicator in scraped_indicators:
            result.append(
                {
                    "value": indicator,
                    "type": FeedIndicatorType.DomainGlob if "*" in indicator else FeedIndicatorType.URL,
                    "FeedURL": self._base_url,
                }
            )

        return result


def test_module(client: Client, *_) -> tuple[str, dict[Any, Any], dict[Any, Any]]:
    """Builds the iterator to check that the feed is accessible.
    Args:
        client: Client object.
    Returns:
        Outputs.
    """
    client.build_iterator()
    return "ok", {}, {}


def fetch_indicators(client: Client, feed_tags: list = [], tlp_color: str | None = "", limit: int = -1) -> list[dict]:
    """Retrieves indicators from the feed
    Args:
        client (Client): Client object with request
        feed_tags (list): tags to assign fetched indicators
        tlp_color (str): Traffic Light Protocol color
        limit (int): limit the results
    Returns:
        Indicators.
    """
    iterator = client.build_iterator()
    indicators = []
    if limit > 0:
        iterator = iterator[:limit]
    for item in iterator:
        value = item.get("value")
        type_ = item.get("type", FeedIndicatorType.Domain)
        raw_data = {
            "value": value,
            "type": type_,
        }
        for key, val in item.items():
            raw_data.update({key: val})
        indicator_obj = {
            "value": value,
            "type": type_,
            "service": "Azure AD Connect Health Feed",
            "rawJSON": raw_data,
            "fields": {},
        }
        if feed_tags:
            indicator_obj["fields"]["tags"] = feed_tags
        if tlp_color:
            indicator_obj["fields"]["trafficlightprotocol"] = feed_tags

        indicators.append(indicator_obj)
    return indicators


def get_indicators_command(
    client: Client, params: dict[str, str], args: dict[str, str]
) -> tuple[str, dict[Any, Any], dict[Any, Any]]:
    """Wrapper for retrieving indicators from the feed to the war-room.
    Args:
        client: Client object with request
        params: demisto.params()
        args: demisto.args()
    Returns:
        Outputs.
    """
    feed_tags = argToList(params.get("feedTags", ""))
    tlp_color = demisto.params().get("tlp_color")
    limit = int(args.get("limit", "10"))
    indicators = fetch_indicators(client, feed_tags, tlp_color, limit)
    human_readable = tableToMarkdown(
        "Indicators from Microsoft Azure Feed:", indicators, headers=["value", "type"], removeNull=True
    )

    return human_readable, {}, {"raw_response": indicators}


def fetch_indicators_command(client: Client, params: dict[str, str]) -> list[dict]:
    """Wrapper for fetching indicators from the feed to the Indicators tab.
    Args:
        client: Client object with request
        params: demisto.params()
    Returns:
        Indicators.
    """
    feed_tags = argToList(params.get("feedTags", ""))
    tlp_color = demisto.params().get("tlp_color")
    indicators = fetch_indicators(client, feed_tags, tlp_color)
    return indicators


def main():
    """
    PARSE AND VALIDATE INTEGRATION PARAMS
    """
    params = demisto.params()
    base_url = params.get("url")
    insecure = not params.get("insecure", False)
    proxy = params.get("proxy", False)

    command = demisto.command()
    demisto.info(f"Command being called in {INTEGRATION_NAME} is {command}")

    try:
        client = Client(
            base_url=base_url,
            verify=insecure,
            proxy=proxy,
        )

        commands: dict[str, Callable[[Client, dict[str, str], dict[str, str]], tuple[str, dict[Any, Any], dict[Any, Any]]]] = {
            "test-module": test_module,
            "azure-ad-health-get-indicators": get_indicators_command,
        }
        if command in commands:
            return_outputs(*commands[command](client, demisto.params(), demisto.args()))

        elif command == "fetch-indicators":
            indicators = fetch_indicators_command(client, demisto.params())
            for iter_ in batch(indicators, batch_size=2000):
                demisto.createIndicators(iter_)

        else:
            raise NotImplementedError(f"Command {command} is not implemented.")

    except Exception as err:
        err_msg = f"Error in {INTEGRATION_NAME} Integration. [{err}]"
        return_error(err_msg)


if __name__ in ["__main__", "builtin", "builtins"]:
    main()