Files
calvana/ayn-antivirus/ayn_antivirus/signatures/feeds/feodotracker.py

74 lines
2.2 KiB
Python

"""Feodo Tracker feed for AYN Antivirus.
Downloads the recommended IP blocklist from the abuse.ch Feodo Tracker
project. The list contains IP addresses of verified botnet C2 servers
(Dridex, Emotet, TrickBot, QakBot, etc.).
Source: https://feodotracker.abuse.ch/blocklist/
"""
from __future__ import annotations
import logging
from typing import Any, Dict, List
import requests
from ayn_antivirus.signatures.feeds.base_feed import BaseFeed
logger = logging.getLogger(__name__)
_BLOCKLIST_URL = "https://feodotracker.abuse.ch/downloads/ipblocklist_aggressive.txt"
_TIMEOUT = 30
class FeodoTrackerFeed(BaseFeed):
"""Fetch C2 server IPs from the Feodo Tracker blocklist."""
def get_name(self) -> str:
return "feodotracker"
def fetch(self) -> List[Dict[str, Any]]:
"""Download the recommended IP blocklist.
Returns a list of dicts, each with:
``ioc_type="ip"``, ``value``, ``threat_name``, ``type``, ``source``.
"""
self._rate_limit_wait()
self._log("Downloading Feodo Tracker IP blocklist")
try:
resp = requests.get(_BLOCKLIST_URL, timeout=_TIMEOUT)
resp.raise_for_status()
except requests.RequestException as exc:
self._error("Download failed: %s", exc)
return []
results: List[Dict[str, Any]] = []
for line in resp.text.splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
# Basic IPv4 validation.
parts = line.split(".")
if len(parts) != 4:
continue
try:
if not all(0 <= int(p) <= 255 for p in parts):
continue
except ValueError:
continue
results.append({
"ioc_type": "ip",
"value": line,
"threat_name": "Botnet.C2.Feodo",
"type": "C2",
"source": "feodotracker",
"details": "Verified botnet C2 IP from Feodo Tracker",
})
self._log("Fetched %d C2 IP(s)", len(results))
self._mark_updated()
return results