MaxMind GeoIP2

Enriches IP addresses.

Data Enrichment & Threat Intelligence · MaxMind GeoIP2

Details

IDMaxMind GeoIP2
ProviderMaxMind Inc
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

This integration was integrated and tested with MaxMind GeoIP2 v2.1.

Configure MaxMind GeoIP2 on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for MaxMind GeoIP2.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • API Key: The API key from MaxMind
    • Account ID: Account number used for MaxMind
    • Use system proxy
    • Trust any certificate (not secure)
    • Service Version: Denotes what level of detail for the results. There are three options Country, City, and Insights. Note that each version has a different cost per API call.
    • Base URL: The API endpoint.
  4. Click Test to validate the URLs, token, and connection.

Commands

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

  1. Check the reputation of an IP address: ip

1. Check the reputation of an IP address


Checks the reputation of an IP address (when information is available, returns a JSON with details). Uses all configured Threat Intelligence feeds.

Base Command

ip

Input
Argument Name Description Required
ip IP address to query Required

 

Context Output
Path Type Description
IP.Address string The IP address
MaxMind.Address string The IP address
MaxMind.Geo.City string The IP city
IP.Geo.Country string The IP country
MaxMind.Geo.Country string The IP country
IP.Geo.Location string The IP geographic location in coordinates
MaxMind.Geo.Location string The IP geographic location in coordinates
MaxMind.Geo.TimeZone string The time zone the IP is located
MaxMind.Geo.Accuracy number The accuracy of the location
MaxMind.Geo.Continent string The IP continent
MaxMind.Geo.Subdivision string The IP subdivision
IP.ASN string The IP ASN
MaxMind.ASN string The IP ASN
MaxMind.Organization string The IP organization
MaxMind.Tor boolean Is IP a Tor exit node
MaxMind.Host string The IP host
MaxMind.Anonymous boolean Is the IP anonymous
MaxMind.UserType string The IP user type
MaxMind.ISP string The IP ISP
MaxMind.Domain string The domain associated to the IP
MaxMind.ISO_Code string ISO code for the country the IP is located
MaxMind.RegisteredCountry string Country the IP is registered to

 

Command Example

!ip ip="8.8.8.8"

Context Example
{
    "IP": {
        "Geo": {
            "Country": "United States",
            "Location": "37.751, -97.822"
        },
        "ASN": 15169,
        "Address": "8.8.8.8"
    },
    "MaxMind": {
        "Address": "8.8.8.8",
        "ISP": "Google",
        "Organization": "Google LLC",
        "ISO_Code": "US",
        "Geo": {
            "Location": "37.751, -97.822",
            "Country": "United States",
            "Continent": "North America",
            "Accuracy": 1000
        },
        "ASN": 15169,
        "RegisteredCountry": "United States"
    }
}
Human Readable Output

screen shot 2019-01-16 at 15 22 07

Configuration parameters

  • url — Base URL (required)
  • apikey — API Key
  • credentials — Account ID
  • account — Account ID
  • proxy — Use system proxy settings
  • insecure — Trust any certificate (not secure)
  • mode — Service Version (required)
  • integrationReliability — Source Reliability
  • feedExpirationPolicy
  • feedExpirationInterval

Commands (1)

  • ip

    Check IP reputation (when information is available, returns a JSON with details). Uses all configured Threat Intelligence feeds.

import demistomock as demisto
from CommonServerPython import *
from CommonServerUserPython import *
import requests
from collections import defaultdict
from requests.auth import HTTPBasicAuth
import urllib3

# disable insecure warnings
urllib3.disable_warnings()

"""GLOBAL VARS"""
PARAMS = demisto.params()
BASE_URL = PARAMS.get("url")
APIKEY = PARAMS.get("credentials", {}).get("password") or PARAMS.get("apikey")
ACCOUNT_ID = PARAMS.get("credentials", {}).get("identifier") or PARAMS.get("account")
MODE = PARAMS.get("mode")
USE_SSL = not PARAMS.get("insecure", False)
PROXY = PARAMS.get("proxy")
API_VERSION = "geoip/v2.1"

HR_HEADERS = [
    "IP",
    "Domain",
    "ASN",
    "Organization",
    "ISP",
    "Location",
    "Accuracy Radius",
    "User Type",
    "Continent",
    "ISO Code",
    "Country",
    "Registered Country",
    "TimeZone",
    "City",
    "Subdivision",
    "Is TOR Exit Node",
    "Is Hosting Provider",
    "Is Anonymous",
]

HEADERS = {"Content-Type": "application/json", "Accept": "application/json"}

"""HELPER FUNCTIONS"""


def http_request(query):
    r = requests.request(
        "GET",
        BASE_URL + API_VERSION + "/" + MODE + "/" + query,
        headers=HEADERS,
        verify=USE_SSL,
        auth=HTTPBasicAuth(ACCOUNT_ID, APIKEY),
    )
    if r.status_code != 200:
        return_error(f"Error in API call to MaxMind, got status code - {r.status_code} and a reason: {r.reason}")
    return r


def create_map_entry(lat, lng):
    demisto.results({"Type": entryTypes["map"], "ContentsFormat": formats["json"], "Contents": {"lat": lat, "lng": lng}})


def format_results(res_json):
    hr = defaultdict()  # type: dict
    maxmind_ec = defaultdict(lambda: defaultdict(int))  # type: dict
    ip_ec = defaultdict(lambda: defaultdict(int))  # type: dict
    if "continent" in res_json:
        continent = res_json["continent"]
        hr["Continent"] = continent["names"]["en"]
        maxmind_ec["Geo"]["Continent"] = continent["names"]["en"]
    if "city" in res_json:
        city = res_json["city"]
        hr["City"] = city["names"]["en"]
        maxmind_ec["Geo"]["City"] = city["names"]["en"]
    if "country" in res_json:
        country = res_json["country"]
        hr["Country"] = country["names"]["en"]
        maxmind_ec["Geo"]["Country"] = country["names"]["en"]
        ip_ec["Geo"]["Country"] = country["names"]["en"]
    if "location" in res_json:
        location = res_json["location"]
        ip_ec["Geo"]["Location"] = str(location["latitude"]) + ", " + str(location["longitude"])
        maxmind_ec["Geo"]["Location"] = str(location["latitude"]) + ", " + str(location["longitude"])
        create_map_entry(location["latitude"], location["longitude"])
        if "time_zone" in location:
            hr["TimeZone"] = location["time_zone"]
            maxmind_ec["Geo"]["TimeZone"] = location["time_zone"]
        if "accuracy_radius" in location:
            hr["Accuracy Radius"] = location["accuracy_radius"]
            maxmind_ec["Geo"]["Accuracy"] = location["accuracy_radius"]
    if "registered_country" in res_json:
        hr["ISO Code"] = res_json["registered_country"]["iso_code"]
        maxmind_ec["ISO_Code"] = res_json["registered_country"]["iso_code"]
        registration = res_json["registered_country"]["names"]["en"]
        hr["Registered Country"] = registration
        maxmind_ec["RegisteredCountry"] = registration
    if "subdivisions" in res_json:
        subs = res_json["subdivisions"][0]
        hr["Subdivision"] = subs["names"]["en"]
        maxmind_ec["Geo"]["Subdivision"] = subs["names"]["en"]
    if "traits" in res_json:
        traits = res_json["traits"]
        if "user_type" in traits:
            hr["User Type"] = traits["user_type"]
            maxmind_ec["UserType"] = traits["user_type"]
        if "domain" in traits:
            hr["Domain"] = traits["domain"]
            maxmind_ec["Domain"] = traits["domain"]
        if "is_anonymous" in traits:
            hr["Is Anonymous"] = traits["is_anonymous"]
            maxmind_ec["Anonymous"] = traits["is_anonymous"]
        if "is_hosting_provider" in traits:
            hr["Is Hosting Provider"] = traits["is_hosting_provider"]
            maxmind_ec["Host"] = traits["is_hosting_provider"]
        if "is_tor_exit_node" in traits:
            hr["Is TOR Exit Node"] = traits["is_tor_exit_node"]
            maxmind_ec["Tor"] = traits["is_tor_exit_node"]
        if "autonomous_system_number" in traits:
            hr["ASN"] = traits["autonomous_system_number"]
            ip_ec["ASN"] = traits["autonomous_system_number"]
            maxmind_ec["ASN"] = traits["autonomous_system_number"]
        if "autonomous_system_organization" in traits:
            hr["Organization"] = traits["autonomous_system_organization"]
            maxmind_ec["Organization"] = traits["autonomous_system_organization"]
        hr["IP"] = traits["ip_address"]
        ip_ec["Address"] = traits["ip_address"]
        maxmind_ec["Address"] = traits["ip_address"]
        if "isp" in traits:
            hr["ISP"] = traits["isp"]
            maxmind_ec["ISP"] = traits["isp"]
    dbot_score = {
        "Indicator": ip_ec.get("Address"),
        "Type": "ip",
        "Vendor": "MaxMind_GeoIP2",
        "Score": 0,
        "Reliability": PARAMS.get("integrationReliability"),
    }
    return hr, ip_ec, maxmind_ec, dbot_score


""" FUNCTIONS """


def get_geo_ip(query):
    raw = http_request(query)
    res_json = raw.json()
    return res_json


def geo_ip_command():
    ip_list = argToList(demisto.args().get("ip", ""))
    results = []
    for ip in ip_list:
        res_json = get_geo_ip(ip)
        hr, ip_ec, maxmind_ec, dbot_score = format_results(res_json)
        ec = {
            "IP(val.Address && val.Address == obj.Address)": ip_ec,
            "MaxMind(val.Address && val.Address == obj.Address)": maxmind_ec,
            "DBotScore": dbot_score,
        }
        results.append(
            {
                "Type": entryTypes["note"],
                "ContentsFormat": formats["markdown"],
                "Contents": res_json,
                "HumanReadable": tableToMarkdown(f"{ip} - Scan Results", hr, HR_HEADERS, removeNull=True),
                "EntryContext": ec,
            }
        )
    demisto.results(results)


""" EXECUTION CODE """
LOG(f"command is {demisto.command()}")
try:
    handle_proxy()
    if demisto.command() == "ip":
        geo_ip_command()
    if demisto.command() == "test-module":
        raw = http_request("8.8.8.8")
        demisto.results("ok")
except Exception as e:
    LOG(e)
    LOG.print_log()
    return_error(str(e))