Skip to content

Commit fcc0d3c

Browse files
pranjalg1331mlodic
authored andcommitted
GreedyBear Ingestor (Closes #2355) (#2709)
* Intelowl wroking Signed-off-by: pranjalg1331 <pranjaloff13@gmail.com> * parameters for url request Signed-off-by: pranjalg1331 <pranjaloff13@gmail.com> * sample corrected Signed-off-by: pranjalg1331 <pranjaloff13@gmail.com> * updated url+ flake updated Signed-off-by: pranjalg1331 <pranjaloff13@gmail.com> * protocol included in url Signed-off-by: pranjalg1331 <pranjaloff13@gmail.com> --------- Signed-off-by: pranjalg1331 <pranjaloff13@gmail.com>
1 parent 19ece05 commit fcc0d3c

File tree

3 files changed

+434
-1
lines changed

3 files changed

+434
-1
lines changed

.flake8

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ exclude =
1212
migrations,
1313
virtualenv,
1414
ldap_config.py
15-
api_app/analyzers_manager/migrations/*
15+
api_app/analyzers_manager/migrations/*
16+
api_app/ingestors_manager/migrations/*
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import ipaddress
2+
import logging
3+
from typing import Any, Iterable
4+
from unittest.mock import patch
5+
6+
import requests
7+
8+
from api_app.ingestors_manager.classes import Ingestor
9+
from api_app.ingestors_manager.exceptions import (
10+
IngestorConfigurationException,
11+
IngestorRunException,
12+
)
13+
from tests.mock_utils import MockUpResponse, if_mock_connections
14+
15+
logger = logging.getLogger(__name__)
16+
17+
18+
class GreedyBear(Ingestor):
19+
20+
url: str
21+
feed_type: str
22+
attack_type: str
23+
age: str
24+
25+
VALID_FEED_TYPES = {"log4j", "cowrie", "all"}
26+
VALID_ATTACK_TYPES = {"scanner", "payload_request", "all"}
27+
VALID_AGE = {"recent", "persistent"}
28+
29+
@classmethod
30+
def update(cls) -> bool:
31+
pass
32+
33+
def run(self) -> Iterable[Any]:
34+
if self.feed_type not in self.VALID_FEED_TYPES:
35+
raise IngestorConfigurationException(
36+
f"Invalid feed_type: {self.feed_type}. Must be one of {self.VALID_FEED_TYPES}"
37+
)
38+
if self.attack_type not in self.VALID_ATTACK_TYPES:
39+
raise IngestorConfigurationException(
40+
f"Invalid attack_type: {self.attack_type}. Must be one of {self.VALID_ATTACK_TYPES}"
41+
)
42+
if self.age not in self.VALID_AGE:
43+
raise IngestorConfigurationException(
44+
f"Invalid age: {self.age}. Must be one of {self.VALID_AGE}"
45+
)
46+
47+
req_url = (
48+
f"{self.url}/api/feeds/{self.feed_type}/{self.attack_type}/{self.age}.json"
49+
)
50+
result = requests.get(req_url)
51+
result.raise_for_status()
52+
content = result.json()
53+
if not isinstance(content.get("iocs"), list):
54+
raise IngestorRunException(f"Content {content} not expected")
55+
56+
limit = min(len(content["iocs"]), self.limit)
57+
for elem in content["iocs"][:limit]:
58+
value = elem.get("value")
59+
try:
60+
ipaddress.ip_address(value)
61+
yield value
62+
except ValueError:
63+
pass
64+
65+
@classmethod
66+
def _monkeypatch(cls):
67+
patches = [
68+
if_mock_connections(
69+
patch(
70+
"requests.get",
71+
return_value=MockUpResponse(
72+
{
73+
"license": "https://github.com/honeynet/GreedyBear/blob/main/FEEDS_LICENSE.md",
74+
"iocs": [
75+
{
76+
"feed_type": "suricata",
77+
"value": "91.205.219.185",
78+
"scanner": True,
79+
"payload_request": False,
80+
"first_seen": "2024-05-29",
81+
"last_seen": "2025-02-01",
82+
"times_seen": 6437,
83+
},
84+
{
85+
"feed_type": "suricata",
86+
"value": "88.210.32.15",
87+
"scanner": True,
88+
"payload_request": False,
89+
"first_seen": "2024-07-30",
90+
"last_seen": "2025-02-01",
91+
"times_seen": 61,
92+
},
93+
],
94+
},
95+
200,
96+
),
97+
),
98+
)
99+
]
100+
return super()._monkeypatch(patches=patches)

0 commit comments

Comments
 (0)