{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# MSTICPy Pivot Functions\n", "\n", "## What are Pivot Functions?\n", "\n", "MSTICPy has a lot of functionality distributed across many classes and modules. \n", "However, there is no simple way to discover where these functions are and what types\n", "of data the function is relevant to.\n", "\n", "Pivot functions bring this functionality together grouped around Entities.\n", "\n", "Entities are representations real-world objects found commonly in CyberSec investigations.\n", "Some examples are:\n", "\n", "- IP Address\n", "- Host\n", "- Account\n", "- URL\n", "\n", "MSTICPy has had entity classes from the very early days but, until now, these\n", "have only been used sporadically in the rest of the package.\n", "\n", "The pivot functionality exposed operations relevant to a particular\n", "entity as methods of that entity. These operations could include:\n", "\n", "- Data queries\n", "- Threat intelligence lookups\n", "- Other data lookups such as GeoLocation or domain resolution\n", "- and other local functionality\n", "\n", "## What is Pivoting?\n", "\n", "The name comes from the common practice of Cyber investigators navigating\n", "between related entities. For example an entity/investigation chain might\n", "look like the following:\n", "\n", "\n", "| Step | Source | Operation | Target |\n", "| :--: | :----------------- | :----------------- | :----------------- |\n", "| 1 | Alert | Review alert -> | Source IP(A) |\n", "| 2 | Source IP(A) | Lookup TI -> | Related URLs |\n", "| | | | Malware names |\n", "| 3 | URL | Query web logs -> | Requesting hosts |\n", "| 4 | Host | Query host logons -> | Accounts |\n", "\n", "\n", "At each step there are one or more directions that you can take to\n", "follow the chain of related indicators of activity in a possible attack.\n", "\n", "Bringing these functions into a few, well-known locations makes it easier to\n", "use MSTICPy to carry out this common pivoting pattern in Jupyter notebooks." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Getting started" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Processing imports....\n", "Checking configuration....\n", "No errors found.\n", "No warnings found.\n", "Setting notebook options....\n" ] }, { "data": { "text/html": [ "

Notebook setup complete

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from msticpy.nbtools.nbinit import init_notebook\n", "init_notebook(namespace=globals());" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The pivoting library depends on a number of data providers used in MSTICPy.\n", "These normally need to be loaded an initialized before starting the Pivot library.\n", "\n", "This is mandatory for data query providers such as the AzureSentinel, Splunk or \n", "MDE data providers. These usually need initialization and authentication steps\n", "to load query definitions and connect to the service. \n", "\n", "> Note: you do not have to authenticate to the data provider before loading Pivot.
\n", "> However, some providers are populated with additional queries only after connecting
\n", "> to the service. These will not be added to the pivot functions unless you\n", "> create a new Pivot object.\n", "\n", "This is optional with providers such as Threat Intelligence (TILookup) and GeoIP.\n", "If you do not initialize these before starting Pivot they will be loaded with\n", "the defaults as specified in your *msticpyconfig.yaml*. If you want to use a \n", "specific configuration for any of these, you should load and configure them \n", "before starting Pivot." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load one or more data providers" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please wait. Loading Kqlmagic extension...\n" ] }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.reconnect();} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "az_provider = QueryProvider(\"AzureSentinel\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initialize the Pivot library\n", "\n", "You can either pass an explicit list of providers to Pivot or let it look for them in\n", "the notebook global namespace. In the latter case, the Pivot class will use the\n", "most recently-created instance of each that it finds.\n", "\n", "#### What happens at initialization?\n", "\n", "- Any instantiated data providers are searched for relevant queries. Any queries found are added to the approriate entity or entities.\n", "- TI provider is loaded and entity-specific lookups (e.g. IP, Url, File) are added as pivot functions\n", "- Miscellaneous Msticpy functions and classes (e.g. GeoIP, IpType, Domain utils) are added as pivot functions to the appropriate entity.\n", "\n", "You can add additional functions as pivot functions by creating a registration template and importing the function.\n", "Details of this are covered later in the document." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pivot function list\n", "\n", "Because we haven't yet loaded the Pivot library nothing is listed." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "entities.Host.get_pivot_list()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Initializing the Pivot library\n", "\n", "You will usually see some output as provider libraries are loaded." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using Open PageRank. See https://www.domcop.com/openpagerank/what-is-openpagerank\n" ] }, { "data": { "text/html": [ "\n", "This product includes GeoLite2 data created by MaxMind, available from\n", "https://www.maxmind.com.\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "This library uses services provided by ipstack.\n", "https://ipstack.com" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from msticpy.datamodel.pivot import Pivot\n", "Pivot(namespace=globals())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> Note: Although you can assign the created Pivot object to a variable you normally don't need to do so.
\n", "> You can access the current Pivot instance using the class attribute `Pivot.current`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### See the list of providers loaded by the Pivot class\n", "\n", "Notice that TILookup was loaded even though we did not create an instance of TILookup beforehand." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'AzureSentinel': ,\n", " 'TILookup': }" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Pivot.current.providers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### After loading the Pivot class, entities have pivot functions added to them" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Host pivot functions\n", "\n" ] }, { "data": { "text/plain": [ "['AzureSentinel.list_related_alerts',\n", " 'AzureSentinel.az_net_analytics',\n", " 'AzureSentinel.get_info_by_hostname',\n", " 'AzureSentinel.auditd_all',\n", " 'AzureSentinel.sudo_activity',\n", " 'AzureSentinel.cron_activity',\n", " 'AzureSentinel.user_group_activity',\n", " 'AzureSentinel.all_syslog',\n", " 'AzureSentinel.squid_activity',\n", " 'AzureSentinel.user_logon',\n", " 'AzureSentinel.list_logons_for_host',\n", " 'AzureSentinel.list_host_logon_failures',\n", " 'AzureSentinel.get_ips_for_host',\n", " 'AzureSentinel.get_heartbeat_for_host',\n", " 'AzureSentinel.list_azure_network_flows_by_host',\n", " 'AzureSentinel.list_host_events',\n", " 'AzureSentinel.list_host_events_by_id',\n", " 'AzureSentinel.list_other_events',\n", " 'AzureSentinel.get_host_logon',\n", " 'AzureSentinel.list_host_logons',\n", " 'AzureSentinel.list_all_logons_by_host',\n", " 'AzureSentinel.list_host_processes',\n", " 'AzureSentinel.get_process_tree',\n", " 'AzureSentinel.get_parent_process',\n", " 'AzureSentinel.list_processes_in_session',\n", " 'util.dns_validate_tld',\n", " 'util.dns_is_resolvable',\n", " 'util.dns_in_abuse_list']" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "IpAddress pivot functions\n", "\n" ] }, { "data": { "text/plain": [ "['AzureSentinel.list_alerts_for_ip',\n", " 'AzureSentinel.list_aad_signins_for_ip',\n", " 'AzureSentinel.list_azure_activity_for_ip',\n", " 'AzureSentinel.list_azure_network_flows_by_ip',\n", " 'AzureSentinel.list_activity_for_ip',\n", " 'AzureSentinel.get_info_by_ipaddress',\n", " 'AzureSentinel.list_logons_for_source_ip',\n", " 'AzureSentinel.get_host_for_ip',\n", " 'AzureSentinel.get_heartbeat_for_ip',\n", " 'AzureSentinel.list_indicators',\n", " 'AzureSentinel.list_indicators_by_ip',\n", " 'AzureSentinel.list_indicators_by_hash',\n", " 'AzureSentinel.list_indicators_by_filepath',\n", " 'AzureSentinel.list_indicators_by_domain',\n", " 'AzureSentinel.list_indicators_by_email',\n", " 'AzureSentinel.list_indicators_by_url',\n", " 'ti.lookup_ip',\n", " 'ti.lookup_ipv4',\n", " 'ti.lookup_ipv4_OTX',\n", " 'ti.lookup_ipv4_Tor',\n", " 'ti.lookup_ipv4_VirusTotal',\n", " 'ti.lookup_ipv4_XForce',\n", " 'ti.lookup_ipv6',\n", " 'ti.lookup_ipv6_OTX',\n", " 'util.whois',\n", " 'util.ip_type',\n", " 'util.geoloc_mm',\n", " 'util.geoloc_ips']" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print(\"Host pivot functions\\n\")\n", "display(entities.Host.get_pivot_list())\n", "print(\"\\nIpAddress pivot functions\\n\")\n", "display(entities.IpAddress.get_pivot_list())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pivot functions are grouped into containers\n", "\n", "Data queries are grouped into a container with the name of the data provider to which they belong.\n", "E.g. AzureSentinel queries are in a container of that name, Spunk queries would be in a \"Splunk\" container.\n", "\n", "TI lookups are put into a \"ti\" container\n", "\n", "All other built-in functions are added to the \"other\" container.\n", "\n", "The containers themselves are callable and will return a list of their contents. \n", "Containers are also iterable - each iteration returns a tuple (pair) of name/function values.\n", "\n", "In notebooks/IPython you can also use tab completion to get to the right function." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "list_related_alerts function\n", "az_net_analytics function\n", "get_info_by_hostname function\n", "auditd_all function\n", "sudo_activity function\n", "cron_activity function\n", "user_group_activity function\n", "all_syslog function\n", "squid_activity function\n", "user_logon function\n", "list_logons_for_host function\n", "list_host_logon_failures function\n", "get_ips_for_host function\n", "get_heartbeat_for_host function\n", "list_azure_network_flows_by_host function\n", "list_host_events function\n", "list_host_events_by_id function\n", "list_other_events function\n", "get_host_logon function\n", "list_host_logons function\n", "list_all_logons_by_host function\n", "list_host_processes function\n", "get_process_tree function\n", "get_parent_process function\n", "list_processes_in_session function\n" ] } ], "source": [ "entities.Host.AzureSentinel()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['user_logon',\n", " 'list_logons_for_host',\n", " 'list_host_logon_failures',\n", " 'get_host_logon',\n", " 'list_host_logons',\n", " 'list_all_logons_by_host']" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[query for query, _ in entities.Host.AzureSentinel if \"logon\" in query]" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "msticpy.datamodel.entities.host.Host" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "entities.Host" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Running a pivot function\n", "\n", "Pivot functions have flexible input types. They can be used with the following types of parameters:\n", "\n", "- entity instances (e.g. where you have an IpAddress entity with a populated address field)\n", "- single values (e.g. a DNS domain name)\n", "- lists of values (e.g. a list of IpAddresses)\n", "- pandas DataFrames (where one or more of the columns contains the input parameter data)\n", "\n", "Pivot functions normally return results as a dataframe (although some complex functions such as Notebooklets\n", "can return composite results objects containing multiple dataframes and other object types.\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "from msticpy.datamodel.entities import IpAddress, Host, Url, Account" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "List 'other' pivot functions for IpAddress\n", "\n", "whois function\n", "ip_type function\n", "geoloc_mm function\n", "geoloc_ips function\n", "\n", "-------------------------------\n", "\n", "Print help for a function - IpAddress.util.type\n", "\n" ] }, { "data": { "text/plain": [ "\u001b[1;31mSignature:\u001b[0m \u001b[0mIpAddress\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutil\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mip_type\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mip\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mip_str\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mDocstring:\u001b[0m\n", "Validate value is an IP address and deteremine IPType category.\n", "\n", "(IPAddress category is e.g. Private/Public/Multicast).\n", "\n", "Parameters\n", "----------\n", "ip_str : str\n", " The string of the IP Address\n", "\n", "Returns\n", "-------\n", "str\n", " Returns ip type string using ip address module\n", "\u001b[1;31mFile:\u001b[0m e:\\src\\microsoft\\msticpy\\msticpy\\sectools\\ip_utils.py\n", "\u001b[1;31mType:\u001b[0m function\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print(\"List 'other' pivot functions for IpAddress\\n\")\n", "IpAddress.util()\n", "print()\n", "print(\"-------------------------------\\n\")\n", "print(\"Print help for a function - IpAddress.util.type\\n\")\n", "IpAddress.util.ip_type?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Parameter names\n", "- Positional parameter - If the function only accepts one parameter you can usually just supply it without a name - as a positional parameter (see first and third examples below)\n", "- Native parameter - You can also use the native parameter name - i.e. the name that the underlying function expects and that will be shown in the help(function) output\n", "- Generic parameter - You can also use the generic parameter name \"value\" in most cases.\n", "\n", "If in doubt, use help(entity.container.func) or entity.container.func?" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
010.1.1.1Private
\n", "
" ], "text/plain": [ " ip result\n", "0 10.1.1.1 Private" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IpAddress.util.ip_type(\"10.1.1.1\")" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
010.1.1.1Private
\n", "
" ], "text/plain": [ " ip result\n", "0 10.1.1.1 Private" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
0157.53.1.1Public
\n", "
" ], "text/plain": [ " ip result\n", "0 157.53.1.1 Public" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
asnasn_cidrasn_country_codeasn_dateasn_descriptionasn_registrynetsnirqueryrawraw_referralreferral
0NANAUS2015-04-01NAarin[{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '...None157.53.1.1NoneNoneNone
\n", "
" ], "text/plain": [ " asn asn_cidr asn_country_code asn_date asn_description asn_registry \\\n", "0 NA NA US 2015-04-01 NA arin \n", "\n", " nets \\\n", "0 [{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '... \n", "\n", " nir query raw raw_referral referral \n", "0 None 157.53.1.1 None None None " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CountryCodeCountryNameStateCityLongitudeLatitudeAsnedgesTypeAdditionalDataIpAddress
0USUnited StatesNoneNone-97.82237.751None{}geolocation{}157.53.1.1
\n", "
" ], "text/plain": [ " CountryCode CountryName State City Longitude Latitude Asn edges \\\n", "0 US United States None None -97.822 37.751 None {} \n", "\n", " Type AdditionalData IpAddress \n", "0 geolocation {} 157.53.1.1 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(IpAddress.util.ip_type(\"10.1.1.1\"))\n", "display(IpAddress.util.ip_type(ip_str=\"157.53.1.1\"))\n", "display(IpAddress.util.whois(\"157.53.1.1\"))\n", "display(IpAddress.util.geoloc_mm(value=\"157.53.1.1\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using an entity as a parameter\n", "\n", "Behind the scenes the Pivot api is using a mapping of\n", "entity attributes to supply the right value to the function parameter." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
010.1.1.1Private
\n", "
" ], "text/plain": [ " ip result\n", "0 10.1.1.1 Private" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
0157.53.1.1Public
\n", "
" ], "text/plain": [ " ip result\n", "0 157.53.1.1 Public" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
asnasn_cidrasn_country_codeasn_dateasn_descriptionasn_registrynetsnirqueryrawraw_referralreferral
0NANAUS2015-04-01NAarin[{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '...None157.53.1.1NoneNoneNone
\n", "
" ], "text/plain": [ " asn asn_cidr asn_country_code asn_date asn_description asn_registry \\\n", "0 NA NA US 2015-04-01 NA arin \n", "\n", " nets \\\n", "0 [{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '... \n", "\n", " nir query raw raw_referral referral \n", "0 None 157.53.1.1 None None None " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CountryCodeCountryNameStateCityLongitudeLatitudeAsnedgesTypeAdditionalDataIpAddress
0USUnited StatesNoneNone-97.82237.751None{}geolocation{}157.53.1.1
\n", "
" ], "text/plain": [ " CountryCode CountryName State City Longitude Latitude Asn edges \\\n", "0 US United States None None -97.822 37.751 None {} \n", "\n", " Type AdditionalData IpAddress \n", "0 geolocation {} 157.53.1.1 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ip1 = IpAddress(Address=\"10.1.1.1\")\n", "ip2 = IpAddress(Address=\"157.53.1.1\")\n", "\n", "display(IpAddress.util.ip_type(ip1))\n", "display(IpAddress.util.ip_type(ip2))\n", "display(IpAddress.util.whois(ip2))\n", "display(IpAddress.util.geoloc_mm(ip2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using a list (or other iterable) as a parameter\n", "\n", "Many of the underlying functions will accept either single values or collections \n", "(usually in DataFrames) of values as input.\n", "Even in cases where the underlying function does not accept iterables as parameters, the\n", "Pivot library will usually be able to iterate through each value and collate the results\n", "to hand you back a single dataframe.\n", "\n", "> Note: there are some exceptions to this - usually where the underlying function
\n", "> is long-running or expensive and has opted not to accept iterated calls.
\n", "> Notebooklets are an example of these.
\n", "\n", "Where the function has multiple parameters you can supply a mixture of iterables and single values.\n", "\n", "- In this case, the single-valued parameters are re-used on each call, paired with the item\n", " in the list(s) taken from the multi-valued parameters\n", " \n", "You can also use multiple iterables for multiple parameters.\n", "- In this case the iterables *should* be the same length. \n", " If they are different lengths the iterations stop after the shorted list/iterable is exhausted.\n", " \n", "For example:\n", "```\n", " list_1 = [1, 2, 3, 4]\n", " list_2 = [\"a\", \"b\", \"c\"]\n", " entity.util.func(p1=list_1, p2=list_2)\n", "```\n", "\n", "The function will execute with the pairings (1, \"a\"), (2, \"b\") and (3, \"c) - (4, \\_) will be ignored" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "

Use our magic function to convert pasted-in list to dataframe

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from msticpy.datamodel import txt_df_magic\n", "md(\"Use our magic function to convert pasted-in list to dataframe\")" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AllExtIPs
9172.217.15.99
1040.85.232.64
1120.38.98.100
1223.96.64.84
1365.55.44.108
14131.107.147.209
1510.0.3.4
1610.0.3.5
1713.82.152.48
\n", "
" ], "text/plain": [ " AllExtIPs\n", "9 172.217.15.99\n", "10 40.85.232.64\n", "11 20.38.98.100\n", "12 23.96.64.84\n", "13 65.55.44.108\n", "14 131.107.147.209\n", "15 10.0.3.4\n", "16 10.0.3.5\n", "17 13.82.152.48" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%txt2df --headers --name ip_df1\n", "AllExtIPs\n", "9, 172.217.15.99\n", "10, 40.85.232.64\n", "11, 20.38.98.100\n", "12, 23.96.64.84\n", "13, 65.55.44.108\n", "14, 131.107.147.209\n", "15, 10.0.3.4\n", "16, 10.0.3.5\n", "17, 13.82.152.48" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
023.96.64.84Public
165.55.44.108Public
2131.107.147.209Public
310.0.3.4Private
410.0.3.5Private
513.82.152.48Public
\n", "
" ], "text/plain": [ " ip result\n", "0 23.96.64.84 Public\n", "1 65.55.44.108 Public\n", "2 131.107.147.209 Public\n", "3 10.0.3.4 Private\n", "4 10.0.3.5 Private\n", "5 13.82.152.48 Public" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
023.96.64.84Public
165.55.44.108Public
2131.107.147.209Public
310.0.3.4Private
410.0.3.5Private
513.82.152.48Public
\n", "
" ], "text/plain": [ " ip result\n", "0 23.96.64.84 Public\n", "1 65.55.44.108 Public\n", "2 131.107.147.209 Public\n", "3 10.0.3.4 Private\n", "4 10.0.3.5 Private\n", "5 13.82.152.48 Public" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nirasn_registryasnasn_cidrasn_country_codeasn_dateasn_descriptionquerynetsrawreferralraw_referral
0NaNarin807523.96.0.0/14US2013-06-18MICROSOFT-CORP-MSN-AS-BLOCK, US23.96.64.84[{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23....NaNNaNNaN
1NaNarin807565.52.0.0/14US2001-02-14MICROSOFT-CORP-MSN-AS-BLOCK, US65.55.44.108[{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52...NaNNaNNaN
2NaNarin3598131.107.0.0/16US1988-11-11MICROSOFT-CORP-AS, US131.107.147.209[{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10...NaNNaNNaN
3NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
4NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
5NaNarin807513.64.0.0/11US2015-03-26MICROSOFT-CORP-MSN-AS-BLOCK, US13.82.152.48[{'cidr': '13.104.0.0/14, 13.64.0.0/11, 13.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-...NaNNaNNaN
\n", "
" ], "text/plain": [ " nir asn_registry asn asn_cidr asn_country_code asn_date \\\n", "0 NaN arin 8075 23.96.0.0/14 US 2013-06-18 \n", "1 NaN arin 8075 65.52.0.0/14 US 2001-02-14 \n", "2 NaN arin 3598 131.107.0.0/16 US 1988-11-11 \n", "3 NaN NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN NaN \n", "5 NaN arin 8075 13.64.0.0/11 US 2015-03-26 \n", "\n", " asn_description query \\\n", "0 MICROSOFT-CORP-MSN-AS-BLOCK, US 23.96.64.84 \n", "1 MICROSOFT-CORP-MSN-AS-BLOCK, US 65.55.44.108 \n", "2 MICROSOFT-CORP-AS, US 131.107.147.209 \n", "3 NaN NaN \n", "4 NaN NaN \n", "5 MICROSOFT-CORP-MSN-AS-BLOCK, US 13.82.152.48 \n", "\n", " nets \\\n", "0 [{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23.... \n", "1 [{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52... \n", "2 [{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10... \n", "3 NaN \n", "4 NaN \n", "5 [{'cidr': '13.104.0.0/14, 13.64.0.0/11, 13.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-... \n", "\n", " raw referral raw_referral \n", "0 NaN NaN NaN \n", "1 NaN NaN NaN \n", "2 NaN NaN NaN \n", "3 NaN NaN NaN \n", "4 NaN NaN NaN \n", "5 NaN NaN NaN " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CountryCodeCountryNameStateCityLongitudeLatitudeAsnedgesTypeAdditionalDataIpAddress
0USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}23.96.64.84
1USUnited StatesVirginiaBoydton-78.375036.6534None{}geolocation{}65.55.44.108
2USUnited StatesWashingtonRedmond-122.125747.6722None{}geolocation{}131.107.147.209
3USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}13.82.152.48
\n", "
" ], "text/plain": [ " CountryCode CountryName State City Longitude Latitude \\\n", "0 US United States Virginia Washington -78.1539 38.7095 \n", "1 US United States Virginia Boydton -78.3750 36.6534 \n", "2 US United States Washington Redmond -122.1257 47.6722 \n", "3 US United States Virginia Washington -78.1539 38.7095 \n", "\n", " Asn edges Type AdditionalData IpAddress \n", "0 None {} geolocation {} 23.96.64.84 \n", "1 None {} geolocation {} 65.55.44.108 \n", "2 None {} geolocation {} 131.107.147.209 \n", "3 None {} geolocation {} 13.82.152.48 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ip_list1 = ip_df1.AllExtIPs.values[-6:]\n", "\n", "display(IpAddress.util.ip_type(ip_list1))\n", "display(IpAddress.util.ip_type(ip_str=list(ip_list1)))\n", "display(IpAddress.util.whois(value=tuple(ip_list1)))\n", "display(IpAddress.util.geoloc_mm(ip_list1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using DataFrames as input\n", "\n", "Using a dataframe as input requires a slightly different syntax since you not\n", "only need to pass the dataframe as a parameter but also tell the function\n", "which column to use for input.\n", "\n", "To specify the column to use, you can use the name of the parameter that the\n", "underlying function expects or one of these generic names:\n", "\n", "- column\n", "- input_column\n", "- input_col\n", "- src_column\n", "- src_col\n", "\n", "> Note these generic names are not shown in the function help" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
0172.217.15.99Public
140.85.232.64Public
220.38.98.100Public
323.96.64.84Public
465.55.44.108Public
5131.107.147.209Public
610.0.3.4Private
710.0.3.5Private
813.82.152.48Public
\n", "
" ], "text/plain": [ " ip result\n", "0 172.217.15.99 Public\n", "1 40.85.232.64 Public\n", "2 20.38.98.100 Public\n", "3 23.96.64.84 Public\n", "4 65.55.44.108 Public\n", "5 131.107.147.209 Public\n", "6 10.0.3.4 Private\n", "7 10.0.3.5 Private\n", "8 13.82.152.48 Public" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ipresult
0172.217.15.99Public
140.85.232.64Public
220.38.98.100Public
323.96.64.84Public
465.55.44.108Public
5131.107.147.209Public
610.0.3.4Private
710.0.3.5Private
813.82.152.48Public
\n", "
" ], "text/plain": [ " ip result\n", "0 172.217.15.99 Public\n", "1 40.85.232.64 Public\n", "2 20.38.98.100 Public\n", "3 23.96.64.84 Public\n", "4 65.55.44.108 Public\n", "5 131.107.147.209 Public\n", "6 10.0.3.4 Private\n", "7 10.0.3.5 Private\n", "8 13.82.152.48 Public" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nirasn_registryasnasn_cidrasn_country_codeasn_dateasn_descriptionquerynetsrawreferralraw_referral
9NaNarin15169172.217.15.0/24US2012-04-16GOOGLE, US172.217.15.99[{'cidr': '172.217.0.0/16', 'name': 'GOOGLE', 'handle': 'NET-172-217-0-0-1', 'range': '172.217.0...NaNNaNNaN
10NaNarin807540.80.0.0/12US2015-02-23MICROSOFT-CORP-MSN-AS-BLOCK, US40.85.232.64[{'cidr': '40.112.0.0/13, 40.76.0.0/14, 40.120.0.0/14, 40.80.0.0/12, 40.74.0.0/15, 40.125.0.0/17...NaNNaNNaN
11NaNarin807520.36.0.0/14US2017-10-18MICROSOFT-CORP-MSN-AS-BLOCK, US20.38.98.100[{'cidr': '20.40.0.0/13, 20.33.0.0/16, 20.36.0.0/14, 20.64.0.0/10, 20.34.0.0/15, 20.128.0.0/16, ...NaNNaNNaN
12NaNarin807523.96.0.0/14US2013-06-18MICROSOFT-CORP-MSN-AS-BLOCK, US23.96.64.84[{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23....NaNNaNNaN
13NaNarin807565.52.0.0/14US2001-02-14MICROSOFT-CORP-MSN-AS-BLOCK, US65.55.44.108[{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52...NaNNaNNaN
14NaNarin3598131.107.0.0/16US1988-11-11MICROSOFT-CORP-AS, US131.107.147.209[{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10...NaNNaNNaN
15NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
16NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
17NaNarin807513.64.0.0/11US2015-03-26MICROSOFT-CORP-MSN-AS-BLOCK, US13.82.152.48[{'cidr': '13.104.0.0/14, 13.64.0.0/11, 13.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-...NaNNaNNaN
\n", "
" ], "text/plain": [ " nir asn_registry asn asn_cidr asn_country_code asn_date \\\n", "9 NaN arin 15169 172.217.15.0/24 US 2012-04-16 \n", "10 NaN arin 8075 40.80.0.0/12 US 2015-02-23 \n", "11 NaN arin 8075 20.36.0.0/14 US 2017-10-18 \n", "12 NaN arin 8075 23.96.0.0/14 US 2013-06-18 \n", "13 NaN arin 8075 65.52.0.0/14 US 2001-02-14 \n", "14 NaN arin 3598 131.107.0.0/16 US 1988-11-11 \n", "15 NaN NaN NaN NaN NaN NaN \n", "16 NaN NaN NaN NaN NaN NaN \n", "17 NaN arin 8075 13.64.0.0/11 US 2015-03-26 \n", "\n", " asn_description query \\\n", "9 GOOGLE, US 172.217.15.99 \n", "10 MICROSOFT-CORP-MSN-AS-BLOCK, US 40.85.232.64 \n", "11 MICROSOFT-CORP-MSN-AS-BLOCK, US 20.38.98.100 \n", "12 MICROSOFT-CORP-MSN-AS-BLOCK, US 23.96.64.84 \n", "13 MICROSOFT-CORP-MSN-AS-BLOCK, US 65.55.44.108 \n", "14 MICROSOFT-CORP-AS, US 131.107.147.209 \n", "15 NaN NaN \n", "16 NaN NaN \n", "17 MICROSOFT-CORP-MSN-AS-BLOCK, US 13.82.152.48 \n", "\n", " nets \\\n", "9 [{'cidr': '172.217.0.0/16', 'name': 'GOOGLE', 'handle': 'NET-172-217-0-0-1', 'range': '172.217.0... \n", "10 [{'cidr': '40.112.0.0/13, 40.76.0.0/14, 40.120.0.0/14, 40.80.0.0/12, 40.74.0.0/15, 40.125.0.0/17... \n", "11 [{'cidr': '20.40.0.0/13, 20.33.0.0/16, 20.36.0.0/14, 20.64.0.0/10, 20.34.0.0/15, 20.128.0.0/16, ... \n", "12 [{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23.... \n", "13 [{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52... \n", "14 [{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10... \n", "15 NaN \n", "16 NaN \n", "17 [{'cidr': '13.104.0.0/14, 13.64.0.0/11, 13.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-... \n", "\n", " raw referral raw_referral \n", "9 NaN NaN NaN \n", "10 NaN NaN NaN \n", "11 NaN NaN NaN \n", "12 NaN NaN NaN \n", "13 NaN NaN NaN \n", "14 NaN NaN NaN \n", "15 NaN NaN NaN \n", "16 NaN NaN NaN \n", "17 NaN NaN NaN " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CountryCodeCountryNameStateCityLongitudeLatitudeAsnedgesTypeAdditionalDataIpAddress
0USUnited StatesNoneNone-97.822037.7510None{}geolocation{}172.217.15.99
1CACanadaOntarioToronto-79.419543.6644None{}geolocation{}40.85.232.64
2USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}20.38.98.100
3USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}23.96.64.84
4USUnited StatesVirginiaBoydton-78.375036.6534None{}geolocation{}65.55.44.108
5USUnited StatesWashingtonRedmond-122.125747.6722None{}geolocation{}131.107.147.209
6USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}13.82.152.48
\n", "
" ], "text/plain": [ " CountryCode CountryName State City Longitude Latitude \\\n", "0 US United States None None -97.8220 37.7510 \n", "1 CA Canada Ontario Toronto -79.4195 43.6644 \n", "2 US United States Virginia Washington -78.1539 38.7095 \n", "3 US United States Virginia Washington -78.1539 38.7095 \n", "4 US United States Virginia Boydton -78.3750 36.6534 \n", "5 US United States Washington Redmond -122.1257 47.6722 \n", "6 US United States Virginia Washington -78.1539 38.7095 \n", "\n", " Asn edges Type AdditionalData IpAddress \n", "0 None {} geolocation {} 172.217.15.99 \n", "1 None {} geolocation {} 40.85.232.64 \n", "2 None {} geolocation {} 20.38.98.100 \n", "3 None {} geolocation {} 23.96.64.84 \n", "4 None {} geolocation {} 65.55.44.108 \n", "5 None {} geolocation {} 131.107.147.209 \n", "6 None {} geolocation {} 13.82.152.48 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(IpAddress.util.ip_type(data=ip_df1, input_col=\"AllExtIPs\"))\n", "display(IpAddress.util.ip_type(data=ip_df1, ip=\"AllExtIPs\"))\n", "display(IpAddress.util.whois(data=ip_df1, column=\"AllExtIPs\"))\n", "display(IpAddress.util.geoloc_mm(data=ip_df1, src_col=\"AllExtIPs\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Joining input to output data\n", "\n", "You might want to return a data set that is joined to your input set.\n", "To do that use the \"join\" parameter.\n", "\n", "The value of join can be:\n", "- inner\n", "- left\n", "- right\n", "- outer\n", "\n", "To preserve all rows from the input, use a \"left\" join.\n", "To keep only rows that have a valid result from the function use \"inner\" or \"right\"\n", "\n", "> Note while most functions only return a single output row for each input row
\n", "> some return multiple rows. Be cautious using \"outer\" in these cases." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AllExtIPsCountryCodeCountryNameStateCityLongitudeLatitudeAsnedgesTypeAdditionalDataIpAddress
0172.217.15.99USUnited StatesNoneNone-97.822037.7510None{}geolocation{}172.217.15.99
140.85.232.64CACanadaOntarioToronto-79.419543.6644None{}geolocation{}40.85.232.64
220.38.98.100USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}20.38.98.100
323.96.64.84USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}23.96.64.84
465.55.44.108USUnited StatesVirginiaBoydton-78.375036.6534None{}geolocation{}65.55.44.108
5131.107.147.209USUnited StatesWashingtonRedmond-122.125747.6722None{}geolocation{}131.107.147.209
610.0.3.4NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
710.0.3.5NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
813.82.152.48USUnited StatesVirginiaWashington-78.153938.7095None{}geolocation{}13.82.152.48
\n", "
" ], "text/plain": [ " AllExtIPs CountryCode CountryName State City \\\n", "0 172.217.15.99 US United States None None \n", "1 40.85.232.64 CA Canada Ontario Toronto \n", "2 20.38.98.100 US United States Virginia Washington \n", "3 23.96.64.84 US United States Virginia Washington \n", "4 65.55.44.108 US United States Virginia Boydton \n", "5 131.107.147.209 US United States Washington Redmond \n", "6 10.0.3.4 NaN NaN NaN NaN \n", "7 10.0.3.5 NaN NaN NaN NaN \n", "8 13.82.152.48 US United States Virginia Washington \n", "\n", " Longitude Latitude Asn edges Type AdditionalData \\\n", "0 -97.8220 37.7510 None {} geolocation {} \n", "1 -79.4195 43.6644 None {} geolocation {} \n", "2 -78.1539 38.7095 None {} geolocation {} \n", "3 -78.1539 38.7095 None {} geolocation {} \n", "4 -78.3750 36.6534 None {} geolocation {} \n", "5 -122.1257 47.6722 None {} geolocation {} \n", "6 NaN NaN NaN NaN NaN NaN \n", "7 NaN NaN NaN NaN NaN NaN \n", "8 -78.1539 38.7095 None {} geolocation {} \n", "\n", " IpAddress \n", "0 172.217.15.99 \n", "1 40.85.232.64 \n", "2 20.38.98.100 \n", "3 23.96.64.84 \n", "4 65.55.44.108 \n", "5 131.107.147.209 \n", "6 NaN \n", "7 NaN \n", "8 13.82.152.48 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(IpAddress.util.geoloc_mm(data=ip_df1, src_col=\"AllExtIPs\", join=\"left\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## DataQuery Pivot functions\n", "\n", "A significant difference between the functions that we've seen so far\n", "and data query functions is that the latter **do not accept generic parameter names.**\n", "\n", "When you use a named parameter in a data query pivot, you must specify\n", "the name that the query function is expecting. If in doubt, use \"?\" prefix to show the function help.\n", "\n", "Example:\n", "```\n", " Host.AzureSentinel.list_host_events_by_id?\n", "```" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", "
\n", " \n", " \n", "
\n", "\n", " \n", "\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ws = WorkspaceConfig(workspace=\"CyberSecuritySoc\")\n", "az_provider.connect(ws.code_connect_str)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setting time parameters for queries interactively\n", "\n", "Use the `edit_query_time` function to set/change the time range used by queries.\n", "\n", "With no parameters it defaults to a period of \\[*UtcNow - 1 day*\\] to \\[*UtcNow*\\].\n", "\n", "Or you can specify a timespan to use with the TimeSpan class." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function edit_query_time in module msticpy.datamodel.pivot:\n", "\n", "edit_query_time(self, timespan: Union[msticpy.common.timespan.TimeSpan, NoneType] = None)\n", " Display a QueryTime widget to get the timespan.\n", " \n", " Parameters\n", " ----------\n", " timespan : Optional[TimeSpan], optional\n", " Pre-populate the timespan shown by the QueryTime editor,\n", " by default None\n", "\n" ] } ], "source": [ "help(Pivot.edit_query_time)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8ed7de7792c94b2bb5a1dd02c1cc13a5", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(HTML(value='

Set time range for pivot functions.

'), HBox(children=(DatePicker(value=dat…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from msticpy.common.timespan import TimeSpan\n", "ts = TimeSpan(start=\"2020-10-01\", period=\"1d\")\n", "Pivot.current.edit_query_time(timespan=ts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setting the timespan programmatically\n", "You can also just set the timespan directly on the pivot object" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "Pivot.current.timespan = ts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### What queries do we have?" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "list_related_alerts function\n", "az_net_analytics function\n", "get_info_by_hostname function\n", "auditd_all function\n", "sudo_activity function\n", "cron_activity function\n", "user_group_activity function\n", "all_syslog function\n", "squid_activity function\n", "user_logon function\n", "list_logons_for_host function\n", "list_host_logon_failures function\n", "get_ips_for_host function\n", "get_heartbeat_for_host function\n", "list_azure_network_flows_by_host function\n", "list_host_events function\n", "list_host_events_by_id function\n", "list_other_events function\n", "get_host_logon function\n", "list_host_logons function\n", "list_all_logons_by_host function\n", "list_host_processes function\n", "get_process_tree function\n", "get_parent_process function\n", "list_processes_in_session function\n" ] } ], "source": [ "Host.AzureSentinel()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TenantIdSourceSystemTimeGeneratedMGManagementGroupNameSourceComputerIdComputerIPComputerCategoryOSTypeOSNameOSMajorVersionOSMinorVersionVersionSCAgentChannelIsGatewayInstalledRemoteIPLongitudeRemoteIPLatitudeRemoteIPCountrySubscriptionIdResourceGroupResourceProviderResourceResourceIdResourceTypeComputerEnvironmentSolutionsVMUUIDType_ResourceId
08ecf8077-cf51-4820-aadd-14040956f35dOpsManager2020-12-03 18:01:11.167000+00:0000000000-0000-0000-0000-000000000001AOI-8ecf8077-cf51-4820-aadd-14040956f35df6638b82-98a5-4542-8bec-6bc0977f793f13.89.108.248VictimPc.Contoso.AzureDirect AgentWindows10010.20.18040.0DirectFalse-93.6241.59United Statesd1d8779d-38d7-4f06-91db-9cbc8de0176fDefendTheFlagMicrosoft.ComputeVictimPc/subscriptions/d1d8779d-38d7-4f06-91db-9cbc8de0176f/resourceGroups/DefendTheFlag/providers/Micro...virtualMachinesAzure\"behaviorAnalyticsInsights\", \"security\", \"networkMonitoring\", \"dnsAnalytics\", \"securityCenterFre...14fa800d-e9b0-4dea-86ac-679933d59253Heartbeat/subscriptions/d1d8779d-38d7-4f06-91db-9cbc8de0176f/resourcegroups/defendtheflag/providers/micro...
\n", "
" ], "text/plain": [ " TenantId SourceSystem \\\n", "0 8ecf8077-cf51-4820-aadd-14040956f35d OpsManager \n", "\n", " TimeGenerated MG \\\n", "0 2020-12-03 18:01:11.167000+00:00 00000000-0000-0000-0000-000000000001 \n", "\n", " ManagementGroupName \\\n", "0 AOI-8ecf8077-cf51-4820-aadd-14040956f35d \n", "\n", " SourceComputerId ComputerIP \\\n", "0 f6638b82-98a5-4542-8bec-6bc0977f793f 13.89.108.248 \n", "\n", " Computer Category OSType OSName OSMajorVersion \\\n", "0 VictimPc.Contoso.Azure Direct Agent Windows 10 \n", "\n", " OSMinorVersion Version SCAgentChannel IsGatewayInstalled \\\n", "0 0 10.20.18040.0 Direct False \n", "\n", " RemoteIPLongitude RemoteIPLatitude RemoteIPCountry \\\n", "0 -93.62 41.59 United States \n", "\n", " SubscriptionId ResourceGroup ResourceProvider \\\n", "0 d1d8779d-38d7-4f06-91db-9cbc8de0176f DefendTheFlag Microsoft.Compute \n", "\n", " Resource \\\n", "0 VictimPc \n", "\n", " ResourceId \\\n", "0 /subscriptions/d1d8779d-38d7-4f06-91db-9cbc8de0176f/resourceGroups/DefendTheFlag/providers/Micro... \n", "\n", " ResourceType ComputerEnvironment \\\n", "0 virtualMachines Azure \n", "\n", " Solutions \\\n", "0 \"behaviorAnalyticsInsights\", \"security\", \"networkMonitoring\", \"dnsAnalytics\", \"securityCenterFre... \n", "\n", " VMUUID Type \\\n", "0 14fa800d-e9b0-4dea-86ac-679933d59253 Heartbeat \n", "\n", " _ResourceId \n", "0 /subscriptions/d1d8779d-38d7-4f06-91db-9cbc8de0176f/resourcegroups/defendtheflag/providers/micro... " ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "host = Host(HostName=\"VictimPc\")\n", "Host.AzureSentinel.get_heartbeat_for_host(host)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TenantIdAccountEventIDTimeGeneratedSourceComputerIdComputerSubjectUserNameSubjectDomainNameSubjectUserSidTargetUserNameTargetDomainNameTargetUserSidTargetLogonIdLogonProcessNameLogonTypeLogonTypeNameAuthenticationPackageNameStatusIpAddressWorkstationNameTimeCreatedUtc
08ecf8077-cf51-4820-aadd-14040956f35dNT AUTHORITY\\SYSTEM46242020-10-01 22:39:36.987000+00:00f6638b82-98a5-4542-8bec-6bc0977f793fVictimPc.Contoso.AzureVictimPc$CONTOSOS-1-5-18SYSTEMNT AUTHORITYS-1-5-180x3e7Advapi55 - ServiceNegotiate--2020-10-01 22:39:36.987000+00:00
18ecf8077-cf51-4820-aadd-14040956f35dNT AUTHORITY\\SYSTEM46242020-10-01 22:39:37.220000+00:00f6638b82-98a5-4542-8bec-6bc0977f793fVictimPc.Contoso.AzureVictimPc$CONTOSOS-1-5-18SYSTEMNT AUTHORITYS-1-5-180x3e7Advapi55 - ServiceNegotiate--2020-10-01 22:39:37.220000+00:00
28ecf8077-cf51-4820-aadd-14040956f35dNT AUTHORITY\\SYSTEM46242020-10-01 22:39:42.603000+00:00f6638b82-98a5-4542-8bec-6bc0977f793fVictimPc.Contoso.AzureVictimPc$CONTOSOS-1-5-18SYSTEMNT AUTHORITYS-1-5-180x3e7Advapi55 - ServiceNegotiate--2020-10-01 22:39:42.603000+00:00
38ecf8077-cf51-4820-aadd-14040956f35dCONTOSO\\RonHD46242020-10-01 22:40:00.957000+00:00f6638b82-98a5-4542-8bec-6bc0977f793fVictimPc.Contoso.AzureVictimPc$CONTOSOS-1-5-18RonHDCONTOSOS-1-5-21-1661583231-2311428937-3957907789-11050x117a0f7fAdvapi44 - BatchNegotiate-VictimPc2020-10-01 22:40:00.957000+00:00
48ecf8077-cf51-4820-aadd-14040956f35dNT AUTHORITY\\SYSTEM46242020-10-01 22:40:14.040000+00:00f6638b82-98a5-4542-8bec-6bc0977f793fVictimPc.Contoso.AzureVictimPc$CONTOSOS-1-5-18SYSTEMNT AUTHORITYS-1-5-180x3e7Advapi55 - ServiceNegotiate--2020-10-01 22:40:14.040000+00:00
\n", "
" ], "text/plain": [ " TenantId Account EventID \\\n", "0 8ecf8077-cf51-4820-aadd-14040956f35d NT AUTHORITY\\SYSTEM 4624 \n", "1 8ecf8077-cf51-4820-aadd-14040956f35d NT AUTHORITY\\SYSTEM 4624 \n", "2 8ecf8077-cf51-4820-aadd-14040956f35d NT AUTHORITY\\SYSTEM 4624 \n", "3 8ecf8077-cf51-4820-aadd-14040956f35d CONTOSO\\RonHD 4624 \n", "4 8ecf8077-cf51-4820-aadd-14040956f35d NT AUTHORITY\\SYSTEM 4624 \n", "\n", " TimeGenerated SourceComputerId \\\n", "0 2020-10-01 22:39:36.987000+00:00 f6638b82-98a5-4542-8bec-6bc0977f793f \n", "1 2020-10-01 22:39:37.220000+00:00 f6638b82-98a5-4542-8bec-6bc0977f793f \n", "2 2020-10-01 22:39:42.603000+00:00 f6638b82-98a5-4542-8bec-6bc0977f793f \n", "3 2020-10-01 22:40:00.957000+00:00 f6638b82-98a5-4542-8bec-6bc0977f793f \n", "4 2020-10-01 22:40:14.040000+00:00 f6638b82-98a5-4542-8bec-6bc0977f793f \n", "\n", " Computer SubjectUserName SubjectDomainName SubjectUserSid \\\n", "0 VictimPc.Contoso.Azure VictimPc$ CONTOSO S-1-5-18 \n", "1 VictimPc.Contoso.Azure VictimPc$ CONTOSO S-1-5-18 \n", "2 VictimPc.Contoso.Azure VictimPc$ CONTOSO S-1-5-18 \n", "3 VictimPc.Contoso.Azure VictimPc$ CONTOSO S-1-5-18 \n", "4 VictimPc.Contoso.Azure VictimPc$ CONTOSO S-1-5-18 \n", "\n", " TargetUserName TargetDomainName \\\n", "0 SYSTEM NT AUTHORITY \n", "1 SYSTEM NT AUTHORITY \n", "2 SYSTEM NT AUTHORITY \n", "3 RonHD CONTOSO \n", "4 SYSTEM NT AUTHORITY \n", "\n", " TargetUserSid TargetLogonId \\\n", "0 S-1-5-18 0x3e7 \n", "1 S-1-5-18 0x3e7 \n", "2 S-1-5-18 0x3e7 \n", "3 S-1-5-21-1661583231-2311428937-3957907789-1105 0x117a0f7f \n", "4 S-1-5-18 0x3e7 \n", "\n", " LogonProcessName LogonType LogonTypeName AuthenticationPackageName Status \\\n", "0 Advapi 5 5 - Service Negotiate \n", "1 Advapi 5 5 - Service Negotiate \n", "2 Advapi 5 5 - Service Negotiate \n", "3 Advapi 4 4 - Batch Negotiate \n", "4 Advapi 5 5 - Service Negotiate \n", "\n", " IpAddress WorkstationName TimeCreatedUtc \n", "0 - - 2020-10-01 22:39:36.987000+00:00 \n", "1 - - 2020-10-01 22:39:37.220000+00:00 \n", "2 - - 2020-10-01 22:39:42.603000+00:00 \n", "3 - VictimPc 2020-10-01 22:40:00.957000+00:00 \n", "4 - - 2020-10-01 22:40:14.040000+00:00 " ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Host.AzureSentinel.list_host_logons(host_name=\"VictimPc\").head()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adding additional parameters\n", "\n", "The example below shows using the host entity as an initial parameter\n", "(Pivot is using the attribute mapping assign the `host_name` function parameter the value of `host.fqdn`).\n", "\n", "The second parameter is a list of event IDs specified explicitly." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\u001b[1;31mSignature:\u001b[0m \u001b[0mHost\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mAzureSentinel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlist_host_events_by_id\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mpandas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mframe\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mDocstring:\u001b[0m\n", "Retrieves list of events on a host\n", "\n", "Parameters\n", "----------\n", "add_query_items: str (optional)\n", " Additional query clauses\n", "end: datetime\n", " Query end time\n", "event_list: list (optional)\n", " List of event IDs to match\n", " (default value is: has)\n", "host_name: str\n", " Name of host\n", "host_op: str (optional)\n", " The hostname match operator\n", " (default value is: has)\n", "query_project: str (optional)\n", " Column project statement\n", "start: datetime\n", " Query start time\n", "table: str (optional)\n", " Table name\n", " (default value is: SecurityEvent)\n", "\u001b[1;31mFile:\u001b[0m c:\\users\\ian\\anaconda3\\envs\\condadev\\lib\\functools.py\n", "\u001b[1;31mType:\u001b[0m function\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "Host.AzureSentinel.list_host_events_by_id?" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Computer
EventIDActivity
46244624 - An account was successfully logged on.520
46724672 - Special privileges assigned to new logon.436
\n", "
" ], "text/plain": [ " Computer\n", "EventID Activity \n", "4624 4624 - An account was successfully logged on. 520\n", "4672 4672 - Special privileges assigned to new logon. 436" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(\n", " Host.AzureSentinel.list_host_events_by_id( # Pivot query returns DataFrame\n", " host, event_list=[4624, 4625, 4672]\n", " )\n", " [[\"Computer\", \"EventID\", \"Activity\"]] # we could have save the output to a dataframe\n", " .groupby([\"EventID\", \"Activity\"]) # variable but we can also use pandas\n", " .count() # functions/syntax directly on the output\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using iterables as parameters to data queries\n", "\n", "Some data queries accept \"list\" items as parameters (e.g. many of the IP queries accept a\n", "list of IP addresses). These work as expected, with a single query calling sending the whole list\n", "as a single parameter." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "list_alerts_for_ip function\n", "list_aad_signins_for_ip function\n", "list_azure_activity_for_ip function\n", "list_azure_network_flows_by_ip function\n", "list_activity_for_ip function\n", "get_info_by_ipaddress function\n", "list_logons_for_source_ip function\n", "get_host_for_ip function\n", "get_heartbeat_for_ip function\n", "list_indicators function\n", "list_indicators_by_ip function\n", "list_indicators_by_hash function\n", "list_indicators_by_filepath function\n", "list_indicators_by_domain function\n", "list_indicators_by_email function\n", "list_indicators_by_url function\n" ] } ], "source": [ "ip_list = [\n", " \"203.23.68.64\",\n", " \"67.10.68.45\",\n", " \"182.69.173.164\",\n", " \"79.176.167.161\",\n", " \"167.220.197.230\",\n", "]\n", "\n", "IpAddress.AzureSentinel()" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\u001b[1;31mSignature:\u001b[0m \u001b[0mIpAddress\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mAzureSentinel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlist_aad_signins_for_ip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mpandas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mframe\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mDocstring:\u001b[0m\n", "Lists Azure AD Signins for an IP Address\n", "\n", "Parameters\n", "----------\n", "add_query_items: str (optional)\n", " Additional query clauses\n", "end: datetime (optional)\n", " Query end time\n", "ip_address_list: list\n", " The IP Address or list of Addresses\n", "start: datetime (optional)\n", " Query start time\n", " (default value is: -5)\n", "table: str (optional)\n", " Table name\n", " (default value is: SigninLogs)\n", "\u001b[1;31mFile:\u001b[0m c:\\users\\ian\\anaconda3\\envs\\condadev\\lib\\functools.py\n", "\u001b[1;31mType:\u001b[0m function\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "IpAddress.AzureSentinel.list_aad_signins_for_ip?" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TenantIdSourceSystemTimeGeneratedResourceIdOperationNameOperationVersionCategoryResultTypeResultSignatureResultDescriptionDurationMsCorrelationIdResourceResourceGroupResourceProviderIdentityLevelLocationAlternateSignInNameAppDisplayNameAppIdAuthenticationDetailsAuthenticationMethodsUsedAuthenticationProcessingDetailsAuthenticationRequirement...IsRiskyLocationDetailsMfaDetailNetworkLocationDetailsOriginalRequestIdProcessingTimeInMillisecondsRiskDetailRiskEventTypesRiskEventTypes_V2RiskLevelAggregatedRiskLevelDuringSignInRiskStateResourceDisplayNameResourceIdentityServicePrincipalIdServicePrincipalNameStatusTokenIssuerNameTokenIssuerTypeUserAgentUserDisplayNameUserIdUserPrincipalNameAADTenantIdType
08ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 13:02:35.957000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None0affb9968-fde2-4369-bd7e-d529369d6da1Microsoft.aadiamMicrosoft.aadiamBrandon4USAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17[][\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n]singleFactorAuthentication...None{'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':...None[]5d995a60-e8ef-4ca8-acdd-41c2db788100182none[][]nonenonenoneAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17{'errorCode': 0}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427...Brandon9dadd76f-3237-4e1d-84e7-e45c59867492brandon@seccxpninja.onmicrosoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
18ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 14:02:40.100000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None09d67aa98-e889-417b-888d-e75611c1a458Microsoft.aadiamMicrosoft.aadiamBrandon4USAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17[][\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n]singleFactorAuthentication...None{'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':...None[]70141716-651c-4f23-a1f8-e06015497f00176none[][]nonenonenoneAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17{'errorCode': 0}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427...Brandon9dadd76f-3237-4e1d-84e7-e45c59867492brandon@seccxpninja.onmicrosoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
28ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 15:02:45.205000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None0d3c71898-c2f7-4563-ae0c-82851116852dMicrosoft.aadiamMicrosoft.aadiamBrandon4USAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17[][\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n]singleFactorAuthentication...None{'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':...None[]422d0e7e-9e69-48ea-85a7-34bcb7a20101166none[][]nonenonenoneAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17{'errorCode': 0}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427...Brandon9dadd76f-3237-4e1d-84e7-e45c59867492brandon@seccxpninja.onmicrosoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
38ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 17:45:14.507000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None0b1d3e8fa-fe53-4b6f-b683-debb7b482f87Microsoft.aadiamMicrosoft.aadiamBrandon4USMicrosoft Cloud App Security05a65629-4c1b-48c1-a78b-804c4abdd4af[][\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n]singleFactorAuthentication...None{'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':...None[]70959618-8d07-4004-a68f-0b93c1409200150none[][]nonenonenoneWindows Azure Active Directory00000002-0000-0000-c000-000000000000{'errorCode': 0}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427...Brandon9dadd76f-3237-4e1d-84e7-e45c59867492brandon@seccxpninja.onmicrosoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
48ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 10:02:18.923000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None0ac81524b-bb83-4a0a-a3f8-577a14dda295Microsoft.aadiamMicrosoft.aadiamBrandon4USAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17[][\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n]singleFactorAuthentication...None{'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':...None[]c2bcb991-75ad-42f4-a6c0-1a90686dfd00210none[][]nonenonenoneAzure Advanced Threat Protection7b7531ad-5926-4f2d-8a1d-38495ad33e17{'errorCode': 0}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427...Brandon9dadd76f-3237-4e1d-84e7-e45c59867492brandon@seccxpninja.onmicrosoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
\n", "

5 rows × 59 columns

\n", "
" ], "text/plain": [ " TenantId SourceSystem \\\n", "0 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "1 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "2 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "3 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "4 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "\n", " TimeGenerated \\\n", "0 2020-10-01 13:02:35.957000+00:00 \n", "1 2020-10-01 14:02:40.100000+00:00 \n", "2 2020-10-01 15:02:45.205000+00:00 \n", "3 2020-10-01 17:45:14.507000+00:00 \n", "4 2020-10-01 10:02:18.923000+00:00 \n", "\n", " ResourceId \\\n", "0 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "1 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "2 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "3 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "4 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "\n", " OperationName OperationVersion Category ResultType ResultSignature \\\n", "0 Sign-in activity 1.0 SignInLogs 0 None \n", "1 Sign-in activity 1.0 SignInLogs 0 None \n", "2 Sign-in activity 1.0 SignInLogs 0 None \n", "3 Sign-in activity 1.0 SignInLogs 0 None \n", "4 Sign-in activity 1.0 SignInLogs 0 None \n", "\n", " ResultDescription DurationMs CorrelationId \\\n", "0 0 affb9968-fde2-4369-bd7e-d529369d6da1 \n", "1 0 9d67aa98-e889-417b-888d-e75611c1a458 \n", "2 0 d3c71898-c2f7-4563-ae0c-82851116852d \n", "3 0 b1d3e8fa-fe53-4b6f-b683-debb7b482f87 \n", "4 0 ac81524b-bb83-4a0a-a3f8-577a14dda295 \n", "\n", " Resource ResourceGroup ResourceProvider Identity Level \\\n", "0 Microsoft.aadiam Microsoft.aadiam Brandon 4 \n", "1 Microsoft.aadiam Microsoft.aadiam Brandon 4 \n", "2 Microsoft.aadiam Microsoft.aadiam Brandon 4 \n", "3 Microsoft.aadiam Microsoft.aadiam Brandon 4 \n", "4 Microsoft.aadiam Microsoft.aadiam Brandon 4 \n", "\n", " Location AlternateSignInName AppDisplayName \\\n", "0 US Azure Advanced Threat Protection \n", "1 US Azure Advanced Threat Protection \n", "2 US Azure Advanced Threat Protection \n", "3 US Microsoft Cloud App Security \n", "4 US Azure Advanced Threat Protection \n", "\n", " AppId AuthenticationDetails \\\n", "0 7b7531ad-5926-4f2d-8a1d-38495ad33e17 [] \n", "1 7b7531ad-5926-4f2d-8a1d-38495ad33e17 [] \n", "2 7b7531ad-5926-4f2d-8a1d-38495ad33e17 [] \n", "3 05a65629-4c1b-48c1-a78b-804c4abdd4af [] \n", "4 7b7531ad-5926-4f2d-8a1d-38495ad33e17 [] \n", "\n", " AuthenticationMethodsUsed \\\n", "0 \n", "1 \n", "2 \n", "3 \n", "4 \n", "\n", " AuthenticationProcessingDetails \\\n", "0 [\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n] \n", "1 [\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n] \n", "2 [\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n] \n", "3 [\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n] \n", "4 [\\r\\n {\\r\\n \"key\": \"IsCAEToken\",\\r\\n \"value\": \"False\"\\r\\n }\\r\\n] \n", "\n", " AuthenticationRequirement ... IsRisky \\\n", "0 singleFactorAuthentication ... None \n", "1 singleFactorAuthentication ... None \n", "2 singleFactorAuthentication ... None \n", "3 singleFactorAuthentication ... None \n", "4 singleFactorAuthentication ... None \n", "\n", " LocationDetails \\\n", "0 {'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':... \n", "1 {'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':... \n", "2 {'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':... \n", "3 {'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':... \n", "4 {'city': 'Lewisville', 'state': 'Texas', 'countryOrRegion': 'US', 'geoCoordinates': {'latitude':... \n", "\n", " MfaDetail NetworkLocationDetails OriginalRequestId \\\n", "0 None [] 5d995a60-e8ef-4ca8-acdd-41c2db788100 \n", "1 None [] 70141716-651c-4f23-a1f8-e06015497f00 \n", "2 None [] 422d0e7e-9e69-48ea-85a7-34bcb7a20101 \n", "3 None [] 70959618-8d07-4004-a68f-0b93c1409200 \n", "4 None [] c2bcb991-75ad-42f4-a6c0-1a90686dfd00 \n", "\n", " ProcessingTimeInMilliseconds RiskDetail RiskEventTypes RiskEventTypes_V2 \\\n", "0 182 none [] [] \n", "1 176 none [] [] \n", "2 166 none [] [] \n", "3 150 none [] [] \n", "4 210 none [] [] \n", "\n", " RiskLevelAggregated RiskLevelDuringSignIn RiskState \\\n", "0 none none none \n", "1 none none none \n", "2 none none none \n", "3 none none none \n", "4 none none none \n", "\n", " ResourceDisplayName ResourceIdentity \\\n", "0 Azure Advanced Threat Protection 7b7531ad-5926-4f2d-8a1d-38495ad33e17 \n", "1 Azure Advanced Threat Protection 7b7531ad-5926-4f2d-8a1d-38495ad33e17 \n", "2 Azure Advanced Threat Protection 7b7531ad-5926-4f2d-8a1d-38495ad33e17 \n", "3 Windows Azure Active Directory 00000002-0000-0000-c000-000000000000 \n", "4 Azure Advanced Threat Protection 7b7531ad-5926-4f2d-8a1d-38495ad33e17 \n", "\n", " ServicePrincipalId ServicePrincipalName Status TokenIssuerName \\\n", "0 {'errorCode': 0} \n", "1 {'errorCode': 0} \n", "2 {'errorCode': 0} \n", "3 {'errorCode': 0} \n", "4 {'errorCode': 0} \n", "\n", " TokenIssuerType \\\n", "0 AzureAD \n", "1 AzureAD \n", "2 AzureAD \n", "3 AzureAD \n", "4 AzureAD \n", "\n", " UserAgent \\\n", "0 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427... \n", "1 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427... \n", "2 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427... \n", "3 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427... \n", "4 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.427... \n", "\n", " UserDisplayName UserId \\\n", "0 Brandon 9dadd76f-3237-4e1d-84e7-e45c59867492 \n", "1 Brandon 9dadd76f-3237-4e1d-84e7-e45c59867492 \n", "2 Brandon 9dadd76f-3237-4e1d-84e7-e45c59867492 \n", "3 Brandon 9dadd76f-3237-4e1d-84e7-e45c59867492 \n", "4 Brandon 9dadd76f-3237-4e1d-84e7-e45c59867492 \n", "\n", " UserPrincipalName AADTenantId \\\n", "0 brandon@seccxpninja.onmicrosoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c \n", "1 brandon@seccxpninja.onmicrosoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c \n", "2 brandon@seccxpninja.onmicrosoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c \n", "3 brandon@seccxpninja.onmicrosoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c \n", "4 brandon@seccxpninja.onmicrosoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c \n", "\n", " Type \n", "0 SigninLogs \n", "1 SigninLogs \n", "2 SigninLogs \n", "3 SigninLogs \n", "4 SigninLogs \n", "\n", "[5 rows x 59 columns]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IpAddress.AzureSentinel.list_aad_signins_for_ip(ip_address_list=ip_list).head(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using iterable values where parameters only accept single value\n", "\n", "In this case the pivot function will iterate through the values of the\n", "iterable, making a separate query for each and then joining the results.\n", "\n", "We can see that this function only accepts a single value for \"account_name\"." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\u001b[1;31mSignature:\u001b[0m \u001b[0mAccount\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mAzureSentinel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlist_aad_signins_for_account\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mpandas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mframe\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mDocstring:\u001b[0m\n", "Lists Azure AD Signins for Account\n", "\n", "Parameters\n", "----------\n", "account_name: str\n", " The account name to find\n", "add_query_items: str (optional)\n", " Additional query clauses\n", "end: datetime (optional)\n", " Query end time\n", "start: datetime (optional)\n", " Query start time\n", " (default value is: -5)\n", "table: str (optional)\n", " Table name\n", " (default value is: SigninLogs)\n", "\u001b[1;31mFile:\u001b[0m c:\\users\\ian\\anaconda3\\envs\\condadev\\lib\\functools.py\n", "\u001b[1;31mType:\u001b[0m function\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "Account.AzureSentinel.list_aad_signins_for_account?" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TenantIdSourceSystemTimeGeneratedResourceIdOperationNameOperationVersionCategoryResultTypeResultSignatureResultDescriptionDurationMsCorrelationIdResourceResourceGroupResourceProviderIdentityLevelLocationAlternateSignInNameAppDisplayNameAppIdAuthenticationDetailsAuthenticationMethodsUsedAuthenticationProcessingDetailsAuthenticationRequirement...IsRiskyLocationDetailsMfaDetailNetworkLocationDetailsOriginalRequestIdProcessingTimeInMillisecondsRiskDetailRiskEventTypesRiskEventTypes_V2RiskLevelAggregatedRiskLevelDuringSignInRiskStateResourceDisplayNameResourceIdentityServicePrincipalIdServicePrincipalNameStatusTokenIssuerNameTokenIssuerTypeUserAgentUserDisplayNameUserIdUserPrincipalNameAADTenantIdType
08ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 11:04:42.689000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None02e6fd17c-1227-433e-b3a3-80a74374a7dcMicrosoft.aadiamMicrosoft.aadiamOfer Shezaf4ILAzure Portalc44b4083-3bb0-49c1-b47d-974e53cbdf3c[][\\r\\n {\\r\\n \"key\": \"Login Hint Present\",\\r\\n \"value\": \"True\"\\r\\n },\\r\\n {\\r\\n \"key\":...multiFactorAuthentication...None{'city': 'Tiberias', 'state': 'Hazafon', 'countryOrRegion': 'IL', 'geoCoordinates': {'latitude':...{}[]c8bfc04f-28bf-40b4-a9c1-07fd5bd9f800918none[][]nonenonenoneWindows Azure Service Management API797f4846-ba00-4fd7-ba43-dac1f8f63013{'errorCode': 0, 'additionalDetails': 'MFA requirement satisfied by claim in the token'}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.418...Ofer Shezaf9c459db5-0407-43fe-a2ea-126757297bebofshezaf@microsoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
18ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 11:19:36.626000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None04bdf65b2-99af-4bd4-ab7c-ffbc5a1d5038Microsoft.aadiamMicrosoft.aadiamMor Shabi4ILAzure Portalc44b4083-3bb0-49c1-b47d-974e53cbdf3c[][\\r\\n {\\r\\n \"key\": \"Login Hint Present\",\\r\\n \"value\": \"True\"\\r\\n },\\r\\n {\\r\\n \"key\":...multiFactorAuthentication...None{'city': 'Herzliya', 'state': 'Tel Aviv', 'countryOrRegion': 'IL', 'geoCoordinates': {'latitude'...{}[]4a40c63d-5e43-4af0-a0e5-2ae5df81e5003600none[][]nonenonenoneWindows Azure Service Management API797f4846-ba00-4fd7-ba43-dac1f8f63013{'errorCode': 0, 'additionalDetails': 'MFA requirement satisfied by claim in the token'}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.418...Mor Shabi7b77cfef-7ac7-4121-a834-561291927ad1moshabi@microsoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
28ecf8077-cf51-4820-aadd-14040956f35dAzure AD2020-10-01 11:19:40.787000+00:00/tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiamSign-in activity1.0SignInLogs0None04460b859-84c1-4751-bddb-b305516cbed4Microsoft.aadiamMicrosoft.aadiamMor Shabi4ILAzure Portalc44b4083-3bb0-49c1-b47d-974e53cbdf3c[][\\r\\n {\\r\\n \"key\": \"Login Hint Present\",\\r\\n \"value\": \"True\"\\r\\n },\\r\\n {\\r\\n \"key\":...singleFactorAuthentication...None{'city': 'Herzliya', 'state': 'Tel Aviv', 'countryOrRegion': 'IL', 'geoCoordinates': {'latitude'...{}[]4a40c63d-5e43-4af0-a0e5-2ae5c182e5001526none[][]nonenonenoneWindows Azure Service Management API797f4846-ba00-4fd7-ba43-dac1f8f63013{'errorCode': 0}AzureADMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.418...Mor Shabi7b77cfef-7ac7-4121-a834-561291927ad1moshabi@microsoft.com4b2462a4-bbee-495a-a0e1-f23ae524cc9cSigninLogs
\n", "

3 rows × 59 columns

\n", "
" ], "text/plain": [ " TenantId SourceSystem \\\n", "0 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "1 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "2 8ecf8077-cf51-4820-aadd-14040956f35d Azure AD \n", "\n", " TimeGenerated \\\n", "0 2020-10-01 11:04:42.689000+00:00 \n", "1 2020-10-01 11:19:36.626000+00:00 \n", "2 2020-10-01 11:19:40.787000+00:00 \n", "\n", " ResourceId \\\n", "0 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "1 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "2 /tenants/4b2462a4-bbee-495a-a0e1-f23ae524cc9c/providers/Microsoft.aadiam \n", "\n", " OperationName OperationVersion Category ResultType ResultSignature \\\n", "0 Sign-in activity 1.0 SignInLogs 0 None \n", "1 Sign-in activity 1.0 SignInLogs 0 None \n", "2 Sign-in activity 1.0 SignInLogs 0 None \n", "\n", " ResultDescription DurationMs CorrelationId \\\n", "0 0 2e6fd17c-1227-433e-b3a3-80a74374a7dc \n", "1 0 4bdf65b2-99af-4bd4-ab7c-ffbc5a1d5038 \n", "2 0 4460b859-84c1-4751-bddb-b305516cbed4 \n", "\n", " Resource ResourceGroup ResourceProvider Identity Level \\\n", "0 Microsoft.aadiam Microsoft.aadiam Ofer Shezaf 4 \n", "1 Microsoft.aadiam Microsoft.aadiam Mor Shabi 4 \n", "2 Microsoft.aadiam Microsoft.aadiam Mor Shabi 4 \n", "\n", " Location AlternateSignInName AppDisplayName \\\n", "0 IL Azure Portal \n", "1 IL Azure Portal \n", "2 IL Azure Portal \n", "\n", " AppId AuthenticationDetails \\\n", "0 c44b4083-3bb0-49c1-b47d-974e53cbdf3c [] \n", "1 c44b4083-3bb0-49c1-b47d-974e53cbdf3c [] \n", "2 c44b4083-3bb0-49c1-b47d-974e53cbdf3c [] \n", "\n", " AuthenticationMethodsUsed \\\n", "0 \n", "1 \n", "2 \n", "\n", " AuthenticationProcessingDetails \\\n", "0 [\\r\\n {\\r\\n \"key\": \"Login Hint Present\",\\r\\n \"value\": \"True\"\\r\\n },\\r\\n {\\r\\n \"key\":... \n", "1 [\\r\\n {\\r\\n \"key\": \"Login Hint Present\",\\r\\n \"value\": \"True\"\\r\\n },\\r\\n {\\r\\n \"key\":... \n", "2 [\\r\\n {\\r\\n \"key\": \"Login Hint Present\",\\r\\n \"value\": \"True\"\\r\\n },\\r\\n {\\r\\n \"key\":... \n", "\n", " AuthenticationRequirement ... IsRisky \\\n", "0 multiFactorAuthentication ... None \n", "1 multiFactorAuthentication ... None \n", "2 singleFactorAuthentication ... None \n", "\n", " LocationDetails \\\n", "0 {'city': 'Tiberias', 'state': 'Hazafon', 'countryOrRegion': 'IL', 'geoCoordinates': {'latitude':... \n", "1 {'city': 'Herzliya', 'state': 'Tel Aviv', 'countryOrRegion': 'IL', 'geoCoordinates': {'latitude'... \n", "2 {'city': 'Herzliya', 'state': 'Tel Aviv', 'countryOrRegion': 'IL', 'geoCoordinates': {'latitude'... \n", "\n", " MfaDetail NetworkLocationDetails OriginalRequestId \\\n", "0 {} [] c8bfc04f-28bf-40b4-a9c1-07fd5bd9f800 \n", "1 {} [] 4a40c63d-5e43-4af0-a0e5-2ae5df81e500 \n", "2 {} [] 4a40c63d-5e43-4af0-a0e5-2ae5c182e500 \n", "\n", " ProcessingTimeInMilliseconds RiskDetail RiskEventTypes RiskEventTypes_V2 \\\n", "0 918 none [] [] \n", "1 3600 none [] [] \n", "2 1526 none [] [] \n", "\n", " RiskLevelAggregated RiskLevelDuringSignIn RiskState \\\n", "0 none none none \n", "1 none none none \n", "2 none none none \n", "\n", " ResourceDisplayName ResourceIdentity \\\n", "0 Windows Azure Service Management API 797f4846-ba00-4fd7-ba43-dac1f8f63013 \n", "1 Windows Azure Service Management API 797f4846-ba00-4fd7-ba43-dac1f8f63013 \n", "2 Windows Azure Service Management API 797f4846-ba00-4fd7-ba43-dac1f8f63013 \n", "\n", " ServicePrincipalId ServicePrincipalName \\\n", "0 \n", "1 \n", "2 \n", "\n", " Status \\\n", "0 {'errorCode': 0, 'additionalDetails': 'MFA requirement satisfied by claim in the token'} \n", "1 {'errorCode': 0, 'additionalDetails': 'MFA requirement satisfied by claim in the token'} \n", "2 {'errorCode': 0} \n", "\n", " TokenIssuerName TokenIssuerType \\\n", "0 AzureAD \n", "1 AzureAD \n", "2 AzureAD \n", "\n", " UserAgent \\\n", "0 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.418... \n", "1 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.418... \n", "2 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.418... \n", "\n", " UserDisplayName UserId \\\n", "0 Ofer Shezaf 9c459db5-0407-43fe-a2ea-126757297beb \n", "1 Mor Shabi 7b77cfef-7ac7-4121-a834-561291927ad1 \n", "2 Mor Shabi 7b77cfef-7ac7-4121-a834-561291927ad1 \n", "\n", " UserPrincipalName AADTenantId Type \n", "0 ofshezaf@microsoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c SigninLogs \n", "1 moshabi@microsoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c SigninLogs \n", "2 moshabi@microsoft.com 4b2462a4-bbee-495a-a0e1-f23ae524cc9c SigninLogs \n", "\n", "[3 rows x 59 columns]" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "accounts = [\n", " \"ofshezaf\",\n", " \"moshabi\",\n", "]\n", "Account.AzureSentinel.list_aad_signins_for_account(account_name=accounts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Combining multiple iterables and single-valued parameters\n", "\n", "The same rules as outline earlier for multiple parameters of different types apply to data queries" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
UserPrincipalNameIdentity
0ofshezaf@microsoft.comOfer Shezaf
1moshabi@microsoft.comMor Shabi
2moshabi@microsoft.comMor Shabi
\n", "
" ], "text/plain": [ " UserPrincipalName Identity\n", "0 ofshezaf@microsoft.com Ofer Shezaf\n", "1 moshabi@microsoft.com Mor Shabi\n", "2 moshabi@microsoft.com Mor Shabi" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "project = \"| project UserPrincipalName, Identity\"\n", "Account.AzureSentinel.list_aad_signins_for_account(account_name=accounts, add_query_items=project)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using DataFrames as input\n", "\n", "This is similar to using dataframes for other pivot functions.\n", "\n", "We must use the `data` parameter to specify the input dataframe.\n", "You supply the column name from your input dataframe as the value of\n", "the parameters expected by the function." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
User
0ofshezaf
1moshabi
\n", "
" ], "text/plain": [ " User\n", "0 ofshezaf\n", "1 moshabi" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "account_df = pd.DataFrame(accounts, columns=[\"User\"])\n", "display(account_df)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we have our dataframe:\n", "\n", "- we specify `account_df` as the value of the `data` parameter.\n", "- in our source (input) dataframe, the column that we want to use as the input value for each query is `User`\n", "- we specify that column name as the value of the function parameter\n", "\n", "On each iteration, the column value from a subsequent row will be extracted and \n", "given as the parameter value for the function parameter.\n", "\n", "> Note:
\n", "> If the function parameter type is a \"list\" type - i.e. it expects a list of values
\n", "> the parameter value will be sent as a list and only a single query is executed.
\n", "> If the query function has multiple \"list\" type parameters, these will be
\n", "> populated in the same way.\n", "\n", "> Note2:
\n", "> If you have multiple parameters fed by multiple input columns AND one or more
\n", "> of the function parameters *is not* a list type, the the query will be broken
\n", "> into queries for each row. Each sub-query getting its values from a single row
\n", "> of the input dataframe." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "try {IPython.notebook.kernel.execute(\"NOTEBOOK_URL = '\" + window.location + \"'\");} catch(err) {;}" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
UserPrincipalNameIdentity
0ofshezaf@microsoft.comOfer Shezaf
1moshabi@microsoft.comMor Shabi
2moshabi@microsoft.comMor Shabi
\n", "
" ], "text/plain": [ " UserPrincipalName Identity\n", "0 ofshezaf@microsoft.com Ofer Shezaf\n", "1 moshabi@microsoft.com Mor Shabi\n", "2 moshabi@microsoft.com Mor Shabi" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Account.AzureSentinel.list_aad_signins_for_account(data=account_df, account_name=\"User\", add_query_items=project)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Threat Intelligence Lookups\n", "\n", "These work in the same way as the functions described earlier. However,\n", "there are a few peculiarities of the Threat Intel functions:\n", "\n", "### Provider-specific functions\n", "Queries for individual providers are broken out into separate functions\n", "You will see multiple `lookup_ipv4` functions, for example: one with no suffix\n", "and one for each individual TI provider with a corresponding suffix.\n", "This is a convenience to let you use a specific provider more quickly. You\n", "can still use the generic function (`lookup_ipv4`) and supply a providers parameter\n", "to indicate which providers you want to use.\n", "\n", "### IPV4 and IPV6\n", "Some providers treat these interchangably and use the same endpoint for both.\n", "Other providers do not explicitly support IPV6 (e.g. the Tor exit nodes provider).\n", "Still others (notably OTX) use different endpoints for IPv4 and IPv6.\n", "\n", "If you are querying IPv4 you can use either the `lookup_ip` function or one\n", "of the `lookup_ipv4` functions. In most cases, you can also use these functions\n", "for a mixture of IPv4 and v6 addresses. However, in cases where a provider\n", "does not support IPv6 or uses a different endpoint for IPv6 queries you\n", "will get no responses.\n", "\n", "### Entity mapping to IoC Types\n", "This table shows the mapping between and entity type\n", "and IoC Types:\n", "\n", "| Entity | IoCType |\n", "| :--------- | :----------------- |\n", "| IpAddress | ipv4, ipv6 |\n", "| Dns | domain |\n", "| File | filehash (incl |\n", "| | md5, sha1, sha256) |\n", "| Url | url |\n", "\n", "> Note: Where you are using a File entity as a parameter, there is a complication.
\n", "> A file entity can have multiple hash values (md5, sha1, sha256 and even sha256 authenticode).
\n", "> The `file_hash` attibute of File is used as the default parameter.
\n", "> In cases where a file has multiple hashes the highest priority hash (in order
\n", "> sha256, sha1, md5, sha256ac) is returned.
\n", "> If you are not using file entities as parameters (and specifying the input values
\n", "> explicitly or via a Dataframe or iterable, you can ignore this." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "lookup_ip function\n", "lookup_ipv4 function\n", "lookup_ipv4_OTX function\n", "lookup_ipv4_Tor function\n", "lookup_ipv4_VirusTotal function\n", "lookup_ipv4_XForce function\n", "lookup_ipv6 function\n", "lookup_ipv6_OTX function\n" ] } ], "source": [ "IpAddress.ti()" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IocIocTypeSafeIocQuerySubtypeProviderResultSeverityDetailsRawResultReferenceStatus
0fkksjobnn43.orgdnsfkksjobnn43.orgNoneOTXTruehigh{'pulse_count': 35, 'names': ['Jaff - Malware Domain Feed V2', 'Jaff - Malware Domain Feed V2', ...{'indicator': 'fkksjobnn43.org', 'alexa': 'http://www.alexa.com/siteinfo/fkksjobnn43.org', 'whoi...https://otx.alienvault.com/api/v1/indicators/domain/fkksjobnn43.org/general0
0fkksjobnn43.orgdnsNoneOPRTruewarning{'rank': None, 'error': 'Domain not found'}{'status_code': 404, 'error': 'Domain not found', 'page_rank_integer': 0, 'page_rank_decimal': 0...https://openpagerank.com/api/v1.0/getPageRank?domains[0]=fkksjobnn43.org0
0fkksjobnn43.orgdnsfkksjobnn43.orgNoneVirusTotalTrueinformation{'verbose_msg': 'Domain found in dataset', 'response_code': 1, 'detected_urls': [], 'positives':...{'undetected_downloaded_samples': [], 'whois_timestamp': 1603963073, 'detected_downloaded_sample...https://www.virustotal.com/vtapi/v2/domain/report0
0fkksjobnn43.orgdnsfkksjobnn43.orgNoneXForceTrueinformation{'score': 0, 'cats': None, 'categoryDescriptions': None, 'reason': None, 'reasonDescription': 0,...{'result': {'url': 'fkksjobnn43.org', 'cats': {'General Business': True}, 'score': 1, 'categoryD...https://api.xforce.ibmcloud.com/url/fkksjobnn43.org0
\n", "
" ], "text/plain": [ " Ioc IocType SafeIoc QuerySubtype Provider Result \\\n", "0 fkksjobnn43.org dns fkksjobnn43.org None OTX True \n", "0 fkksjobnn43.org dns None OPR True \n", "0 fkksjobnn43.org dns fkksjobnn43.org None VirusTotal True \n", "0 fkksjobnn43.org dns fkksjobnn43.org None XForce True \n", "\n", " Severity \\\n", "0 high \n", "0 warning \n", "0 information \n", "0 information \n", "\n", " Details \\\n", "0 {'pulse_count': 35, 'names': ['Jaff - Malware Domain Feed V2', 'Jaff - Malware Domain Feed V2', ... \n", "0 {'rank': None, 'error': 'Domain not found'} \n", "0 {'verbose_msg': 'Domain found in dataset', 'response_code': 1, 'detected_urls': [], 'positives':... \n", "0 {'score': 0, 'cats': None, 'categoryDescriptions': None, 'reason': None, 'reasonDescription': 0,... \n", "\n", " RawResult \\\n", "0 {'indicator': 'fkksjobnn43.org', 'alexa': 'http://www.alexa.com/siteinfo/fkksjobnn43.org', 'whoi... \n", "0 {'status_code': 404, 'error': 'Domain not found', 'page_rank_integer': 0, 'page_rank_decimal': 0... \n", "0 {'undetected_downloaded_samples': [], 'whois_timestamp': 1603963073, 'detected_downloaded_sample... \n", "0 {'result': {'url': 'fkksjobnn43.org', 'cats': {'General Business': True}, 'score': 1, 'categoryD... \n", "\n", " Reference \\\n", "0 https://otx.alienvault.com/api/v1/indicators/domain/fkksjobnn43.org/general \n", "0 https://openpagerank.com/api/v1.0/getPageRank?domains[0]=fkksjobnn43.org \n", "0 https://www.virustotal.com/vtapi/v2/domain/report \n", "0 https://api.xforce.ibmcloud.com/url/fkksjobnn43.org \n", "\n", " Status \n", "0 0 \n", "0 0 \n", "0 0 \n", "0 0 " ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from msticpy.datamodel.entities import Url, Dns, File\n", "dns = Dns(DomainName=\"fkksjobnn43.org\")\n", "\n", "Dns.ti.lookup_dns(dns)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IocIocTypeSafeIocQuerySubtypeProviderResultSeverityDetailsRawResultReferenceStatus
0fkksjobnn43.orgdnsfkksjobnn43.orgNoneOTXTruehigh{'pulse_count': 35, 'names': ['Jaff - Malware Domain Feed V2', 'Jaff - Malware Domain Feed V2', ...{'indicator': 'fkksjobnn43.org', 'alexa': 'http://www.alexa.com/siteinfo/fkksjobnn43.org', 'whoi...https://otx.alienvault.com/api/v1/indicators/domain/fkksjobnn43.org/general0
0fkksjobnn43.orgdnsNoneOPRTruewarning{'rank': None, 'error': 'Domain not found'}{'status_code': 404, 'error': 'Domain not found', 'page_rank_integer': 0, 'page_rank_decimal': 0...https://openpagerank.com/api/v1.0/getPageRank?domains[0]=fkksjobnn43.org0
0fkksjobnn43.orgdnsfkksjobnn43.orgNoneVirusTotalTrueinformation{'verbose_msg': 'Domain found in dataset', 'response_code': 1, 'detected_urls': [], 'positives':...{'undetected_downloaded_samples': [], 'whois_timestamp': 1603963073, 'detected_downloaded_sample...https://www.virustotal.com/vtapi/v2/domain/report0
0fkksjobnn43.orgdnsfkksjobnn43.orgNoneXForceTrueinformation{'score': 0, 'cats': None, 'categoryDescriptions': None, 'reason': None, 'reasonDescription': 0,...{'result': {'url': 'fkksjobnn43.org', 'cats': {'General Business': True}, 'score': 1, 'categoryD...https://api.xforce.ibmcloud.com/url/fkksjobnn43.org0
\n", "
" ], "text/plain": [ " Ioc IocType SafeIoc QuerySubtype Provider Result \\\n", "0 fkksjobnn43.org dns fkksjobnn43.org None OTX True \n", "0 fkksjobnn43.org dns None OPR True \n", "0 fkksjobnn43.org dns fkksjobnn43.org None VirusTotal True \n", "0 fkksjobnn43.org dns fkksjobnn43.org None XForce True \n", "\n", " Severity \\\n", "0 high \n", "0 warning \n", "0 information \n", "0 information \n", "\n", " Details \\\n", "0 {'pulse_count': 35, 'names': ['Jaff - Malware Domain Feed V2', 'Jaff - Malware Domain Feed V2', ... \n", "0 {'rank': None, 'error': 'Domain not found'} \n", "0 {'verbose_msg': 'Domain found in dataset', 'response_code': 1, 'detected_urls': [], 'positives':... \n", "0 {'score': 0, 'cats': None, 'categoryDescriptions': None, 'reason': None, 'reasonDescription': 0,... \n", "\n", " RawResult \\\n", "0 {'indicator': 'fkksjobnn43.org', 'alexa': 'http://www.alexa.com/siteinfo/fkksjobnn43.org', 'whoi... \n", "0 {'status_code': 404, 'error': 'Domain not found', 'page_rank_integer': 0, 'page_rank_decimal': 0... \n", "0 {'undetected_downloaded_samples': [], 'whois_timestamp': 1603963073, 'detected_downloaded_sample... \n", "0 {'result': {'url': 'fkksjobnn43.org', 'cats': {'General Business': True}, 'score': 1, 'categoryD... \n", "\n", " Reference \\\n", "0 https://otx.alienvault.com/api/v1/indicators/domain/fkksjobnn43.org/general \n", "0 https://openpagerank.com/api/v1.0/getPageRank?domains[0]=fkksjobnn43.org \n", "0 https://www.virustotal.com/vtapi/v2/domain/report \n", "0 https://api.xforce.ibmcloud.com/url/fkksjobnn43.org \n", "\n", " Status \n", "0 0 \n", "0 0 \n", "0 0 \n", "0 0 " ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Dns.ti.lookup_dns(value=\"fkksjobnn43.org\")" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IocIocTypeSafeIocQuerySubtypeProviderResultSeverityDetailsRawResultReferenceStatus
002a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbdsha256_hash02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbdNoneVirusTotalTruehigh{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '02a7977d...{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware...https://www.virustotal.com/vtapi/v2/file/report0
106b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdafsha256_hash06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdafNoneVirusTotalTruehigh{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06b020a3...{'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201...https://www.virustotal.com/vtapi/v2/file/report0
206c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ffsha256_hash06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ffNoneVirusTotalTruehigh{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06c676bf...{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware...https://www.virustotal.com/vtapi/v2/file/report0
\n", "
" ], "text/plain": [ " Ioc \\\n", "0 02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd \n", "1 06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf \n", "2 06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff \n", "\n", " IocType \\\n", "0 sha256_hash \n", "1 sha256_hash \n", "2 sha256_hash \n", "\n", " SafeIoc \\\n", "0 02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd \n", "1 06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf \n", "2 06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff \n", "\n", " QuerySubtype Provider Result Severity \\\n", "0 None VirusTotal True high \n", "1 None VirusTotal True high \n", "2 None VirusTotal True high \n", "\n", " Details \\\n", "0 {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '02a7977d... \n", "1 {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06b020a3... \n", "2 {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06c676bf... \n", "\n", " RawResult \\\n", "0 {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware... \n", "1 {'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201... \n", "2 {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware... \n", "\n", " Reference Status \n", "0 https://www.virustotal.com/vtapi/v2/file/report 0 \n", "1 https://www.virustotal.com/vtapi/v2/file/report 0 \n", "2 https://www.virustotal.com/vtapi/v2/file/report 0 " ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hashes = [\n", " \"02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd\",\n", " \"06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf\",\n", " \"06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff\",\n", "]\n", "\n", "File.ti.lookup_file_hash_VirusTotal(hashes)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Lookup from a DataFrame\n", "\n", "To specify the source column you can use either \"column\" or \"obs_column\"" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
hashrefdesc
002a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbditem_0stuff
106b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdafitem_1stuff
206c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ffitem_2stuff
\n", "
" ], "text/plain": [ " hash ref \\\n", "0 02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd item_0 \n", "1 06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf item_1 \n", "2 06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff item_2 \n", "\n", " desc \n", "0 stuff \n", "1 stuff \n", "2 stuff " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IocIocTypeSafeIocQuerySubtypeProviderResultSeverityDetailsRawResultReferenceStatus
002a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbdsha256_hash02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbdNoneVirusTotalTruehigh{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '02a7977d...{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware...https://www.virustotal.com/vtapi/v2/file/report0
106b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdafsha256_hash06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdafNoneVirusTotalTruehigh{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06b020a3...{'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201...https://www.virustotal.com/vtapi/v2/file/report0
206c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ffsha256_hash06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ffNoneVirusTotalTruehigh{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06c676bf...{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware...https://www.virustotal.com/vtapi/v2/file/report0
\n", "
" ], "text/plain": [ " Ioc \\\n", "0 02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd \n", "1 06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf \n", "2 06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff \n", "\n", " IocType \\\n", "0 sha256_hash \n", "1 sha256_hash \n", "2 sha256_hash \n", "\n", " SafeIoc \\\n", "0 02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd \n", "1 06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf \n", "2 06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff \n", "\n", " QuerySubtype Provider Result Severity \\\n", "0 None VirusTotal True high \n", "1 None VirusTotal True high \n", "2 None VirusTotal True high \n", "\n", " Details \\\n", "0 {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '02a7977d... \n", "1 {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06b020a3... \n", "2 {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'resource': '06c676bf... \n", "\n", " RawResult \\\n", "0 {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware... \n", "1 {'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201... \n", "2 {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetectVM.malware... \n", "\n", " Reference Status \n", "0 https://www.virustotal.com/vtapi/v2/file/report 0 \n", "1 https://www.virustotal.com/vtapi/v2/file/report 0 \n", "2 https://www.virustotal.com/vtapi/v2/file/report 0 " ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hashes_df = pd.DataFrame(\n", " [(fh, f\"item_{idx}\", \"stuff\") for idx, fh in enumerate(hashes)],\n", " columns=[\"hash\", \"ref\", \"desc\"],\n", ")\n", "display(hashes_df)\n", "File.ti.lookup_file_hash_VirusTotal(data=hashes_df, column=\"hash\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chaining pivot and other functions\n", "\n", "Because pivot functions can take dataframes as inputs and return them\n", "as outputs, you can create chains of pivot functions.\n", "You can also add other items to the chain that input or output\n", "dataframes.\n", "\n", "For example, you could build a chain that included the following:\n", "- take IP addresses from firewall alerts\n", "- lookup the IPs in Threat Intel providers filtering those that have high severity\n", "- lookup the any remote logon events sourced at those IPs\n", "- display a timeline of the logons\n", "\n", "To make building these types of pipelines easier we've implemented some\n", "pandas helper functions. These are available in the `mp_pivot`\n", "property of pandas DataFrames, once Pivot is imported.\n", "\n", "### mp_pivot.run\n", "\n", "`run` lets you run a pivot function as a pandas pipeline operation.\n", " \n", "Let's take an example of a simple pivot function using a dataframe as input\n", "```\n", " IpAddress.util.whois(data=my_df, column=\"Ioc\")\n", "```\n", "\n", "We can us mp_pivot.run to do this:\n", "```\n", " (\n", " my_df\n", " .query(\"UserCount > 1\")\n", " .mp_pivot.run(IpAddress.util.whois, column=\"Ioc\")\n", " .drop_duplicates()\n", " )\n", "```\n", "The pandas extension takes care of the `data=my_df` parameter. We still have\n", "to add any other required parameters (like the column specification in this case.\n", "When it runs it returns its output as a DataFrame and the next operation\n", "(drop_duplicates()) runs on this output.\n", "\n", "Depending on the scenario you might want to preserve the existing dataframe\n", "contents (most of the pivot functions only return the results of their specific\n", "operation - e.g. whois returns ASN information for an IP address). You\n", "can carry the columns of the input dataframe over to the output from \n", "the pivot function by adding a `join` parameter to the mp_pivot.run() call.\n", "Use a \"left\" to keep all of the input rows regardless of whether the pivot\n", "function returned a result for that row.\n", "Use an \"inner\" join to return only rows where the input had a positive result\n", "in the pivot function.\n", "```\n", " .mp_pivot.run(IpAddress.util.whois, column=\"Ioc\", join=\"inner\")\n", "```\n", "\n", "There are also a couple of convenience functions. These only work in\n", "an IPython/Jupyter environment.\n", "\n", "## mp_pivot.display\n", "\n", "`mp_pivot.display` will display the intermediate results of the dataframe in the middle\n", "of a pipeline. It does not change the data at all, but does give you the \n", "chance to display a view of the data partway through processing. This\n", "is useful for debugging but its main purpose is to give you a way to\n", "show partial results without having to break the pipeline into pieces\n", "and create unnecessary throw-away variables that will add bulk to your\n", "code and clutter to your memory.\n", "\n", "`display` supports some options that you can use to modify the displayed\n", "output:\n", "\n", "- title - displays a title above the data\n", "- cols - a list of columns to display (others are hidden)\n", "- query - you can filter the output using a df.query() string. See https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html?highlight=query#pandas.DataFrame.query\n", " for more details\n", "- head - limits the display to the first `head` rows\n", "\n", "These options do not affect the data being passed through the pipeline -\n", "only how the intermediate output is displayed.\n", "\n", "# mp_pivot.tee\n", "`mp_pivot.tee` behaves a little like the Linux \"tee\" command. It allows the\n", "data to pass through unchanged but allows you to create a variable that\n", "is a snapshot of the data at that point in the pipeline. It takes\n", "a parameter `var_name` and assigns the current DataFrame instance\n", "to that name. So, when your pipeline has run you can access partial results (again,\n", "without having to break up your pipeline to do so).\n", "\n", "By default, it will not overwrite an existing variable of the same name\n", "unless you specify `clobber=True` in the call to `tee`.\n", "\n", "## Example\n", "The example below shows the use of mp_pivot.run and mp_pivot.display.\n", "\n", "This takes an existing DataFrame - suspcious_ips - and:\n", "\n", "- displays the top 5 rows of the dataframe\n", "- checks for threat intelligence reports on any of the IP addresses\n", "- uses pandas `query` to filter only the high severity hits\n", "- calls the whois pivot function to obtain ownership information for these IPs\n", " (note that we join the results of the previous step here usine `join='left'`\n", " so our output will be all TI result data plus whois data\n", "- calls a pivot data query to check for Azure Active Directory logins that\n", " have an IP address source that matches any of these addresses.\n", " \n", "The final step uses another MSTICPy pandas extension to plot the login attempts\n", "on a timeline chart." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [], "source": [ "suspicious_ips = [\n", " \"113.190.36.2\",\n", " \"118.163.135.17\",\n", " \"118.163.135.18\",\n", " \"118.163.97.19\",\n", " \"125.34.240.33\",\n", " \"135.26.152.186\",\n", " \"165.225.17.6\",\n", " \"177.135.101.5\",\n", " \"177.159.99.89\",\n", " \"177.19.187.79\",\n", " \"186.215.197.15\",\n", " \"186.215.198.137\",\n", " \"189.59.5.81\",\n", "]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(\n", " suspicious_ips\n", " .mp_pivot.display(title=f\"Initial IPs {len(suspicious_ips)}\", head=5)\n", " # Lookup IPs at VT\n", " .mp_pivot.run(IpAddress.ti.lookup_ipv4_VirusTotal, column=\"IPAddress\")\n", " # Filter on high severity\n", " .query(\"Severity == 'high'\")\n", " .mp_pivot.run(IpAddress.util.whois, column=\"Ioc\", join=\"left\")\n", " .mp_pivot.display(title=\"TI High Severity IPs\", head=5)\n", " # Query IPs that have login attempts\n", " .mp_pivot.run(IpAddress.AzureSentinel.list_aad_signins_for_ip, ip_address_list=\"Ioc\")\n", " # Send the output of this to a plot\n", " .mp_timeline.plot(\n", " title=\"High Severity IPs with Logon attempts\",\n", " source_columns=[\"UserPrincipalName\", \"IPAddress\", \"ResultType\", \"ClientAppUsed\", \"UserAgent\", \"Location\"],\n", " group_by=\"UserPrincipalName\"\n", " )\n", ")" ] }, { "attachments": { "0f98df03-f8db-4ddc-a8cd-2535ff315af5.png": { "image/png": "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lZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu4rh1Acf27tvvT/sYfSM7IIK2TU4Zz/73N5+7YRduDA97KEMDNkFlZiyi3mEoqJwB4AMFO4oExasUCG7Rt+5s+dsx9I9tvIbm+3t104Mezg9IbugQnYNzoN3PG5L//cGe/boC8MeysCQ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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "### Example output from pipelined functions\n", "\n", "This is what the pipelined functions should output (although the results\n", "will obviously not be the same for your environment).\n", "\n", "![image.png](attachment:0f98df03-f8db-4ddc-a8cd-2535ff315af5.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adding custom functions to the pivot interface\n", "\n", "To do this you need the following information\n", "\n", "| Item | Description | Required |\n", "| :--------------------- | :-------------------------- | :---------- |\n", "| src_module | The src_module to containing the class or function | Yes |\n", "| class | The class containing function | No |\n", "| src_func_name | The name of the function to wrap | Yes |\n", "| func_new_name | Rename the function | No |\n", "| input type | The input type that the wrapped function expects (dataframe iterable value) | Yes |\n", "| entity_map | Mapping of entity and attribute used for function | Yes |\n", "| func_df_param_name | The param name that the function uses as input param for DataFrame | If DF input |\n", "| func_df_col_param_name | The param name that function uses to identify the input column name | If DF input |\n", "| func_out_column_name | Name of the column in the output DF to use as a key to join | If DF output|\n", "| func_static_params | dict of static name/value params always sent to the function | No |\n", "| func_input_value_arg | Name of the param that the wrapped function uses for its input value | No |\n", "| can_iterate | True if the function supports being called multiple times | No |\n", "| entity_container_name | The name of the container in the entity where the func will appear | No |\n", "\n", "\n", "The entity_map controls where the pivot function will be added. Each entry\n", "requires an Entity name (see msticpy.datamodel.entities) and an entity\n", "attribute name. This is only used if an instance of the entity is used\n", "as a parameter to the function. For `IpAddress` in the example below,\n", "the pivot function will try to extract the value of the `Address` attribute\n", "when an instance of IpAddress is used as a function parameter.\n", "\n", "```yaml\n", " entity_map:\n", " IpAddress: Address\n", " Host: HostName\n", " Account: Name\n", "```\n", "\n", "This means that you can specify different attributes of the same entity\n", "for different functions (or even for two instances of the same function)\n", "\n", "The `func_df_param_name` and `func_df_col_param_name` are needed only if\n", "the source function takes a dataframe and column name as input parameters.\n", "\n", "`func_out_column_name` is relevant if the source function returns a\n", "dataframe. In order to join input data with output data this needs to\n", "be the column in the output that has the same value as the function\n", "input (e.g. if you are processing IP addresses and the column name\n", "in the output DF containing the IP is named \"ip_addr\", put \"ip_addr\" here.)\n", "\n", "When you have this information create or add this to a yaml file\n", "with the top-level element `pivot_providers`.\n", "\n", "Example from the msticpy ip_utils `who_is` function\n", "```yaml\n", "pivot_providers:\n", " ...\n", " who_is:\n", " src_module: msticpy.sectools.ip_utils\n", " src_func_name: get_whois_df\n", " func_new_name: whois\n", " input_type: dataframe\n", " entity_map:\n", " IpAddress: Address\n", " func_df_param_name: data\n", " func_df_col_param_name: ip_column\n", " func_out_column_name: ip\n", " func_static_params:\n", " whois_col: whois_result\n", " func_input_value_arg: ip_address\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This doesn't currently support creating pivots from functions\n", "defined inline (in the notebook)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you have your yaml definition file you can call\n", "```python\n", " Pivot.register_pivot_providers(\n", " pivot_reg_path=path_to_your_yaml,\n", " namespace=globals(),\n", " def_container=\"my_container\",\n", " force_container=True\n", " )\n", "```\n", "\n", "Note, this is not persistent. You will need to call this each time you\n", "start a new session." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### register_pivot_providers docstring\n", "\n", "```python\n", "Pivot.register_pivot_providers(\n", " pivot_reg_path: str,\n", " namespace: Dict[str, Any] = None,\n", " def_container: str = 'custom',\n", " force_container: bool = False,\n", ")\n", "Docstring:\n", "Register pivot functions from configuration file.\n", "\n", "Parameters\n", "----------\n", "file_path : str\n", " Path to config yaml file\n", "namespace : Dict[str, Any], optional\n", " Namespace to search for existing instances of classes, by default None\n", "container : str, optional\n", " Container name to use for entity pivot functions, by default \"other\"\n", "force_container : bool, optional\n", " Force `container` value to be used even if entity definitions have\n", " specific setting for a container name, by default False\n", "```" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\u001b[1;31mSignature:\u001b[0m\n", "\u001b[0mPivot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mregister_pivot_providers\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m\n", "\u001b[0m \u001b[0mpivot_reg_path\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n", "\u001b[0m \u001b[0mnamespace\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n", "\u001b[0m \u001b[0mdef_container\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'custom'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n", "\u001b[0m \u001b[0mforce_container\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mbool\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n", "\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mDocstring:\u001b[0m\n", "Register pivot functions from configuration file.\n", "\n", "Parameters\n", "----------\n", "file_path : str\n", " Path to config yaml file\n", "namespace : Dict[str, Any], optional\n", " Namespace to search for existing instances of classes, by default None\n", "container : str, optional\n", " Container name to use for entity pivot functions, by default \"other\"\n", "force_container : bool, optional\n", " Force `container` value to be used even if entity definitions have\n", " specific setting for a container name, by default False\n", "\n", "Raises\n", "------\n", "ValueError\n", " An entity specified in the config file is not recognized.\n", "\u001b[1;31mFile:\u001b[0m e:\\src\\microsoft\\msticpy\\msticpy\\datamodel\\pivot.py\n", "\u001b[1;31mType:\u001b[0m function\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "Pivot.register_pivot_providers?" ] } ], "metadata": { "kernelspec": { "display_name": "Python (condadev)", "language": "python", "name": "condadev" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.9" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "00b3afb04d3d4c249eec82505ede8571": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "0171f82d179d4d8dae5e75c69951bd77": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_d8231c08bf204f62a9fea1008abce911", "IPY_MODEL_be1842c22e6443978c7ca2e74795ac86", "IPY_MODEL_8afe9fa7ab3e411dab31b91ec8d75934" ], "layout": "IPY_MODEL_4c9dbb0aea5e41bf83724ea7854cd18a" } }, "03caa019c27d4fc4810c94bf771e3a55": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DatePickerModel", "state": { "description": "Origin Date", "disabled": false, "layout": "IPY_MODEL_7c562e7e2a634abbb51aa74236187d45", "style": "IPY_MODEL_7c341a3953d94e23a02bdb9a8bb2fcbc", "value": { "date": 2, "month": 9, "year": 2020 } } }, "080317bd2e7d4bec9e473c248b53e618": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "0abd2afa11b845c0b7733ed8cd07773c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_e6b95b26dad0430cb7310db1f8bdca93", "IPY_MODEL_0e6b74e6ffd34e1cae53130ce65be13d", "IPY_MODEL_0171f82d179d4d8dae5e75c69951bd77" ], "layout": "IPY_MODEL_9f8ce116e98c4350bde6ffb13c8a8671" } }, "0e6b74e6ffd34e1cae53130ce65be13d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_03caa019c27d4fc4810c94bf771e3a55", "IPY_MODEL_c0e214f35451463a8a10f016ee5c2a3f" ], "layout": "IPY_MODEL_4c19c4fdb2a44543a24e70d360d8ff16" } }, "0fb4d78ab17b4f1b8ffd1bd6a6dfe771": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "103045fdb6fa401284794e05a8e30c39": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "11c65f0b4d4d46229c8418f8ead4cb2a": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DatePickerModel", "state": { "description": "Origin Date", "disabled": false, "layout": "IPY_MODEL_0fb4d78ab17b4f1b8ffd1bd6a6dfe771", "style": "IPY_MODEL_2597350d74c04818b7d2a344de18acc0", "value": { "date": 2, "month": 9, "year": 2020 } } }, "14e2297c26e94e81aa3c756ad7225e5b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "170e4e7b815a465788315d45d2e764c4": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "80%" } }, "1748df15449d422fb9c5d10c89a28996": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query start time (UTC):", "layout": "IPY_MODEL_814079969a5f4ae0810cb7fa00cd8023", "style": "IPY_MODEL_d18e9480e5334ef7bc37b425b1b41eb4", "value": "2020-12-02 18:01:26.726226" } }, "1c13751ac3df46b380cff6a7478ae7fd": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "1f4168247e8d42babed6e8db2b6245ee": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_8ff6ccf603dd4837ac953965c0059b74", "IPY_MODEL_8e6910adf37f425496f17afbdc8be8f0" ], "layout": "IPY_MODEL_b445588f3a2847199263a89299e51073" } }, "1f4b37521ffb4f418b4d74f5b5a6cad3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "1f6acf50e7f643c394028dc573df87a3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query end time (UTC) : ", "layout": "IPY_MODEL_ad1fbba004364d5a93b3fef2a2e4f228", "style": "IPY_MODEL_1f4b37521ffb4f418b4d74f5b5a6cad3", "value": "2020-10-02 00:00:00" } }, "20b974cb18904e73ac6ab7a5f623d642": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "initial" } }, "21397bf979b4416c98f6e99091978634": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "layout": "IPY_MODEL_00b3afb04d3d4c249eec82505ede8571", "style": "IPY_MODEL_5f9bdccc86824e6bb56cf3cf1bf01bc0", "value": "

Set time range for pivot functions.

" } }, "21b08274c80c4b2fb0938d772f581073": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "2597350d74c04818b7d2a344de18acc0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "2670399a49dc48a68da10f9e2d8aa064": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "33e39e2bdb674c009a20ca2715dca504": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "355a872f37e84f8694203d0289527173": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "374287b971434beab6c082fd32926f07": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Time (24hr)", "layout": "IPY_MODEL_b1a8f10add46434884cddc2b4f4c287f", "style": "IPY_MODEL_a9af168004bb449c91396cfb8b544e39", "value": "00:00:00" } }, "3e72f51be72e47d5b3a80e7cae444c98": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "43ae3c8c925c4c5a962f62959045cbb4": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_11c65f0b4d4d46229c8418f8ead4cb2a", "IPY_MODEL_374287b971434beab6c082fd32926f07" ], "layout": "IPY_MODEL_9b34eb853e364a28a2f6feebac6e9604" } }, "45823fb741ce4fc19e7cfe35b184e401": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntRangeSliderModel", "state": { "_model_name": "IntRangeSliderModel", "_view_name": "IntRangeSliderView", "description": "Time Range (day):", "layout": "IPY_MODEL_170e4e7b815a465788315d45d2e764c4", "max": 4, "min": -4, "style": "IPY_MODEL_d7df3167b4094f418b86c9aec984efca", "value": [ -1, 0 ] } }, "458ecdb873e44fc98ddbf0f5b7ba7597": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "4c19c4fdb2a44543a24e70d360d8ff16": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "4c9dbb0aea5e41bf83724ea7854cd18a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "515037898d6f486b8e1d80a0353c945e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "layout": "IPY_MODEL_d3ea736ab63e46fcb855cb15f36c33ae", "style": "IPY_MODEL_080317bd2e7d4bec9e473c248b53e618", "value": "

Set time range for pivot functions.

" } }, "528c3cff29ea4b3f89be5624d3802078": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "53bac414032846588fe2cd53c96fbd9c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "5f9bdccc86824e6bb56cf3cf1bf01bc0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "6c06bb67a8d2463c8ea5616ddf8c1715": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_45823fb741ce4fc19e7cfe35b184e401", "IPY_MODEL_1748df15449d422fb9c5d10c89a28996", "IPY_MODEL_bcb4d3ca36424c32b2fb717d6caa3a2f" ], "layout": "IPY_MODEL_2670399a49dc48a68da10f9e2d8aa064" } }, "6e0b2e6f9db74b8ca3640fd5deef48ef": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "7c341a3953d94e23a02bdb9a8bb2fcbc": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "7c562e7e2a634abbb51aa74236187d45": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "7e831e806eb04bc9a49cb2a2ecb43e4d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "7ea03c4da997489f891d5adb77703aef": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "initial" } }, "814079969a5f4ae0810cb7fa00cd8023": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "836ff4af177546dfad48b958b7028585": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query start time (UTC):", "layout": "IPY_MODEL_e33baf0bb59749ff856bca0b611ce374", "style": "IPY_MODEL_7e831e806eb04bc9a49cb2a2ecb43e4d", "value": "2020-10-01 00:00:00" } }, "861f59f0453a4c818a9b10a04c631679": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntRangeSliderModel", "state": { "_model_name": "IntRangeSliderModel", "_view_name": "IntRangeSliderView", "description": "Time Range (hour):", "layout": "IPY_MODEL_a4fba06a69cc4ac08646ee8d82af2055", "max": 4, "min": -96, "style": "IPY_MODEL_20b974cb18904e73ac6ab7a5f623d642", "value": [ -24, 0 ] } }, "866de96e9adf462399404d48540ba8a0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "889e46dfa37d4e2588f6046122a25cc3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_515037898d6f486b8e1d80a0353c945e", "IPY_MODEL_1f4168247e8d42babed6e8db2b6245ee", "IPY_MODEL_6c06bb67a8d2463c8ea5616ddf8c1715" ], "layout": "IPY_MODEL_da7a5ba1509a4f2796cde97bf0f75beb" } }, "8afe9fa7ab3e411dab31b91ec8d75934": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query end time (UTC) : ", "layout": "IPY_MODEL_21b08274c80c4b2fb0938d772f581073", "style": "IPY_MODEL_866de96e9adf462399404d48540ba8a0", "value": "2020-10-02 00:00:00" } }, "8e6910adf37f425496f17afbdc8be8f0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Time (24hr)", "layout": "IPY_MODEL_528c3cff29ea4b3f89be5624d3802078", "style": "IPY_MODEL_53bac414032846588fe2cd53c96fbd9c", "value": "18:01:26.726226" } }, "8ed7de7792c94b2bb5a1dd02c1cc13a5": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_21397bf979b4416c98f6e99091978634", "IPY_MODEL_43ae3c8c925c4c5a962f62959045cbb4", "IPY_MODEL_cefc2e988feb4331b46c347487ab3463" ], "layout": "IPY_MODEL_1c13751ac3df46b380cff6a7478ae7fd" } }, "8ff6ccf603dd4837ac953965c0059b74": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DatePickerModel", "state": { "description": "Origin Date", "disabled": false, "layout": "IPY_MODEL_458ecdb873e44fc98ddbf0f5b7ba7597", "style": "IPY_MODEL_f4560bcb769340be918752b7e7931bb1", "value": { "date": 3, "month": 11, "year": 2020 } } }, "91ac641343a544749f9681374e01dcc6": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "9b34eb853e364a28a2f6feebac6e9604": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "9f8ce116e98c4350bde6ffb13c8a8671": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "a4fba06a69cc4ac08646ee8d82af2055": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "80%" } }, "a9af168004bb449c91396cfb8b544e39": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "ad1fbba004364d5a93b3fef2a2e4f228": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "b1a8f10add46434884cddc2b4f4c287f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "b445588f3a2847199263a89299e51073": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "b722bbf9598f4a19a2bd5c232f7fb087": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "bcb4d3ca36424c32b2fb717d6caa3a2f": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query end time (UTC) : ", "layout": "IPY_MODEL_103045fdb6fa401284794e05a8e30c39", "style": "IPY_MODEL_bd98d31feb8845eeb66ade6e59653f58", "value": "2020-12-03 18:01:26.726226" } }, "bd98d31feb8845eeb66ade6e59653f58": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "be1842c22e6443978c7ca2e74795ac86": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query start time (UTC):", "layout": "IPY_MODEL_14e2297c26e94e81aa3c756ad7225e5b", "style": "IPY_MODEL_355a872f37e84f8694203d0289527173", "value": "2020-10-01 00:00:00" } }, "c0e214f35451463a8a10f016ee5c2a3f": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Time (24hr)", "layout": "IPY_MODEL_33e39e2bdb674c009a20ca2715dca504", "style": "IPY_MODEL_b722bbf9598f4a19a2bd5c232f7fb087", "value": "00:00:00" } }, "cefc2e988feb4331b46c347487ab3463": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_861f59f0453a4c818a9b10a04c631679", "IPY_MODEL_836ff4af177546dfad48b958b7028585", "IPY_MODEL_1f6acf50e7f643c394028dc573df87a3" ], "layout": "IPY_MODEL_3e72f51be72e47d5b3a80e7cae444c98" } }, "d18e9480e5334ef7bc37b425b1b41eb4": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "d3ea736ab63e46fcb855cb15f36c33ae": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "d4f71307437b4eacba37822da11173c9": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "95%" } }, "d7df3167b4094f418b86c9aec984efca": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "initial" } }, "d8231c08bf204f62a9fea1008abce911": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntRangeSliderModel", "state": { "_model_name": "IntRangeSliderModel", "_view_name": "IntRangeSliderView", "description": "Time Range (hour):", "layout": "IPY_MODEL_f24094790f964de29f65e41de3056953", "max": 4, "min": -96, "style": "IPY_MODEL_7ea03c4da997489f891d5adb77703aef", "value": [ -24, 0 ] } }, "da7a5ba1509a4f2796cde97bf0f75beb": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "e33baf0bb59749ff856bca0b611ce374": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "e6b95b26dad0430cb7310db1f8bdca93": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "layout": "IPY_MODEL_91ac641343a544749f9681374e01dcc6", "style": "IPY_MODEL_6e0b2e6f9db74b8ca3640fd5deef48ef", "value": "

Set time range for pivot functions.

" } }, "f24094790f964de29f65e41de3056953": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "80%" } }, "f4560bcb769340be918752b7e7931bb1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }