SOCRadarIoCEnrichment

Enrich indicators with deep threat intelligence using SOCRadar IoC Enrichment API. Get categorization, signal strength, confidence levels, and historical data.

Data Enrichment & Threat Intelligence · SOCRadar

Details

IDSOCRadarIoCEnrichment
ProviderSOCRadar
CategoryData Enrichment & Threat Intelligence
From Version6.10.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

SOCRadar IoC Enrichment Integration

Overview

The SOCRadar IoC Enrichment integration provides deep threat intelligence enrichment for indicators of compromise (IoCs). Get comprehensive data including categorization, signal strength, confidence levels, historical events, threat actor attribution, and campaign associations.

Key Features

  • Rich Threat Context: Detailed categorization (CDN, Cloud, Malware, ThreatActor, Tor, VPN, etc.)
  • Signal Strength: IoC reliability assessment (Very Strong to Noisy)
  • Confidence Levels: Cross-source validation (Very High, High, Medium, Low)
  • Historical Data: Timeline of indicator activity across threat feeds
  • Threat Attribution: Associated campaigns, threat actors, malware families
  • Target Intelligence: Industries and countries targeted
  • Performance Optimized: AI insights excluded for fast responses

Configuration

Prerequisites

  • SOCRadar API Key with IoC Enrichment access
  • Network access to platform.socradar.com

Setup

  1. Navigate to SettingsIntegrationsServers & Services
  2. Search for “SOCRadar IoC Enrichment”
  3. Click Add Instance
  4. Configure:
    • Name: Instance name
    • API Key: Your SOCRadar API key
    • Source Reliability: B - Usually reliable (recommended)
  5. Click Test to validate
  6. Click Save & Exit

Commands

ip

Enriches IP addresses with threat intelligence data.

Input

Argument Description Required
ip IP addresses to enrich (IPv4 or IPv6). Supports multiple IPs (comma-separated). Required

Context Output

Path Type Description
SOCRadarIoCEnrichment.IP.Indicator String The IP address
SOCRadarIoCEnrichment.IP.Score Number Threat score (0-100)
SOCRadarIoCEnrichment.IP.SignalStrength String IoC reliability (Very Strong, Strong, Moderate, Slightly Noisy, Noisy)
SOCRadarIoCEnrichment.IP.Confidence String Cross-source confidence (Very High, High, Medium, Low)
SOCRadarIoCEnrichment.IP.Country String Country of origin
SOCRadarIoCEnrichment.IP.ASN String Autonomous System Name
SOCRadarIoCEnrichment.IP.FirstSeen Date First observed date
SOCRadarIoCEnrichment.IP.LastSeen Date Last observed date
SOCRadarIoCEnrichment.IP.Categorization Object Service categorization flags
SOCRadarIoCEnrichment.IP.Categorization.Malware Boolean Associated with malware
SOCRadarIoCEnrichment.IP.Categorization.ThreatActor Boolean Associated with threat actors
SOCRadarIoCEnrichment.IP.Categorization.Tor Boolean Tor exit node
SOCRadarIoCEnrichment.IP.Categorization.VPN Boolean VPN service
SOCRadarIoCEnrichment.IP.Categorization.CDN Boolean Content delivery network
SOCRadarIoCEnrichment.IP.Categorization.Cloud Boolean Cloud hosting
SOCRadarIoCEnrichment.IP.Classifications Object Threat classifications
SOCRadarIoCEnrichment.IP.Classifications.Campaign String Associated campaign name
SOCRadarIoCEnrichment.IP.Classifications.Malwares Array Associated malware families
SOCRadarIoCEnrichment.IP.Classifications.ThreatActors Array Associated threat actors
SOCRadarIoCEnrichment.IP.Classifications.Industries Array Targeted industries
SOCRadarIoCEnrichment.IP.Classifications.TargetCountries Array Targeted countries
SOCRadarIoCEnrichment.IP.History Array Historical events (last 10)
DBotScore.Score Number DBot score (0=Unknown, 1=Good, 2=Suspicious, 3=Malicious)

Command Example

!ip ip="104.251.122.20"
!ip ip="1.1.1.1,8.8.8.8"

domain

Enriches domains with threat intelligence data.

Input

Argument Description Required
domain Domain names to enrich. Supports multiple domains (comma-separated). Required

Context Output

Similar to IP command, with SOCRadarIoCEnrichment.Domain.* prefix.

Command Example

!domain domain="malicious-site.com"
!domain domain="example.com,test.net"

url

Enriches URLs with threat intelligence data.

Input

Argument Description Required
url URLs to enrich. Supports multiple URLs (comma-separated). Required

Context Output

Similar to IP command, with SOCRadarIoCEnrichment.URL.* prefix.

Command Example

!url url="https://malicious-site.com/payload.exe"
!url url="http://phishing.example.com,https://c2.attacker.net"

file

Enriches file hashes with threat intelligence data.

Input

Argument Description Required
file File hashes to enrich (MD5, SHA1, SHA256). Supports multiple hashes. Required

Context Output

Similar to IP command, with SOCRadarIoCEnrichment.File.* prefix.

Command Example

!file file="44d88612fea8a8f36de82e1278abb02f"
!file file="3b7b359ea17ac76341957573e332a2d6bcac363401ac71c8df94dac93df6d792"

DBot Score Interpretation

DBot Score Meaning Criteria
3 Malicious Score > 80 OR Signal Strength = Very Strong/Strong
2 Suspicious Score 40-80 OR Signal Strength = Moderate
1 Good Score 1-40
0 Unknown Score = 0 or NULL

Use Cases

1. Incident Investigation

# Enrich suspicious IP from logs
!ip ip="192.168.1.100"

# Check associated domain
!domain domain="suspicious-domain.com"

# Investigate related hash
!file file="abc123def456..."

Output: Get complete threat context including campaigns, threat actors, target industries, and historical activity.

2. Threat Hunting

# Enrich multiple indicators
!ip ip="1.1.1.1,2.2.2.2,3.3.3.3"

Output: Batch enrichment with categorization flags to identify Tor nodes, VPNs, malware C2s, etc.

3. Playbook Enrichment

- id: "1"
  task: Enrich Incident IOCs
  command: ip
  args:
    ip: ${incident.sourceip}

- id: "2"
  task: Check Signal Strength
  condition: ${SOCRadarIoCEnrichment.IP.SignalStrength} == "Very Strong"
  nexttasks:
    "true":
      - Block IP

4. Threat Intelligence Analysis

# Get detailed classification
!ip ip="203.0.113.45"

Output:

  • Signal Strength: Very Strong
  • Confidence: Very High
  • Campaign: APT28 Infrastructure
  • Threat Actors: [“APT28”, “Fancy Bear”]
  • Target Industries: [“Government”, “Defense”]
  • Malwares: [“CHOPSTICK”, “SOURFACE”]

Signal Strength Explained

Level Description Recommended Action
Very Strong High-confidence malicious indicator, low false positive rate Block immediately
Strong Reliable malicious indicator Block with review
Moderate Potentially malicious, moderate confidence Monitor/investigate
Slightly Noisy Some legitimate use cases exist Investigate context
Noisy High false positive rate Review carefully before action

Confidence Levels

Level Description
Very High Validated across multiple high-quality sources
High Confirmed by multiple sources
Medium Moderate source validation
Low Limited source validation

Categorization Flags

Flag Meaning
Malware Associated with malware distribution/C2
ThreatActor Attributed to known threat actor
Tor Tor network node
VPN VPN service endpoint
Proxy Proxy service
CDN Content delivery network
Cloud Cloud hosting (AWS, Azure, GCP, etc.)
Hosting Web hosting service
Honeypot Honeypot/research environment
Cryptocurrency Crypto mining/wallet
Scanner Port/vulnerability scanner

Performance Notes

  • AI Insights Excluded: For optimal performance, AI-generated insights are not requested
  • Fields Requested: indicator_details, indicator_history, indicator_relations
  • Response Time: Typically < 2 seconds per indicator
  • Rate Limits: Check your API key’s rate limit with SOCRadar

Troubleshooting

Test Module Fails

Error: “Authorization Error”

  • Solution: Verify API key is correct and has IoC Enrichment access

Error: “Connection failed”

  • Solution: Check network connectivity to platform.socradar.com

No Data Returned

Issue: Empty response for valid indicator

  • Cause: Indicator not in SOCRadar database
  • Note: No data doesn’t mean indicator is safe, just unknown to SOCRadar

Rate Limit Exceeded

Error: “Rate limit has been exceeded”

  • Solution: Contact SOCRadar to increase rate limit or wait for reset

Best Practices

  1. Enrich All IOCs: Run enrichment on all indicators during investigation
  2. Trust Signal Strength: Use signal strength for automated blocking decisions
  3. Check Categorization: Validate if indicator is CDN/Cloud before blocking
  4. Review History: Examine historical events for pattern analysis
  5. Combine with Other Sources: Use alongside other TI feeds for validation
  6. Playbook Integration: Automate enrichment in incident response playbooks

Additional Resources


Version History

  • 1.0.0: Initial release with IP, Domain, URL, and File enrichment

Integration Type: Data Enrichment & Threat Intelligence
Vendor: SOCRadar
Support: Community
Categories: Threat Intelligence, IoC Enrichment, Reputation

Configuration parameters

  • apikey — (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • integrationReliability — Source Reliability
  • include_ai_insights — Include AI Insights (slower response time)

Commands (5)

  • domain

    Enriches domains with SOCRadar IoC threat intelligence data.

  • file

    Enriches file hashes with SOCRadar IoC threat intelligence data.

  • ip

    Enriches IP addresses with SOCRadar IoC threat intelligence data.

  • socradar-ioc-enrichment

    Generic enrichment command with automatic indicator type detection. Enriches any indicator type (IP, domain, URL, hash) without specifying the type.

  • url

    Enriches URLs with SOCRadar IoC threat intelligence data.

import json

import pytest
from CommonServerPython import CommandResults, DemistoException

SOCRADAR_API_ENDPOINT = "https://platform.socradar.com/api"
ENRICHMENT_SUFFIX = f"{SOCRADAR_API_ENDPOINT}/ioc_enrichment/get/indicator_details"


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


def make_client(api_key="TestAPIKey", include_ai_insights=False):
    from SOCRadarIoCEnrichment import Client

    return Client(
        base_url=SOCRADAR_API_ENDPOINT,
        api_key=api_key,
        verify=False,
        proxy=False,
        include_ai_insights=include_ai_insights,
    )


# ---------- calculate_dbot_score ----------


def test_calculate_dbot_score_unknown():
    from SOCRadarIoCEnrichment import calculate_dbot_score

    assert calculate_dbot_score(0) == 0
    assert calculate_dbot_score(None) == 0


def test_calculate_dbot_score_suspicious():
    from SOCRadarIoCEnrichment import calculate_dbot_score

    assert calculate_dbot_score(1) == 2
    assert calculate_dbot_score(50) == 2


def test_calculate_dbot_score_malicious():
    from SOCRadarIoCEnrichment import calculate_dbot_score

    assert calculate_dbot_score(51) == 3
    assert calculate_dbot_score(100) == 3


def test_calculate_dbot_score_list_input():
    from SOCRadarIoCEnrichment import calculate_dbot_score

    assert calculate_dbot_score([85.0]) == 3
    assert calculate_dbot_score([0]) == 0
    assert calculate_dbot_score([]) == 0


# ---------- build_entry_context ----------


def test_build_entry_context():
    from SOCRadarIoCEnrichment import build_entry_context

    raw = util_load_json("test_data/ip_enrichment_response.json")
    result = build_entry_context(raw, "1.2.3.4")

    assert result["Indicator"] == "1.2.3.4"
    assert result["Score"] == 85.0
    assert result["Country"] == "United States"
    assert result["ASN"] == "TestASN Inc"
    assert result["IsWhitelisted"] is False
    assert result["Categorization"]["Malware"] is True
    assert result["Classifications"]["Malwares"] == ["TestMalware"]
    assert len(result["History"]) == 1
    assert result["History"][0]["Event"] == "first_seen"


def test_build_entry_context_ai_insight():
    from SOCRadarIoCEnrichment import build_entry_context

    raw = util_load_json("test_data/ip_enrichment_response.json")
    raw["socradar_copilot:ioc_agent"] = "This IP is associated with botnet activity."
    result = build_entry_context(raw, "1.2.3.4")

    assert result["AIInsight"] == "This IP is associated with botnet activity."


# ---------- detect_indicator_type ----------


def test_detect_indicator_type_ip():
    from SOCRadarIoCEnrichment import detect_indicator_type

    assert detect_indicator_type("1.2.3.4") == "ip"
    assert detect_indicator_type("2001:db8::1") == "ip"


def test_detect_indicator_type_url():
    from SOCRadarIoCEnrichment import detect_indicator_type

    assert detect_indicator_type("https://example.com") == "url"


def test_detect_indicator_type_hash():
    from SOCRadarIoCEnrichment import detect_indicator_type

    assert detect_indicator_type("d41d8cd98f00b204e9800998ecf8427e") == "file"


def test_detect_indicator_type_domain():
    from SOCRadarIoCEnrichment import detect_indicator_type

    assert detect_indicator_type("example.com") == "domain"


def test_detect_indicator_type_unknown():
    from SOCRadarIoCEnrichment import detect_indicator_type

    with pytest.raises(ValueError, match="Unable to determine indicator type"):
        detect_indicator_type("???not-valid???")


# ---------- ip_command ----------


def test_ip_command(requests_mock):
    from SOCRadarIoCEnrichment import ip_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))

    results = ip_command(make_client(), {"ip": "1.2.3.4"}, reliability="B - Usually reliable")

    assert len(results) == 1
    assert isinstance(results[0], CommandResults)
    assert results[0].outputs["Indicator"] == "1.2.3.4"
    assert results[0].outputs["Score"] == 85.0
    assert "1.2.3.4" in results[0].readable_output


def test_ip_command_invalid_ip():
    from SOCRadarIoCEnrichment import ip_command

    results = ip_command(make_client(), {"ip": "not-an-ip"}, reliability=None)

    assert len(results) == 1
    assert "not a valid IPv4 or IPv6" in results[0].readable_output


# ---------- domain_command ----------


def test_domain_command(requests_mock):
    from SOCRadarIoCEnrichment import domain_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))

    results = domain_command(make_client(), {"domain": "example.com"}, reliability=None)

    assert len(results) == 1
    assert results[0].outputs["Indicator"] == "example.com"


def test_domain_command_invalid_domain():
    from SOCRadarIoCEnrichment import domain_command

    results = domain_command(make_client(), {"domain": "not a domain!!"}, reliability=None)

    assert len(results) == 1
    assert "not a valid domain" in results[0].readable_output


# ---------- url_command ----------


def test_url_command(requests_mock):
    from SOCRadarIoCEnrichment import url_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))

    results = url_command(make_client(), {"url": "https://example.com/path"}, reliability=None)

    assert len(results) == 1
    assert results[0].outputs["Indicator"] == "https://example.com/path"


def test_url_command_invalid_url():
    from SOCRadarIoCEnrichment import url_command

    results = url_command(make_client(), {"url": "not-a-url"}, reliability=None)

    assert len(results) == 1
    assert "not a valid URL" in results[0].readable_output


# ---------- file_command ----------


def test_file_command_sha256(requests_mock):
    from SOCRadarIoCEnrichment import file_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))

    sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    results = file_command(make_client(), {"file": sha256}, reliability=None)

    assert len(results) == 1
    assert results[0].outputs["Indicator"] == sha256


def test_file_command_invalid_hash():
    from SOCRadarIoCEnrichment import file_command

    results = file_command(make_client(), {"file": "notahash"}, reliability=None)

    assert len(results) == 1
    assert "not a valid hash" in results[0].readable_output


# ---------- handle_error_response ----------


def test_handle_error_response_401(requests_mock):
    from SOCRadarIoCEnrichment import MESSAGES

    requests_mock.post(
        ENRICHMENT_SUFFIX,
        json=util_load_json("test_data/auth_error_response.json"),
        status_code=401,
    )

    with pytest.raises(DemistoException, match=MESSAGES["AUTHORIZATION_ERROR"]):
        make_client(api_key="WrongKey").get_indicator_enrichment("1.2.3.4")


def test_handle_error_response_429(requests_mock):
    from SOCRadarIoCEnrichment import MESSAGES

    requests_mock.post(ENRICHMENT_SUFFIX, json={}, status_code=429)

    with pytest.raises(DemistoException, match=MESSAGES["RATE_LIMIT_EXCEED_ERROR"]):
        make_client().get_indicator_enrichment("1.2.3.4")


# ---------- test_module ----------


def test_test_module_success(requests_mock):
    from SOCRadarIoCEnrichment import test_module

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))
    result = test_module(make_client())
    assert result == "ok"


def test_test_module_no_response(requests_mock, mocker):
    from SOCRadarIoCEnrichment import test_module

    mocker.patch("demistomock.error")
    requests_mock.post(ENRICHMENT_SUFFIX, json={})
    with pytest.raises(DemistoException, match="API test failed"):
        test_module(make_client())


def test_test_module_connection_error(requests_mock, mocker):
    import requests as req
    from SOCRadarIoCEnrichment import test_module

    mocker.patch("demistomock.error")
    requests_mock.post(ENRICHMENT_SUFFIX, exc=req.exceptions.ConnectionError("Connection refused"))
    with pytest.raises(DemistoException, match="Authentication failed"):
        test_module(make_client())


# ---------- socradar_ioc_enrichment_command ----------


def test_socradar_ioc_enrichment_command_ip(requests_mock):
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))
    results = socradar_ioc_enrichment_command(make_client(), {"indicator": "1.2.3.4"})

    assert len(results) == 1
    assert results[0].outputs["Indicator"] == "1.2.3.4"


def test_socradar_ioc_enrichment_command_domain(requests_mock):
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))
    results = socradar_ioc_enrichment_command(make_client(), {"indicator": "example.com"})

    assert len(results) == 1
    assert results[0].outputs["Indicator"] == "example.com"


def test_socradar_ioc_enrichment_command_url(requests_mock):
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))
    results = socradar_ioc_enrichment_command(make_client(), {"indicator": "https://example.com/path"})

    assert len(results) == 1
    assert results[0].outputs["Indicator"] == "https://example.com/path"


def test_socradar_ioc_enrichment_command_hash_sha256(requests_mock):
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))
    sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    results = socradar_ioc_enrichment_command(make_client(), {"indicator": sha256})

    assert len(results) == 1
    assert results[0].outputs["Indicator"] == sha256


def test_socradar_ioc_enrichment_command_hash_md5(requests_mock):
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))
    md5 = "d41d8cd98f00b204e9800998ecf8427e"
    results = socradar_ioc_enrichment_command(make_client(), {"indicator": md5})

    assert len(results) == 1


def test_socradar_ioc_enrichment_command_hash_sha1(requests_mock):
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    requests_mock.post(ENRICHMENT_SUFFIX, json=util_load_json("test_data/ip_enrichment_response.json"))
    sha1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709"
    results = socradar_ioc_enrichment_command(make_client(), {"indicator": sha1})

    assert len(results) == 1


def test_socradar_ioc_enrichment_command_no_indicator():
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    results = socradar_ioc_enrichment_command(make_client(), {"indicator": ""})

    assert len(results) == 1
    assert "required" in results[0].readable_output


def test_socradar_ioc_enrichment_command_no_response(requests_mock):
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    requests_mock.post(ENRICHMENT_SUFFIX, json={})
    results = socradar_ioc_enrichment_command(make_client(), {"indicator": "1.2.3.4"})

    assert len(results) == 1
    assert "No enrichment data" in results[0].readable_output


def test_socradar_ioc_enrichment_command_unknown_indicator():
    from SOCRadarIoCEnrichment import socradar_ioc_enrichment_command

    results = socradar_ioc_enrichment_command(make_client(), {"indicator": "???not-valid???"})

    assert len(results) == 1
    assert "Error" in results[0].readable_output


# ---------- API failure / no-data paths ----------


def test_ip_command_no_data(requests_mock):
    from SOCRadarIoCEnrichment import ip_command

    requests_mock.post(ENRICHMENT_SUFFIX, json={})
    results = ip_command(make_client(), {"ip": "1.2.3.4"}, reliability=None)

    assert len(results) == 1
    assert "No enrichment data" in results[0].readable_output


def test_domain_command_no_data(requests_mock):
    from SOCRadarIoCEnrichment import domain_command

    requests_mock.post(ENRICHMENT_SUFFIX, json={})
    results = domain_command(make_client(), {"domain": "example.com"}, reliability=None)

    assert len(results) == 1
    assert "No enrichment data" in results[0].readable_output


def test_url_command_no_data(requests_mock):
    from SOCRadarIoCEnrichment import url_command

    requests_mock.post(ENRICHMENT_SUFFIX, json={})
    results = url_command(make_client(), {"url": "https://example.com"}, reliability=None)

    assert len(results) == 1
    assert "No enrichment data" in results[0].readable_output


def test_file_command_no_data(requests_mock):
    from SOCRadarIoCEnrichment import file_command

    requests_mock.post(ENRICHMENT_SUFFIX, json={})
    sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    results = file_command(make_client(), {"file": sha256}, reliability=None)

    assert len(results) == 1
    assert "No enrichment data" in results[0].readable_output