Skip to content

Commit ff941c2

Browse files
committed
feat: Add isMalicious threat intelligence app
Add a new Shuffle app for isMalicious.com threat intelligence platform. Features: - Check IPs for malicious activity - Check domains for malicious activity - Get reputation data - Get geolocation data - Get blocklist statistics Website: https://ismalicious.com Documentation: https://docs.ismalicious.com
1 parent e0fb386 commit ff941c2

File tree

3 files changed

+280
-0
lines changed

3 files changed

+280
-0
lines changed

ismalicious/1.0.0/api.yaml

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
walkoff_version: 1.0.0
2+
app_version: 1.0.0
3+
name: ismalicious
4+
description: isMalicious threat intelligence platform - check IPs and domains for malicious activity
5+
tags:
6+
- Threat Intelligence
7+
- Security
8+
- IOC
9+
categories:
10+
- SIEM
11+
- Threat Intelligence
12+
contact_info:
13+
name: "isMalicious"
14+
url: https://ismalicious.com
15+
16+
authentication:
17+
required: true
18+
parameters:
19+
- name: api_key
20+
description: isMalicious API Key
21+
example: "your-api-key"
22+
required: true
23+
schema:
24+
type: string
25+
- name: api_secret
26+
description: isMalicious API Secret
27+
example: "your-api-secret"
28+
required: true
29+
schema:
30+
type: string
31+
- name: api_url
32+
description: API Base URL (default https://ismalicious.com)
33+
example: "https://ismalicious.com"
34+
required: false
35+
schema:
36+
type: string
37+
actions:
38+
- name: check_ip
39+
description: Check if an IP address is malicious
40+
parameters:
41+
- name: ip
42+
description: IP address to check
43+
multiline: false
44+
example: "8.8.8.8"
45+
required: true
46+
schema:
47+
type: string
48+
- name: enrichment
49+
description: Enrichment level (basic, standard, full)
50+
multiline: false
51+
options:
52+
- basic
53+
- standard
54+
- full
55+
required: false
56+
example: "standard"
57+
schema:
58+
type: string
59+
returns:
60+
schema:
61+
type: string
62+
example: |
63+
{
64+
"success": true,
65+
"malicious": false,
66+
"riskScore": 15,
67+
"categories": [],
68+
"sources": []
69+
}
70+
- name: check_domain
71+
description: Check if a domain is malicious
72+
parameters:
73+
- name: domain
74+
description: Domain to check
75+
multiline: false
76+
example: "example.com"
77+
required: true
78+
schema:
79+
type: string
80+
- name: enrichment
81+
description: Enrichment level (basic, standard, full)
82+
multiline: false
83+
options:
84+
- basic
85+
- standard
86+
- full
87+
required: false
88+
example: "standard"
89+
schema:
90+
type: string
91+
returns:
92+
schema:
93+
type: string
94+
example: |
95+
{
96+
"success": true,
97+
"malicious": true,
98+
"riskScore": 85,
99+
"categories": ["phishing"],
100+
"sources": ["VirusTotal", "URLhaus"]
101+
}
102+
- name: get_reputation
103+
description: Get reputation data for an IP or domain
104+
parameters:
105+
- name: query
106+
description: IP address or domain to check
107+
multiline: false
108+
example: "8.8.8.8"
109+
required: true
110+
schema:
111+
type: string
112+
returns:
113+
schema:
114+
type: string
115+
example: |
116+
{
117+
"success": true,
118+
"reputation": {
119+
"score": 85,
120+
"category": "trusted"
121+
}
122+
}
123+
- name: get_location
124+
description: Get geolocation data for an IP address
125+
parameters:
126+
- name: ip
127+
description: IP address to geolocate
128+
multiline: false
129+
example: "8.8.8.8"
130+
required: true
131+
schema:
132+
type: string
133+
returns:
134+
schema:
135+
type: string
136+
example: |
137+
{
138+
"success": true,
139+
"geo": {
140+
"country": "US",
141+
"city": "Mountain View",
142+
"lat": 37.4056,
143+
"lon": -122.0775
144+
}
145+
}
146+
- name: get_blocklist_stats
147+
description: Get statistics about available blocklists
148+
parameters: []
149+
returns:
150+
schema:
151+
type: string
152+
example: |
153+
{
154+
"success": true,
155+
"stats": {
156+
"totalIPs": 150000,
157+
"totalDomains": 200000
158+
}
159+
}
160+
large_image: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TpaIVBzuIOGSoThZERRy1CkWoEGqFVh1MLv2CJg1Jiouj4Fpw8GOx6uDirKuDqyAIfoA4OTopukiJ/0sKLWI8OO7Hu3uPu3eAUC8zzeoYBzTdNtPJhJjNrYrBVwQRQhhDGJmZYc5KJQvf8XWPAF/v4jzL/9yfo1fNWwwIiMSzzDBt4g3i6U3b4LxPHGElWSU+Jx4z6YLEj1xXPH7jXHBZ4JkRM52eJ44Qi4UOVjqYlUyNeIo4qmo65QsZj1XOW5y1cpU178lfGM7rK8tcpzmMJBaxBAkiFNRQRgU2YrTqpFhI037Cwz/s+iVyKeQqgZFjAVVokF0/+B/87tbKT054SeEEEHxx3I8RILgLNOuu+33sOM0TIPgMXOltf6UBzH6SXm9r0SOgbxu4uG5r6h5wuQMMPpmKpXhSkKZQKADvZ/RNOaD/FuhZ8/pWSvwECE9eKn1hH+g5kl/pq5cA92X3l/fuv0bT7E1TwEIEIr0I/E4/+1x/g7x6Ao/5LQAAJREREFT7CQAAACEIAAAAAAAAAAIAAE50ZXN0AAAAAQIAAAAAAAAAAABEZWJ1Z01lc3NhZ2UApJQBIAAiH1Rlc3QgSW1hZ2VAAICAgP///wD//wCAgAAA/wAAAP//AP8AAAD/AAD/AP///wAAAAIAAABVbmtub3duAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

ismalicious/1.0.0/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
requests>=2.25.0

ismalicious/1.0.0/src/app.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import json
2+
import base64
3+
import requests
4+
from walkoff_app_sdk.app_base import AppBase
5+
6+
7+
class isMalicious(AppBase):
8+
__version__ = "1.0.0"
9+
app_name = "ismalicious"
10+
11+
def __init__(self, redis, logger, console_logger=None):
12+
super().__init__(redis, logger, console_logger)
13+
14+
def _get_auth_header(self, api_key, api_secret):
15+
"""Generate authentication header."""
16+
credentials = f"{api_key}:{api_secret}"
17+
encoded = base64.b64encode(credentials.encode()).decode()
18+
return {"X-API-KEY": encoded, "Accept": "application/json"}
19+
20+
def _get_base_url(self, api_url=None):
21+
"""Get base URL with fallback to default."""
22+
if api_url and api_url.strip():
23+
return api_url.rstrip("/")
24+
return "https://ismalicious.com"
25+
26+
def check_ip(self, api_key, api_secret, ip, enrichment="standard", api_url=None):
27+
"""Check if an IP address is malicious."""
28+
base_url = self._get_base_url(api_url)
29+
headers = self._get_auth_header(api_key, api_secret)
30+
31+
try:
32+
response = requests.get(
33+
f"{base_url}/api/check",
34+
params={"query": ip, "enrichment": enrichment or "standard"},
35+
headers=headers,
36+
timeout=30,
37+
)
38+
response.raise_for_status()
39+
result = response.json()
40+
return json.dumps({"success": True, **result})
41+
except requests.exceptions.RequestException as e:
42+
return json.dumps({"success": False, "error": str(e)})
43+
44+
def check_domain(
45+
self, api_key, api_secret, domain, enrichment="standard", api_url=None
46+
):
47+
"""Check if a domain is malicious."""
48+
base_url = self._get_base_url(api_url)
49+
headers = self._get_auth_header(api_key, api_secret)
50+
51+
try:
52+
response = requests.get(
53+
f"{base_url}/api/check",
54+
params={"query": domain, "enrichment": enrichment or "standard"},
55+
headers=headers,
56+
timeout=30,
57+
)
58+
response.raise_for_status()
59+
result = response.json()
60+
return json.dumps({"success": True, **result})
61+
except requests.exceptions.RequestException as e:
62+
return json.dumps({"success": False, "error": str(e)})
63+
64+
def get_reputation(self, api_key, api_secret, query, api_url=None):
65+
"""Get reputation data for an IP or domain."""
66+
base_url = self._get_base_url(api_url)
67+
headers = self._get_auth_header(api_key, api_secret)
68+
69+
try:
70+
response = requests.get(
71+
f"{base_url}/api/check/reputation",
72+
params={"query": query},
73+
headers=headers,
74+
timeout=30,
75+
)
76+
response.raise_for_status()
77+
result = response.json()
78+
return json.dumps({"success": True, **result})
79+
except requests.exceptions.RequestException as e:
80+
return json.dumps({"success": False, "error": str(e)})
81+
82+
def get_location(self, api_key, api_secret, ip, api_url=None):
83+
"""Get geolocation data for an IP address."""
84+
base_url = self._get_base_url(api_url)
85+
headers = self._get_auth_header(api_key, api_secret)
86+
87+
try:
88+
response = requests.get(
89+
f"{base_url}/api/check/location",
90+
params={"query": ip},
91+
headers=headers,
92+
timeout=30,
93+
)
94+
response.raise_for_status()
95+
result = response.json()
96+
return json.dumps({"success": True, **result})
97+
except requests.exceptions.RequestException as e:
98+
return json.dumps({"success": False, "error": str(e)})
99+
100+
def get_blocklist_stats(self, api_key, api_secret, api_url=None):
101+
"""Get statistics about available blocklists."""
102+
base_url = self._get_base_url(api_url)
103+
headers = self._get_auth_header(api_key, api_secret)
104+
105+
try:
106+
response = requests.get(
107+
f"{base_url}/api/blocklist/stats",
108+
headers=headers,
109+
timeout=30,
110+
)
111+
response.raise_for_status()
112+
result = response.json()
113+
return json.dumps({"success": True, **result})
114+
except requests.exceptions.RequestException as e:
115+
return json.dumps({"success": False, "error": str(e)})
116+
117+
118+
if __name__ == "__main__":
119+
isMalicious.run()

0 commit comments

Comments
 (0)