Skip to content

Commit 856208c

Browse files
authored
Merge pull request #508 from intelowlproject/develop
v2.4.2 release
2 parents 7ba0444 + 5b4ec3a commit 856208c

File tree

15 files changed

+199
-54
lines changed

15 files changed

+199
-54
lines changed

.github/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# Changelog
22

33
[**Upgrade Guide**](https://intelowl.readthedocs.io/en/latest/Installation.html#update-to-the-most-recent-version)
4+
5+
## [v2.4.2](https://github.com/intelowlproject/IntelOwl/releases/tag/v2.4.2)
6+
- darksearch.io search API analyzer
7+
- improved abuseipdb analyzer to show matched categories in a human readable form too
8+
- improved HoneyDB analyzer
9+
- as always: fixes, tweaks and dependencies upgrades.
10+
411
## [v2.4.1](https://github.com/intelowlproject/IntelOwl/releases/tag/v2.4.1)
512
A lot of different fixes, tweaks and dependencies upgrades. Also the documentation was updated
613

.github/workflows/pull_request_automation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Build & Tests
22

33
on:
44
pull_request:
5-
branches: [ master, develop ]
5+
branches: [ master, develop, develop-2 ]
66

77
jobs:
88
build:

api_app/script_analyzers/observable_analyzers/abuseipdb.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,45 @@ def run(self):
3232
response = requests.get(self.url, params=params, headers=headers)
3333
response.raise_for_status()
3434

35-
return response.json()
35+
result = response.json()
36+
reports = result.get("data", {}).get("reports", {})
37+
mapping = self._get_mapping()
38+
for report in reports:
39+
report["categories_human_readable"] = []
40+
for category in report.get("categories", []):
41+
if category in mapping:
42+
category_human_readable = mapping[category]
43+
else:
44+
category_human_readable = "unknown category"
45+
report["categories_human_readable"].append(category_human_readable)
46+
47+
return result
48+
49+
@staticmethod
50+
def _get_mapping():
51+
mapping = {
52+
1: "DNS Compromise",
53+
2: "DNS Poisoning",
54+
3: "Fraud Orders",
55+
4: "DDOS Attack",
56+
5: "FTP Brute-Force",
57+
6: "Ping of Death",
58+
7: "Phishing",
59+
8: "Fraud VOIP",
60+
9: "Open Proxy",
61+
10: "Web Spam",
62+
11: "Email Spam",
63+
12: "Blog Spam",
64+
13: "VPN IP",
65+
14: "Port Scan",
66+
15: "Hacking",
67+
16: "SQL Injection",
68+
17: "Spoofing",
69+
18: "Brute Force",
70+
19: "Bad Web Bot",
71+
20: "Exploited Host",
72+
21: "Web App Attack",
73+
22: "SSH",
74+
23: "IoT Targeted",
75+
}
76+
return mapping
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# This file is a part of IntelOwl https://github.com/intelowlproject/IntelOwl
2+
# See the file 'LICENSE' for copying permission.
3+
4+
from api_app.script_analyzers.classes import ObservableAnalyzer
5+
6+
7+
class DarkSearchQuery(ObservableAnalyzer):
8+
name: str = "DarkSearchQuery"
9+
10+
def set_config(self, config_params):
11+
self.num_pages = int(config_params.get("pages", 5))
12+
self.proxies = config_params.get("proxies", None)
13+
14+
def run(self):
15+
from darksearch import Client
16+
17+
c = Client(proxies=self.proxies)
18+
responses = c.search(self.observable_name, pages=self.num_pages)
19+
report = {
20+
"total": responses[0]["total"],
21+
"total_pages": responses[0]["last_page"],
22+
"requested_pages": self.num_pages,
23+
"data": [],
24+
}
25+
for resp in responses:
26+
report["data"].extend(resp["data"])
27+
28+
return report

api_app/script_analyzers/observable_analyzers/honeydb.py

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,73 @@
22
# See the file 'LICENSE' for copying permission.
33

44
import requests
5+
import logging
56

6-
from api_app.exceptions import AnalyzerRunException
7+
from api_app.exceptions import AnalyzerConfigurationException
78
from api_app.script_analyzers import classes
89
from intel_owl import secrets
910

11+
logger = logging.getLogger(__name__)
12+
1013

1114
class HoneyDB(classes.ObservableAnalyzer):
1215
base_url = "https://honeydb.io/api"
1316

1417
def set_config(self, additional_config_params):
1518
api_key_name = additional_config_params.get("api_key_name", "HONEYDB_API_KEY")
1619
api_id_name = additional_config_params.get("api_id_name", "HONEYDB_API_ID")
17-
self.analysis_type = additional_config_params.get(
18-
"honeydb_analysis", "ip_query"
19-
)
20+
self.analysis_type = additional_config_params.get("honeydb_analysis", "all")
21+
self.endpoints = [
22+
"scan_twitter",
23+
"ip_query",
24+
"ip_history",
25+
"internet_scanner",
26+
"ip_info",
27+
]
28+
if self.analysis_type not in self.endpoints and self.analysis_type != "all":
29+
raise AnalyzerConfigurationException(
30+
f"analysis_type is not valid: {self.analysis_type}"
31+
)
2032
self.__api_key = secrets.get_secret(api_key_name)
2133
self.__api_id = secrets.get_secret(api_id_name)
22-
23-
def run(self):
2434
if not self.__api_key:
25-
raise AnalyzerRunException("No HoneyDB API Key retrieved")
35+
raise AnalyzerConfigurationException("No HoneyDB API Key retrieved")
2636
if not self.__api_id:
27-
raise AnalyzerRunException("No HoneyDB API ID retrieved")
28-
headers = {"X-HoneyDb-ApiKey": self.__api_key, "X-HoneyDb-ApiId": self.__api_id}
37+
raise AnalyzerConfigurationException("No HoneyDB API ID retrieved")
38+
self.headers = {
39+
"X-HoneyDb-ApiKey": self.__api_key,
40+
"X-HoneyDb-ApiId": self.__api_id,
41+
}
42+
self.result = {}
2943

30-
if self.analysis_type == "scan_twitter":
31-
url = f"{self.base_url}/twitter-threat-feed/{self.observable_name}"
32-
elif self.analysis_type == "ip_query":
33-
url = f"{self.base_url}/netinfo/lookup/{self.observable_name}"
44+
def run(self):
45+
if self.analysis_type == "all":
46+
for endpoint in self.endpoints:
47+
self._request_analysis(endpoint)
3448
else:
35-
raise AnalyzerRunException(
36-
"""invalid analyzer name specified.
37-
Supported: HONEYDB_Scan_Twitter, HONEYDB_Get"""
38-
)
49+
self._request_analysis(self.analysis_type)
3950

40-
response = requests.get(url, headers=headers)
41-
response.raise_for_status()
51+
return self.result
4252

43-
result = response.json()
44-
return result
53+
def _request_analysis(self, endpoint):
54+
if endpoint == "scan_twitter":
55+
url = f"{self.base_url}/twitter-threat-feed/{self.observable_name}"
56+
elif endpoint == "ip_query":
57+
url = f"{self.base_url}/netinfo/lookup/{self.observable_name}"
58+
elif endpoint == "ip_history":
59+
url = f"{self.base_url}/ip-history/{self.observable_name}"
60+
elif endpoint == "internet_scanner":
61+
url = f"{self.base_url}/internet-scanner/info/{self.observable_name}"
62+
elif endpoint == "ip_info":
63+
url = f"{self.base_url}/ipinfo/{self.observable_name}"
64+
else:
65+
logger.error(f"endpoint {endpoint} not supported")
66+
return
67+
try:
68+
response = requests.get(url, headers=self.headers)
69+
response.raise_for_status()
70+
except Exception as e:
71+
logger.exception(e)
72+
self.result[endpoint] = {"error": e}
73+
else:
74+
self.result[endpoint] = response.json()

configuration/analyzer_config.json

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,19 @@
158158
"python_module": "cymru.Cymru",
159159
"soft_time_limit": 50
160160
},
161+
"Darksearch_Query": {
162+
"type": "observable",
163+
"observable_supported": ["ip", "url", "domain", "hash", "generic"],
164+
"external_service": true,
165+
"description": "Query against https://darksearch.io/api/search API",
166+
"python_module": "darksearch.DarkSearchQuery",
167+
"soft_time_limit": 50,
168+
"queue": "long",
169+
"additional_config_params": {
170+
"pages": 10,
171+
"proxies": {}
172+
}
173+
},
161174
"DNSDB": {
162175
"type": "observable",
163176
"observable_supported": [
@@ -365,7 +378,7 @@
365378
},
366379
"soft_time_limit": 30
367380
},
368-
"HoneyDB_Get": {
381+
"HoneyDB": {
369382
"type": "observable",
370383
"observable_supported": [
371384
"ip"
@@ -377,23 +390,7 @@
377390
"additional_config_params": {
378391
"api_key_name": "HONEYDB_API_KEY",
379392
"api_id_name": "HONEYDB_API_ID",
380-
"honeydb_analysis": "ip_query"
381-
},
382-
"soft_time_limit": 200
383-
},
384-
"HoneyDB_Scan_Twitter": {
385-
"type": "observable",
386-
"observable_supported": [
387-
"ip"
388-
],
389-
"external_service": true,
390-
"description": "scan an IP against HoneyDB.io’s Twitter Threat Feed",
391-
"requires_configuration": true,
392-
"python_module": "honeydb.HoneyDB",
393-
"additional_config_params": {
394-
"api_key_name": "HONEYDB_API_KEY",
395-
"api_id_name": "HONEYDB_API_ID",
396-
"honeydb_analysis": "scan_twitter"
393+
"honeydb_analysis": "all"
397394
},
398395
"soft_time_limit": 200
399396
},

docker/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
### DO NOT CHANGE THIS VALUE !!
22
### It should be updated only when you pull latest changes off from the 'master' branch of IntelOwl.
3-
INTELOWL_TAG_VERSION=v2.4.1
3+
INTELOWL_TAG_VERSION=v2.4.2

docker/Dockerfile_nginx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Stage 1: Get build artifacts from intelowl-ng
2-
FROM intelowlproject/intelowl_ng:v2.1.0 AS angular-prod-build
2+
FROM intelowlproject/intelowl_ng:v2.1.1 AS angular-prod-build
33

44
# Stage 2: Inject the build artifacts into nginx container
55
FROM library/nginx:1.19-alpine

docs/source/Advanced-Usage.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ List of some of the analyzers with optional configuration:
149149
* `search_type` (default `WiFi Network`). Supported are: `WiFi Network`, `CDMA Network`, `Bluetooth Network`, `GSM/LTE/WCDMA Network`
150150
* Above mentioned `search_type` is just different routes mentioned in [docs](https://api.wigle.net/swagger#/v3_ALPHA). Also, the string to be passed in input field of generic analyzers have a format. Different variables are separated by semicolons(`;`) and the field-name and value are separated by equals sign(`=`). Example string for search_type `CDMA Network` is `sid=12345;nid=12345;bsid=12345`
151151
* `CRXcavator`:
152-
* Every Chrome-Extension has a unique alpha=numerc identifier. That's the only Input necessary. Eg: `Norton Safe Search Enhanced`'s identifier is `eoigllimhcllmhedfbmahegmoakcdakd`.
152+
* Every Chrome-Extension has a unique alpha=numeric identifier. That's the only Input necessary. Eg: `Norton Safe Search Enhanced`'s identifier is `eoigllimhcllmhedfbmahegmoakcdakd`.
153153
* `SSAPINet`:
154154
* `use_proxy` (default `false`) and `proxy` (default `""`) - use these options to pass your request through a proxy server.
155155
* `output` (default `"image"`) (available options `"image"`, `"json"`) - this specifies whether the result would be a raw image or json (containing link to the image stored on their server).
@@ -162,6 +162,8 @@ List of some of the analyzers with optional configuration:
162162
Refer to the [docs](https://screenshotapi.net/documentation) for a reference to what other parameters are and their default values.
163163
* `FireHol_IPList`:
164164
* `list_names`: Add [FireHol's IPList](https://iplists.firehol.org/) names as comma separated values in `list_names` array.
165+
* `Honey_DB`:
166+
* `honeydb_analysis`(default `all`): choose which endpoint to query from the HoneyDB service (options are `scan_twitter`, `ip_query`, `ip_history`, `internet_scanner`, `ip_info`)
165167

166168
There are two ways to do this:
167169

docs/source/Usage.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,12 @@ The following is the list of the available analyzers you can run out-of-the-box:
152152
* `FireHol_IPList`: check if an IP is in [FireHol's IPList](https://iplists.firehol.org/)
153153
* `ThreatFox`: search for an IOC in [ThreatFox](https://threatfox.abuse.ch/api/)'s database
154154

155-
#### Generic analyzers (email, phone number, ...)
155+
#### Generic analyzers (email, phone number, etc.; anything really)
156156
Some Analyzers require details other than just IP, URL, Domain etc... We classified them as Generic Analyzers. Since the type of field is not known, there is a format for strings to be followed.
157157
* `EmailRep`: search an email address on emailrep.io
158158
* `WiGLE`: Maps and database of 802.11 wireless networks, with statistics, submitted by wardrivers, netstumblers, and net huggers.
159159
* `CRXcavator`: scans a chrome extension against crxcavator.io
160+
* `Darksearch_Query`: Search a keyword against darksearch.io's search API. It's possible to make complex queries using boolean logic. For example, `OSINT AND CTI OR intelowl NOT hack` is a valid observable name.
160161

161162
#### [Additional analyzers](https://intelowl.readthedocs.io/en/develop/Advanced-Usage.html#optional-analyzers) that can be enabled per your wish.
162163

@@ -169,7 +170,7 @@ The following are all the keys that you can change without touching the source c
169170
* `external_service`: if set, in the case you specify via the API to exclude external services, the specific analyzer won't be executed
170171
* `supported_filetypes`: can be populated as a list. If set, if you ask to analyze a file with a different mimetype from the ones you specified, it won't be executed
171172
* `not_supported_filetypes`: can be populated as a list. If set, if you ask to analyze a file with a mimetype from the ones you specified, it won't be executed
172-
* `observable_supported`: can be populated as a list. If set, if you ask to analyze an observable that is not in this list, it won't be executed. Valid values are: `ip`, `domain`, `url`, `hash`
173+
* `observable_supported`: can be populated as a list. If set, if you ask to analyze an observable that is not in this list, it won't be executed. Valid values are: `ip`, `domain`, `url`, `hash`, `generic`.
173174
* `soft_time_limit`: this is the maximum time (in seconds) of execution for an analyzer. Once reached, the task will be killed (or managed in the code by a custom Exception). Default 300s
174175
* `queue`: this takes effects only when [multi-queue](https://intelowl.readthedocs.io/en/develop/Advanced-Usage.html#multi-queue) is enabled. Choose which celery worker would execute the task: `local` (ideal for tasks that leverage local applications like Yara), `long` (ideal for long tasks) or `default` (ideal for simple webAPI-based analyzers).
175176

0 commit comments

Comments
 (0)