Details
| ID | MaxMind GeoIP2 |
|---|---|
| Provider | MaxMind Inc |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
This integration was integrated and tested with MaxMind GeoIP2 v2.1.
Configure MaxMind GeoIP2 on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for MaxMind GeoIP2.
- 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, andInsights. Note that each version has a different cost per API call. - Base URL: The API endpoint.
- 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
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
Configuration parameters
url— Base URL (required)apikey— API Keycredentials— Account IDaccount— Account IDproxy— Use system proxy settingsinsecure— Trust any certificate (not secure)mode— Service Version (required)integrationReliability— Source ReliabilityfeedExpirationPolicy—feedExpirationInterval—
Commands (1)
-
ipCheck 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))
