fix drone file

This commit is contained in:
Jérôme Leonard 2021-07-21 17:52:29 +02:00
commit 0c6c85c950
No known key found for this signature in database
GPG Key ID: 355EFA117B915818
68 changed files with 7251 additions and 5 deletions

View File

@ -74,7 +74,6 @@ steps:
- analyzers/analyzers-stable.json
- responders/responders.json
- responders/responders-stable.json
- analyzers/report-templates.zip
strip_components: 1
when:
event: [tag]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,17 @@
{
"dataType":"file",
"file": "Payment Notification 00000307700.eml",
"filename": "filetest",
"config":{
"manalyze_enable": false,
"manalyze_enable_docker": false,
"proxy_http": null,
"proxy_https": null,
"cacerts": null,
"jobTimeout": 10,
"check_tlp": false,
"max_tlp": 2,
"check_pap": false,
"max_pap": 2
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"success": true, "summary": {"taxonomies": [{"level": "info", "namespace": "EmlParser", "predicate": "Attachments", "value": 1}]}, "artifacts": [{"dataType": "ip", "data": "18.23.71.149"}, {"dataType": "ip", "data": "165.199.8.49"}, {"dataType": "ip", "data": "87.227.176.38"}, {"dataType": "mail", "data": "system@sent-via.netsuite.com"}, {"dataType": "mail", "data": "unsuccessfuldr32@nmail002.na3.netsuite.com"}, {"dataType": "hash", "data": "4dd9dfc92887e8c02cbc54a2abf73fb2"}, {"dataType": "hash", "data": "f7586d41577ed314ef5794072ddffef838996088"}, {"dataType": "hash", "data": "bfee589efb80fccdc2c19e16b54fa19d2a9ee7f5c359e0340cd568dce09f8ecb"}, {"dataType": "file", "file": "tmpu4zg7dbi", "filename": "Inv_307700_Service_04086.xlsm"}], "full": {"subject": "Payment Notification 00000307700", "date": "Mon, 22 Jun 2020 14:15:37 +0200", "receivers": "", "displayFrom": "system@sent-via.netsuite.com", "sender": "", "topic": "", "bcc": "", "displayTo": "<>", "headers": "Received: from ([87.227.176.38]) by [removed] for [removed];\n\tMon, 22 Jun 2020 12:15:38 +0000 (UTC)\nReceived: from [18.23.71.149] (account unsuccessfuldr32@nmail002.na3.netsuite.com HELO TIQOPOP.GAFYWOG.bwd) by customer.orbitel.bg (Exim 4.89)\twith ESMTPA id 89509C7C5024 for [removed]; Mon, 22 Jun 2020 14:15:37 +0200\nReceived: from ([165.199.8.49]) by customer.orbitel.bg with SMTP id 3943963C; Mon, 22 Jun 2020 14:15:37 +0200\nDate: Mon, 22 Jun 2020 14:15:37 +0200\nContent-Class: urn:content-classes:message\nSubject: Payment Notification 00000307700\nFrom: \"Billing Support\" <system@sent-via.netsuite.com>\n", "body": "Thank you very much for your business and continued support.\n\nPlease open the attached file to view your Invoice.\n\n Invoice Due Date: 06/22/2020\n Invoice Total Amount: $1,278.00\n\nBest Regards\n", "attachments": [{"filename": "Inv_307700_Service_04086.xlsm", "mime": "Microsoft Excel 2007+", "extension": "xlsm", "md5": "4dd9dfc92887e8c02cbc54a2abf73fb2", "sha1": "f7586d41577ed314ef5794072ddffef838996088", "sha256": "bfee589efb80fccdc2c19e16b54fa19d2a9ee7f5c359e0340cd568dce09f8ecb", "path": "/job/output/Inv_307700_Service_04086.xlsm"}]}}

Binary file not shown.

View File

@ -4,4 +4,3 @@ ipaddress
tld
sqlalchemy
psycopg2-binary
tqdm

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# coding: utf-8
import re

View File

@ -35,8 +35,7 @@ class URLhausAnalyzer(Analyzer):
namespace = "URLhaus"
if raw['query_status'] == 'no_results' \
or (raw['query_status'] == 'ok' and not raw.get('md5_hash', None) \
and not raw.get('sha256_hash', None)):
or raw['query_status'] == 'ok' and raw['md5_hash'] == None and raw['sha256_hash'] == None:
taxonomies.append(self.build_taxonomy(
'info',
namespace,

View File

@ -0,0 +1,32 @@
{
"name": "AzureTokenRevoker",
"version": "1.0",
"author": "Daniel Weiner @dmweiner",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"description": "Revoke all Microsoft Azure authentication session tokens for a list of User Principal Names",
"dataTypeList": ["thehive:case"],
"command": "AzureTokenRevoker.py",
"baseConfig": "AzureTokenRevoker",
"configurationItems": [
{"name": "redirect_uri",
"description": "Azure AD Application URI (Example: https://login.microsoftonline.com/TENANTIDHERE/oauth2/token)",
"type": "string",
"multi": false,
"required": true
},
{"name": "client_id",
"description": "Client ID/Application ID of Azure AD Registered App",
"type": "string",
"multi": false,
"required": true
},
{"name": "client_secret",
"description": "Secret for Azure AD Registered Application",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
# encoding: utf-8
# Author: Daniel Weiner @dmweiner
import requests
import traceback
import datetime
from cortexutils.responder import Responder
# Initialize Azure Class
class AzureTokenRevoker(Responder):
def __init__(self):
Responder.__init__(self)
self.client_id = self.get_params('config.client_id', None, 'Azure AD Application ID/Client ID Missing')
self.client_secret = self.get_params('config.client_secret', None, 'Azure AD Registered Application Client Secret Missing')
self.redirect_uri = self.get_params('config.redirect_uri', None, 'Set a redirect URI in Azure AD Registered Application. (ex. https://logon.microsoftonline.<tenant id>/oauth2/token)')
self.time = ''
def run(self):
try:
self.user = self.get_params('data.data', None, 'No UPN supplied to revoke credentials for')
if not self.user:
self.error("No user supplied")
base_resource = "https://graph.microsoft.com"
token_data = {
"grant_type": "client_credentials",
'client_id': self.client_id,
'client_secret': self.client_secret,
'resource': 'https://graph.microsoft.com',
'scope': 'https://graph.microsoft.com'
}
#Authenticate to the graph api
token_r = requests.post(self.redirect_uri, data=token_data)
token = token_r.json().get('access_token')
if token_r.status_code != 200:
self.error('Failure to obtain azure access token: {}'.format(token_r.content))
# Set headers for future requests
headers = {
'Authorization': 'Bearer {}'.format(token)
}
base_url = 'https://graph.microsoft.com/v1.0/'
r = requests.post(base_url + 'users/{}/revokeSignInSessions'.format(self.user), headers=headers)
if r.status_code != 200:
self.error('Failure to revoke access tokens of user {}: {}'.format(self.user, r.content))
else:
#record time of successful auth token revokation
self.time = datetime.datetime.utcnow()
except Exception as ex:
self.error(traceback.format_exc())
# Build report to return to Cortex
full_report = {"message": "User {} authentication tokens successfully revoked at {}".format(self.user, self.time)}
self.report(full_report)
if __name__ == '__main__':
AzureTokenRevoker().run()

View File

@ -0,0 +1,3 @@
cortexutils
requests
datetime

View File

@ -0,0 +1,34 @@
{
"name": "DuoLockUserAccount",
"version": "1.0",
"author": "Sven Kutzer / Gyorgy Acs, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"description": "Lock User Account in Duo Security via AdminAPI (The user will not be able to log in)",
"dataTypeList": ["thehive:case_artifact"],
"command": "Duo_Security/duoLockUserAccount.py",
"baseConfig": "Duo_Security_main",
"configurationItems": [
{
"name": "API_hostname",
"description": "Duo Admin API hostname, api-XXXXXXXX.duosecurity.com",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Integration_Key",
"description": "Integration Key",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Secret_Key",
"description": "Secret Key",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,34 @@
{
"name": "DuoUnlockUserAccount",
"version": "1.0",
"author": "Sven Kutzer / Gyorgy Acs, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"description": "Unlock User Account in Duo Security via AdminAPI (The user must complete secondary authentication)",
"dataTypeList": ["thehive:case_artifact"],
"command": "Duo_Security/duoUnlockUserAccount.py",
"baseConfig": "Duo_Security_main",
"configurationItems": [
{
"name": "API_hostname",
"description": "Duo Admin API hostname, api-XXXXXXXX.duosecurity.com",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Integration_Key",
"description": "Integration Key",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Secret_Key",
"description": "Secret Key",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,31 @@
### CortexResponder_DuoUserAccount
Rep. for Cortex Responder (TheHive project - https://github.com/TheHive-Project/CortexDocs)
to Lock/Unlock User Accounts in the Duo Admin Portal (Cisco Security)
There are two Responder available in order to change the status of a User in Duo Security via the AdminAPI (https://duo.com/docs/adminapi)
**DuoLockUserAccount** -> changes the "status" to “disabled” - The user will not be able to log in.
**DuoUnlockUserAccount** -> changes the "status" to “active” - The user must complete secondary authentication.
The Responder is looking for a "**username**" as input and queries the Duo Admin API, to receive the associated UserID.
The UserID is used to change the "status" of the particular user.
#### How to install:
* copy the folders "DuoLockUserAccount" & "DuoUnlockUserAccount" into your Cortex responders path
* install necessary python modules from the requirements.txt (**pip install -r requirements.txt**)
* restart Cortex to initialize the new Responder "**systemctl restart cortex**"
* add the ResponderConfig
* ![ResponderConfig](assets/ResponderConfig.jpg)
* enable the Responder Actions
* ![Responders](assets/Responders.jpg)
#### Add Observable type in TheHive**
* per default TheHive has no "username" Observable type, so we have to add this in the Admin settings
* ![AddObservableType](assets/AddObservableType.jpg)
#### Run the Responder action in TheHive
If you have add an observable, you can now take action and lock/unlock the User in Duo Security
* ![Demo_Lock-Unlock_DuoUser](assets/Demo_Lock-Unlock_DuoUser.gif)

View File

@ -0,0 +1,48 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
import requests
import duo_client
from datetime import datetime
class DuoLockUserAccount(Responder):
def __init__(self):
Responder.__init__(self)
self.API_hostname = self.get_param('config.API_hostname', None, "API hostname is missing")
self.iKey = self.get_param('config.Integration_Key', None, "Integration Key is missing")
self.sKey = self.get_param('config.Secret_Key', None, "Secret Key is missing")
def run(self):
Responder.run(self)
if self.get_param('data.dataType') == 'username':
str_username = self.get_param('data.data', None, 'No artifacts available')
admin_api = duo_client.Admin(self.iKey, self.sKey, self.API_hostname)
response = admin_api.get_users_by_name(username=str_username)
# print(response)
user_id=response[0]["user_id"]
# print("user_id:",user_id)
r = admin_api.update_user(user_id=user_id,status='disabled')
# print("response:",r)
if r.get('status') == 'disabled':
self.report({'message': 'User is locked in Duo Security.'})
else:
self.error('Failed to lock User Account in Duo.')
else:
self.error('Incorrect dataType. "username" expected.')
def operations(self, raw):
return [self.build_operation('AddTagToArtifact', tag='Duo User: locked')]
if __name__ == '__main__':
DuoLockUserAccount().run()

View File

@ -0,0 +1,48 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
import requests
import duo_client
from datetime import datetime
class DuoUnlockUserAccount(Responder):
def __init__(self):
Responder.__init__(self)
self.API_hostname = self.get_param('config.API_hostname', None, "API hostname is missing")
self.iKey = self.get_param('config.Integration_Key', None, "Integration Key is missing")
self.sKey = self.get_param('config.Secret_Key', None, "Secret Key is missing")
def run(self):
Responder.run(self)
if self.get_param('data.dataType') == 'username':
str_username = self.get_param('data.data', None, 'No artifacts available')
admin_api = duo_client.Admin(self.iKey, self.sKey, self.API_hostname)
response = admin_api.get_users_by_name(username=str_username)
# print(response)
user_id=response[0]["user_id"]
# print("user_id:",user_id)
r = admin_api.update_user(user_id=user_id,status='active')
# print("response:",r)
if r.get('status') == 'active':
self.report({'message': 'User is unlocked in Duo Security. The user must complete secondary authentication.'})
else:
self.error('Failed to unlock User Account in Duo.')
else:
self.error('Incorrect dataType. "username" expected.')
def operations(self, raw):
return [self.build_operation('AddTagToArtifact', tag='Duo User: reactivated')]
if __name__ == '__main__':
DuoUnlockUserAccount().run()

View File

@ -0,0 +1,4 @@
cortexutils
requests
datetime
duo_client

View File

@ -0,0 +1,6 @@
FROM python:3
WORKDIR /worker
COPY . Gmail
RUN pip install --no-cache-dir -r Gmail/requirements.txt
ENTRYPOINT Gmail/Gmail.py

243
responders/Gmail/Gmail.py Executable file
View File

@ -0,0 +1,243 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from google.oauth2 import service_account
from googleapiclient.discovery import build
import json
from thehive4py.api import TheHiveApi
from thehive4py.api import TheHiveException
from thehive4py.models import CaseObservable
from thehive4py.query import *
from urllib.parse import quote
from google.auth.exceptions import GoogleAuthError
from googleapiclient.errors import HttpError
class Gmail(Responder):
def __init__(self):
Responder.__init__(self)
self.service = self.get_param("config.service", None, "Service service missing")
self.__scopes = [
"https://mail.google.com/",
"https://www.googleapis.com/auth/gmail.settings.basic",
]
self.__thehive_url = self.get_param("config.thehive_url", None, "The Hive URL missing")
self.__thehive_api_key = self.get_param("config.thehive_api_key", None, "The Hive API key missing")
self.__gmail_domain = self.get_param("config.gmail_domain", None, "The Hive API key missing")
self.__gmail_service_account = {
"type": "service_account",
"project_id": self.get_param("config.gmail_project_id", None, "Project ID missing"),
"private_key_id": self.get_param("config.gmail_private_key_id", None, "Private Key ID missing"),
"private_key": self.get_param("config.gmail_private_key", None, "Private Key (PEM format) missing").replace("\\n", "\n"),
"client_email": self.get_param("config.gmail_client_email", None, "Client email missing"),
"client_id": self.get_param("config.gmail_client_id", None, "Client id missing"),
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/{}".format(
quote(self.get_param("config.gmail_client_email", None, "Client email missing"))
)
}
self.__gmail_service = None
self.__hive_service = None
def __not_found(self):
self.error("service named {} not found.".format(self.service))
def __get_gmail_subjects(self, caseId, query):
"""
Get all email addresses of a case for the correspondig gsuite domain
Returns: Array of Observable objects on success
"""
response = self.__hive_service.get_case_observables(caseId, query=query)
if response.status_code == 200:
return response.json()
else:
self.error("Failed to get valid response for query: {}".format(response.status_code, response.text))
def __get_filter_tag(self, tags):
"""
Get the correct tag for a dataType in a list of tags
Returns: tag string on success else None
"""
for tag in tags:
if "gmail_filter:{}".format(self.get_param("data.data")) in tag:
return tag
self.error("No valid filter tag found on observable. Tags: {}".format(tags))
def hive_check_permissions(self, user):
"""
Checks if the `user` does provide read,write permissions to the hive
Returns: True if read,write permissions are available, otherwise False
"""
roles = user["roles"]
if "read" in roles and "write" in roles:
return True
else:
return False
def hive_auth(self, url, api_key):
self.__hive_service = TheHiveApi(url, api_key)
try:
self.__hive_service.health()
except TheHiveException as e:
self.error("Responder needs TheHive connection but failed: {}".format(e))
user_object = self.__hive_service.get_current_user().json()
if not self.hive_check_permissions(user_object):
self.error("API key of `{}` is missing `read` or `write` role. Users current roles: {}".format(
user_object["name"],
user_object["roles"]
))
def gmail_impersonate(self, subject):
"""Peforms OAuth2 auth for a given service account, scope and a delegated subject
Args:
subject (str): email adress of the user, whos data shall be accessed (delegation)
Returns:
google.auth.service_account.Credentials if valid otherwise None
"""
credentials = service_account.Credentials.from_service_account_info(
info=self.__gmail_service_account,
scopes=self.__scopes,
subject=subject
)
if credentials.has_scopes(self.__scopes):
return build("gmail", "v1", credentials=credentials)
else:
self.error("Gmail service account creation failed. Aborting responder")
def trash_message(self, case_id, query):
"""Moves specified message into trash. this emails can be recovered if false-positive
"""
gmail_observables = self.__get_gmail_subjects(case_id, And(Eq("dataType", "mail"), EndsWith("data", self.__gmail_domain)))
for observable in gmail_observables:
resource = self.gmail_impersonate(observable["data"])
try:
response = resource.users().messages().list(userId=observable["data"], q=query).execute()
for message in response.get("messages", []):
resource.users().messages().delete(userId=observable["data"], id=message["id"]).execute()
observable["tags"].append("gmail_delete:{}".format(message["id"]))
except GoogleAuthError as e:
self.error("Gmail oauth failed: {}".format(e))
except HttpError as e:
self.error("Gmail api failed: {}".format(e))
for observable in gmail_observables:
self.__hive_service.update_case_observables(CaseObservable(**observable), fields=["tags"])
self.report({'message': "Deleted message"})
def block_messages(self, case_id, query):
"""Automatically labels matching emails according to query argument.
gmail search syntax can be used in query. https://support.google.com/mail/answer/7190?hl=en
"""
new_filter = {
"criteria": {
"query": query
},
"action": { # based on https://developers.google.com/gmail/api/guides/labels
"addLabelIds": ["TRASH"],
"removeLabelIds": ["INBOX"]
}
}
gmail_observables = self.__get_gmail_subjects(case_id, And(Eq("dataType", "mail"), EndsWith("data", self.__gmail_domain)))
for observable in gmail_observables:
resource = self.gmail_impersonate(observable["data"])
try:
gmail_filter = resource.users().settings().filters().create(userId=observable["data"], body=new_filter).execute()
except GoogleAuthError as e:
self.error("Gmail oauth failed: {}".format(e))
except HttpError as e:
self.error("Gmail api failed: {}".format(e))
observable["tags"].append("gmail_filter:{}:{}".format(self.get_param("data.data"), gmail_filter["id"]))
for observable in gmail_observables:
self.__hive_service.update_case_observables(CaseObservable(**observable), fields=["tags"])
self.report({'message': "Added filters"})
def unblock_messages(self, case_id):
"""Delete a previous created filter by filter ID
"""
gmail_observables = self.__get_gmail_subjects(case_id, query=
And(
Eq("dataType", "mail"), And(
EndsWith("data", self.__gmail_domain)
)
)
)
for observable in gmail_observables:
tag = self.__get_filter_tag(observable["tags"]) # a tag should look like gmail_filters:domain:1235123121
resource = self.gmail_impersonate(observable["data"])
try:
print("deleteing: {}".format(tag.split(":")[-1]))
resource.users().settings().filters().delete(userId=observable["data"], id=tag.split(":")[-1]).execute()
except GoogleAuthError as e:
self.error("Gmail oauth failed: {}".format(e))
except HttpError as e:
self.error("Gmail api failed: {}".format(e))
observable["tags"].remove(tag)
for observable in gmail_observables:
self.__hive_service.update_case_observables(CaseObservable(**observable), fields=["tags"])
self.report({'message': "Removed filters"})
def deletemessage(self, observable, dataType, caseId):
if dataType != "other":
self.error("{} needs gmail query of type 'other' but {} given".format(
self.get_param("config.service"), dataType
))
self.trash_message(caseId, observable)
def unblockdomain(self, observable, dataType, caseId):
if dataType != "domain":
self.error("{} needs data of type 'domain' but {} given".format(
self.get_param("config.service"), dataType
))
self.unblock_messages(caseId)
def unblocksender(self, observable, dataType, caseId):
if dataType != "mail":
self.error("{} needs data of type 'mail' but {} given".format(
self.get_param("config.service"), dataType
))
self.unblock_messages(caseId)
def blocksender(self, observable, dataType, caseId):
if dataType != "mail":
self.error("{} needs data of type 'mail' but {} given".format(
self.get_param("config.service"), dataType
))
self.block_messages(caseId, "from: {}".format(observable))
def blockdomain(self, observable, dataType, caseId):
if dataType != "domain":
self.error("{} needs data of type 'domain' but {} given".format(
self.get_param("config.service"), dataType
))
self.block_messages(caseId, "from: {}".format(observable))
def run(self):
Responder.run(self)
self.hive_auth(self.__thehive_url, self.__thehive_api_key)
dataType = self.get_param("data.dataType")
observable = self.get_param("data.data")
caseId = self.get_param("data._parent")
action = getattr(self, self.service, self.__not_found) # call respective func or fail with default
action(observable, dataType, caseId)
def operations(self, raw):
return [self.build_operation('AddTagToArtifact', tag='gmail:handled')]
if __name__ == '__main__':
Gmail().run()

View File

@ -0,0 +1,76 @@
{
"name": "Gmail_BlockDomain",
"version": "1.0",
"author": "David Strassegger, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "MIT",
"description": "Move emails from a given domain to trash",
"dataTypeList": ["thehive:case_artifact"],
"command": "Gmail/Gmail.py",
"baseConfig": "Gmail",
"config": {
"service": "blockdomain",
"max_tlp": 2,
"check_tlp": false,
"max_pap": 2,
"check_pap": true
},
"configurationItems": [
{
"name": "thehive_url",
"description": "URL for thehive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "thehive_api_key",
"description": "API key for TheHive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_domain",
"description": "Gsuite Domain",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_project_id",
"description": "GCP Project ID",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key_id",
"description": "Service account private key id",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key",
"description": "Service Account private key (PEM Format)",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_email",
"description": "Service Account E-Mail address",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_id",
"description": "OAuth Client ID",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,76 @@
{
"name": "Gmail_BlockSender",
"version": "1.0",
"author": "David Strassegger, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "MIT",
"description": "Move emails from a given sender to trash",
"dataTypeList": ["thehive:case_artifact"],
"command": "Gmail/Gmail.py",
"baseConfig": "Gmail",
"config": {
"service": "blocksender",
"max_tlp": 2,
"check_tlp": false,
"max_pap": 2,
"check_pap": true
},
"configurationItems": [
{
"name": "thehive_url",
"description": "URL for thehive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "thehive_api_key",
"description": "API key for TheHive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_domain",
"description": "Gsuite Domain",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_project_id",
"description": "GCP Project ID",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key_id",
"description": "Service account private key id",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key",
"description": "Service Account private key (PEM Format)",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_email",
"description": "Service Account E-Mail address",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_id",
"description": "OAuth Client ID",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,76 @@
{
"name": "Gmail_DeleteMessage",
"version": "1.0",
"author": "David Strassegger, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "MIT",
"description": "Move a given message into the trash folder",
"dataTypeList": ["thehive:case_artifact"],
"command": "Gmail/Gmail.py",
"baseConfig": "Gmail",
"config": {
"service": "deletemessage",
"max_tlp": 2,
"check_tlp": false,
"max_pap": 2,
"check_pap": true
},
"configurationItems": [
{
"name": "thehive_url",
"description": "URL for thehive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "thehive_api_key",
"description": "API key for TheHive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_domain",
"description": "Gsuite Domain",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_project_id",
"description": "GCP Project ID",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key_id",
"description": "Service account private key id",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key",
"description": "Service Account private key (PEM Format)",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_email",
"description": "Service Account E-Mail address",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_id",
"description": "OAuth Client ID",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,76 @@
{
"name": "Gmail_UnblockDomain",
"version": "1.0",
"author": "David Strassegger, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "MIT",
"description": "Remove a message filter for a given domain",
"dataTypeList": ["thehive:case_artifact"],
"command": "Gmail/Gmail.py",
"baseConfig": "Gmail",
"config": {
"service": "unblockdomain",
"max_tlp": 2,
"check_tlp": false,
"max_pap": 2,
"check_pap": true
},
"configurationItems": [
{
"name": "thehive_url",
"description": "URL for thehive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "thehive_api_key",
"description": "API key for TheHive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_domain",
"description": "Gsuite Domain",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_project_id",
"description": "GCP Project ID",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key_id",
"description": "Service account private key id",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key",
"description": "Service Account private key (PEM Format)",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_email",
"description": "Service Account E-Mail address",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_id",
"description": "OAuth Client ID",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,76 @@
{
"name": "Gmail_UnblockSender",
"version": "1.0",
"author": "David Strassegger, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "MIT",
"description": "Remove a message filter for a given sender",
"dataTypeList": ["thehive:case_artifact"],
"command": "Gmail/Gmail.py",
"baseConfig": "Gmail",
"config": {
"service": "unblocksender",
"max_tlp": 2,
"check_tlp": false,
"max_pap": 2,
"check_pap": true
},
"configurationItems": [
{
"name": "thehive_url",
"description": "URL for thehive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "thehive_api_key",
"description": "API key for TheHive instance",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_domain",
"description": "Gsuite Domain",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_project_id",
"description": "GCP Project ID",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key_id",
"description": "Service account private key id",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_private_key",
"description": "Service Account private key (PEM Format)",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_email",
"description": "Service Account E-Mail address",
"type": "string",
"multi": false,
"required": true
},
{
"name": "gmail_client_id",
"description": "OAuth Client ID",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,33 @@
### Gmail responder
This responder allows mailbox manipulation of Gsuite / Google Workspace accounts. The responder
can be used to implement message filters and delete message in a mailbox of a Gmail user.
**Usage:**
- You can block `mail` and `domain` observables
- Operations are carried out against all gmail addresses (dataType `mail`) in the case
- Example: `john.doe@gmail.com` or `peter.parker@custom.domain`
- Custom domain can be set in the responder config
- The _message ID_ of deleted messages is added as tag to the respective gmail address (dataType `mail`)
- Messages can only be deleted via Gmail query syntax (datatype `other`); this enables one to bulk delete a lot of messages
- The _filter ID_ of a blocked `domain` or `mail` gets added as tag to respective gmail address (dataType `mail`)
- All observables that get blocked/unblocked get a `gmail:handled` tag
**Constrains:**
- TheHive API key needs to provide **read** AND **write** permissions
- The Gmail user **MUST** be part of a Gsuite domain.
- Gsuite domain **MUST** have an _service account_ enabled with domain-wide delegation.
- The _service account_ **MUST** be configured with the following OAuth Scopes:
- `https://mail.google.com/`
- `https://www.googleapis.com/auth/gmail.settings.basic`
#### How to setup a Gmail service account
The responder needs a Gmail _service account_ with domain-wide delegation. The rough setup steps are:
1. enable a _service account_ via GCP
2. enable Gmail API
3. get service account `client_id` (_oauth approval screens + domain-wide delegation needed_)
4. change to Gsuite Admin panel
5. add third party app (security->API controls) with `client_id`
6. add domain-wide delegation with `client_id`
A detailed guideline for a _service account_ setup can be found in the [Google OAuth Python Client Docs](https://github.com/googleapis/google-api-python-client/blob/master/docs/oauth-server.md).

View File

@ -0,0 +1,6 @@
cortexutils~=2.1.0
google-api-python-client~=1.12.8
google-auth-httplib2~=0.0.4
google-auth-oauthlib~=0.4.2
thehive4py~=1.8.1
urllib3~=1.26.3

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_external_IP_address",
"version": "2.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block external IP address",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_external_ip.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_external_IP_address",
"description": "Name external name security rule for IP address",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block external IP address"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_external_domain",
"version": "2.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block external domain",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_external_domain.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_external_domain",
"description": "Name external security rule for domains",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block external Domain"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_external_user",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block external user",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_external_user.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_external_user",
"description": "Name security rule for external users",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block external user"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_internal_IP_address",
"version": "2.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block internal IP address",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_internal_ip.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_internal_IP_address",
"description": "Name internal security rule for IP address",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block internal IP address"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_internal_domain",
"version": "2.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block internal domain",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_internal_domain.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_internal_domain",
"description": "Name internal security rule for domains",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block internal Domain"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_internal_user",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block internal user",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_internal_user.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_internal_user",
"description": "Name internal security rule for users",
"type": "string",
"multi": false,
"required": false,
"defaultValue": "TheHive Block internal user"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_port_for_external_communication",
"version": "2.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block external port communication",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_port_for_external_communication.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_port_external_communication",
"description": "Name external security rule for port communications",
"type": "string",
"multi": false,
"required": true,
"defaultValue":"TheHive Block port for external communication"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_block_port_for_internal_communication",
"version": "2.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Block internal port communication",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/block_port_for_internal_communication.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_port_internal_communication",
"description": "Name internal security rule for port communications",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block port for internal communication"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_external_IP_address",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock external ip",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_external_ip.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Address_group_for_external_IP_address",
"description": "Name external Address Group for IP address",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block list external IP address"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_external_domain",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock external domain",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_external_domain.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Address_group_for_unblock_external_domain",
"description": "Name external Address Group for domains",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block list external domain"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_external_user",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock external user",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_external_user.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_external_user",
"description": "Name security rule for external users",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block external user"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_internal_IP_address",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock internal ip",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_internal_ip.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Address_group_for_internal_IP_address",
"description": "Name internal Address Group for IP address",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block list internal IP address"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_internal_domain",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock internal domain",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_internal_domain.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Address_group_for_unblock_internal_domain",
"description": "Name internal Address Group for domains",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block list internal domain"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_internal_user",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock internal user",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_internal_user.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Security_rule_for_block_internal_user",
"description": "Name security rule for internal users",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block internal user"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_port_for_external_communication",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock external port communication",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_port_for_external_communication.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Service_group_for_external_port_communication",
"description": "Name external Service Group for port communication",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block list for external port communication"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,56 @@
{
"name": "PaloAltoNGFW_unblock_port_for_internal_communication",
"version": "1.0.0",
"author": "Maxim Konakin, OSCD Initiative",
"url": "",
"license": "AGPL-V3",
"description": "Unblock internal port communication",
"dataTypeList": ["thehive:alert","thehive:case_artifact","thehive:case"],
"command": "PaloAltoNGFW/unblock_port_for_internal_communication.py",
"baseConfig": "PaloAltoNGFW_main",
"configurationItems": [
{
"name": "Hostname_PaloAltoNGFW",
"description": "Hostname PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "User_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Password_PaloAltoNGFW",
"description": "User PaloAltoNGFW",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Service_group_for_internal_port_communication",
"description": "Name internal Service Group for port communication",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "TheHive Block list for internal port communication"
},
{
"name": "TheHive_instance",
"description": "URL of the TheHive instance to query",
"type": "string",
"multi": false,
"required": true
},
{
"name": "TheHive_API_key",
"description": "TheHive API key with read access",
"type": "string",
"multi": false,
"required": true
}
]
}

View File

@ -0,0 +1,51 @@
### Описание работы responder модуля для системы Palo Alto NGFW
Данное описание содержит требуемые действия от инженера для интеграции работы responder с Palo Alto NGFW.
#### Installation
need install:
1. pip install cortexutils
2. pip install requests
3. pip install pan-os-python
4. pip install thehive4py
### ToDo
Для работы responders, необходимо загрузить папку PaloAltoNGFW в директорию, где храняться другие responder.
Далее необходимо:
- Выполнить перезагрузку системы cortex;
- Для настройки респондера необходимо перейти в веб консоли cortex перейти на вкладку "Organization", выбрать организацию для которой будет выполнена настройка и перейти на вкладку "Responders Config" и выполняем настройку полей для "PaloAltoNGFW_main" в соответсвии с их значениями:
![alt text](assets/Responders.jpg)
1. Hostname_PaloAltoNGFW - сетевой адрес системы PaloAltoNGFW
2. User_PaloAltoNGFW - пользователь в системе PaloAltoNGFW
3. Password_PaloAltoNGFW - пароль для пользователя в системе PaloAltoNGFW
4. Security_rule_* - имя правила безопасности в системе PaloAltoNGFW. Установлены следующие стандартные наименования правил:
4.1 Для блокировки\разблокировки имени пользователей:
4.1.1 "TheHive Block internal user"
4.1.2 "TheHive Block external user"
4.2 Для блокировки\разблокировки сетевых адресов:
4.2.1 "TheHive Block internal IP address"
4.2.2 "TheHive Block external IP address"
4.3 Для блокировки\разблокировки FQDN:
4.3.1 "TheHive Block external Domain"
4.3.2 "TheHive Block internal Domain"
4.4 Для блокировки\разблокировки портов:
4.4.1 "TheHive Block port for internal communication"
4.4.2 "TheHive Block port for external communication"
4.5 TheHive_instance - url адрес системы TheHive (используется только для типов case и alert).
Важно для каждой организации должен быть свой пользователь с API!
4.6 TheHive_API_key - API ключ для подключения к системе TheHive
Примечание: указанные правила безопасноти должны быть созданы в PaloAltoNGFW, а так же расставлены в порядке их применения.
Типы используемых данных для работы в системе TheHive:
1. Сетевой адрес - 'ip'
2. FQDN - 'hostname'
3. порт-протокол - 'port-protocol'
4. имя пользователя - 'username'
Примечание: типы 'port-protocol' и 'username' необходимо создать в системе TheHive. По умолчанию TheHive не имеет данных типов данных в Observable type, поэтому мы должны добавить его в настройках администратора.
![alt text](assets/AddObservableType.jpg)

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -0,0 +1,99 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import panos.policies
import json
class Block_domain(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_block_external_domain','TheHive Block external Domain')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'hostname' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'hostname':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressObject.refreshall(fw)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
if f"thehive-{ioc}" not in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
new_ioc_object = panos.objects.AddressObject(f"thehive-{ioc}", ioc, description="TheHive Blocked domain",type="fqdn")
fw.add(new_ioc_object)
new_ioc_object.create()
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find("TheHive Block list external domain", panos.objects.AddressGroup)
if block_list != None:
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" not in ioc_list:
ioc_list.append(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup("TheHive Block list external domain", static_value=ioc_list)
fw.add(temp1)
temp1.apply()
elif block_list == None:
temp1 = panos.objects.AddressGroup("TheHive Block list external domain", static_value=f"thehive-{ioc}")
fw.add(temp1)
temp1.apply()
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == i.about().get("name"):
rule_atrib = i.about()
temp_rule_atrib = rule_atrib.get("destination")
if "TheHive Block list external domain" not in temp_rule_atrib:
temp_rule_atrib.append("TheHive Block list external domain")
if "any" in temp_rule_atrib:
temp_rule_atrib.remove("any")
rule_atrib.update({"destination": temp_rule_atrib})
desired_rule_params = rule_atrib
else:
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s into TheHive Block list external domain from %s' % (ioc,self.name_security_rule)})
if __name__ == '__main__':
Block_domain().run()

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import panos.policies
import json
class Block_ip(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_block_external_IP_address','TheHive Block external IP address')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'ip' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'ip':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressObject.refreshall(fw)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
if f"thehive-{ioc}" not in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
new_ioc_object = panos.objects.AddressObject(f"thehive-{ioc}", ioc, description="TheHive Blocked ip address")
fw.add(new_ioc_object)
new_ioc_object.create()
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find("TheHive Block list external IP address", panos.objects.AddressGroup)
if block_list != None:
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" not in ioc_list:
ioc_list.append(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup("TheHive Block list external IP address", static_value=ioc_list)
fw.add(temp1)
temp1.apply()
elif block_list == None:
temp1 = panos.objects.AddressGroup("TheHive Block list external IP address", static_value=f"thehive-{ioc}")
fw.add(temp1)
temp1.apply()
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == i.about().get("name"):
rule_atrib = i.about()
temp_rule_atrib = rule_atrib.get("destination")
if "TheHive Block list external IP address" not in temp_rule_atrib:
temp_rule_atrib.append("TheHive Block list external IP address")
if "any" in temp_rule_atrib:
temp_rule_atrib.remove("any")
rule_atrib.update({"destination": temp_rule_atrib})
desired_rule_params = rule_atrib
else:
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s into TheHive Block list external IP address from %s' % (ioc,self.name_security_rule)})
if __name__ == '__main__':
Block_ip().run()

View File

@ -0,0 +1,81 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.policies
import json
class Block_user(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_block_external_user','TheHive Block external user')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
user = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
user=None
user_list_alert=[]
for i in list(response.json().get("artifacts")):
if 'username' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
user_list_alert.append(i)
user="".join(user_list_alert)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'username':
user=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
user_list=[]
for i in current_security_rules:
if i.about().get('name') == self.name_security_rule:
user_list=i.about().get("source_user")
if user not in user_list:
user_list.append(user)
if "any" in user_list:
user_list.remove("any")
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == i.about().get("name"):
rule_atrib = i.about()
rule_atrib.update({"source_user": user_list})
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s to %s' % (user,self.name_security_rule)})
if __name__ == '__main__':
Block_user().run()

View File

@ -0,0 +1,99 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import panos.policies
import json
class Block_domain(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_block_internal_domain','TheHive Block internal Domain')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'hostname' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'hostname':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressObject.refreshall(fw)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
if f"thehive-{ioc}" not in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
new_ioc_object = panos.objects.AddressObject(f"thehive-{ioc}", ioc, description="TheHive Blocked domain",type="fqdn")
fw.add(new_ioc_object)
new_ioc_object.create()
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find("TheHive Block list internal domain", panos.objects.AddressGroup)
if block_list != None:
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" not in ioc_list:
ioc_list.append(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup("TheHive Block list internal domain", static_value=ioc_list)
fw.add(temp1)
temp1.apply()
elif block_list == None:
temp1 = panos.objects.AddressGroup("TheHive Block list internal domain", static_value=f"thehive-{ioc}")
fw.add(temp1)
temp1.apply()
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == i.about().get("name"):
rule_atrib = i.about()
temp_rule_atrib = rule_atrib.get("destination")
if "TheHive Block list internal domain" not in temp_rule_atrib:
temp_rule_atrib.append("TheHive Block list internal domain")
if "any" in temp_rule_atrib:
temp_rule_atrib.remove("any")
rule_atrib.update({"destination": temp_rule_atrib})
desired_rule_params = rule_atrib
else:
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s into TheHive Block list internal domain from %s' % (ioc,self.name_security_rule)})
if __name__ == '__main__':
Block_domain().run()

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import panos.policies
import json
class Block_ip(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_block_internal_IP_address','TheHive Block internal IP address')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'ip' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'ip':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressObject.refreshall(fw)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
if f"thehive-{ioc}" not in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
new_ioc_object = panos.objects.AddressObject(f"thehive-{ioc}", ioc, description="TheHive Blocked ip address")
fw.add(new_ioc_object)
new_ioc_object.create()
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find("TheHive Block list internal IP address", panos.objects.AddressGroup)
if block_list != None:
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" not in ioc_list:
ioc_list.append(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup("TheHive Block list internal IP address", static_value=ioc_list)
fw.add(temp1)
temp1.apply()
elif block_list == None:
temp1 = panos.objects.AddressGroup("TheHive Block list internal IP address", static_value=f"thehive-{ioc}")
fw.add(temp1)
temp1.apply()
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == i.about().get("name"):
rule_atrib = i.about()
temp_rule_atrib = rule_atrib.get("destination")
if "TheHive Block list internal IP address" not in temp_rule_atrib:
temp_rule_atrib.append("TheHive Block list internal IP address")
if "any" in temp_rule_atrib:
temp_rule_atrib.remove("any")
rule_atrib.update({"destination": temp_rule_atrib})
desired_rule_params = rule_atrib
else:
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s into TheHive Block list internal IP address from %s' % (ioc,self.name_security_rule)})
if __name__ == '__main__':
Block_ip().run()

View File

@ -0,0 +1,81 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.policies
import json
class Block_user(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_block_internal_user','TheHive Block internal user')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
user = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
user=None
user_list_alert=[]
for i in list(response.json().get("artifacts")):
if 'username' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
user_list_alert.append(i)
user="".join(user_list_alert)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'username':
user=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
user_list=[]
for i in current_security_rules:
if i.about().get('name') == self.name_security_rule:
user_list=i.about().get("source_user")
if user not in user_list:
user_list.append(user)
if "any" in user_list:
user_list.remove("any")
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == i.about().get("name"):
rule_atrib = i.about()
rule_atrib.update({"source_user": user_list})
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s to %s' % (user,self.name_security_rule)})
if __name__ == '__main__':
Block_user().run()

View File

@ -0,0 +1,109 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import re
import panos.policies
import json
class Block_port(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_block_port_external_communication','TheHive Block port for external communication')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
data = self.get_param('data.data')
port=str(data).split('-')[0]
protocol=str(data).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
data_list=[]
data=None
for i in response.json().get("artifacts"):
if "'port-protocol'," in str(i):
data_list.append(i.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
data_list = []
for n in data:
if "'port-protocol'," in str(n):
data_list.append(n.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.ServiceObject.refreshall(fw)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
if f"thehive-{port}-{protocol}" not in str(fw.find(f"thehive-{port}-{protocol}", panos.objects.ServiceObject)):
new_port_object = panos.objects.ServiceObject(f"thehive-{port}-{protocol}", protocol, description="TheHive Blocked port",destination_port=port)
fw.add(new_port_object)
new_port_object.create()
panos.objects.ServiceGroup.refreshall(fw)
block_list = fw.find("TheHive Block list for external port communication", panos.objects.ServiceGroup)
if block_list != None:
port_list = block_list.about().get('value')
if f"thehive-{port}-{protocol}" not in port_list:
port_list.append(f"thehive-{port}-{protocol}")
temp1 = panos.objects.ServiceGroup("TheHive Block list for external port communication", value=port_list)
fw.add(temp1)
temp1.apply()
elif block_list == None:
temp1 = panos.objects.ServiceGroup("TheHive Block list for external port communication", value=f"thehive-{port}-{protocol}")
fw.add(temp1)
temp1.apply()
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == str(i.about().get("name")):
rule_atrib = i.about()
temp_rule_atrib = rule_atrib.get("service")
if "TheHive Block list for external port communication" not in temp_rule_atrib:
temp_rule_atrib.append("TheHive Block list for external port communication")
if "application-default" in temp_rule_atrib:
temp_rule_atrib.remove("application-default")
rule_atrib.update({"service": temp_rule_atrib})
desired_rule_params = rule_atrib
else:
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s into TheHive Block list for external port communication to %s' % (port,self.name_security_rule)})
if __name__ == '__main__':
Block_port().run()

View File

@ -0,0 +1,109 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import panos.policies
import re
import json
class Block_port(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_blocking_port_internal_communication','TheHive Block port for internal communication')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
data = self.get_param('data.data')
port=str(data).split('-')[0]
protocol=str(data).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
data_list=[]
data=None
for i in response.json().get("artifacts"):
if "'port-protocol'," in str(i):
data_list.append(i.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
data_list=[]
for n in data:
if "'port-protocol'," in str(n):
data_list.append(n.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.ServiceObject.refreshall(fw)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
if f"thehive-{port}-{protocol}" not in str(fw.find(f"thehive-{port}-{protocol}", panos.objects.ServiceObject)):
new_port_object = panos.objects.ServiceObject(f"thehive-{port}-{protocol}", protocol, description="TheHive Blocked port",destination_port=port)
fw.add(new_port_object)
new_port_object.create()
panos.objects.ServiceGroup.refreshall(fw)
block_list = fw.find("TheHive Block list for internal port communication", panos.objects.ServiceGroup)
if block_list != None:
port_list = block_list.about().get('value')
if f"thehive-{port}-{protocol}" not in port_list:
port_list.append(f"thehive-{port}-{protocol}")
temp1 = panos.objects.ServiceGroup("TheHive Block list for internal port communication", value=port_list)
fw.add(temp1)
temp1.apply()
elif block_list == None:
temp1 = panos.objects.ServiceGroup("TheHive Block list for internal port communication", value=f"thehive-{port}-{protocol}")
fw.add(temp1)
temp1.apply()
desired_rule_params = None
for i in current_security_rules:
if self.name_security_rule == i.about().get("name"):
rule_atrib = i.about()
temp_rule_atrib = rule_atrib.get("service")
if "TheHive Block list for internal port communication" not in temp_rule_atrib:
temp_rule_atrib.append("TheHive Block list for internal port communication")
if "application-default" in temp_rule_atrib:
temp_rule_atrib.remove("application-default")
rule_atrib.update({"service": temp_rule_atrib})
desired_rule_params = rule_atrib
else:
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
fw.commit()
self.report({'message': 'Responder successfully added %s into TheHive Block list for internal port communication from %s' % (port,self.name_security_rule)})
if __name__ == '__main__':
Block_port().run()

View File

@ -0,0 +1,4 @@
cortexutils
requests
pan-os-python
thehive4py

View File

@ -0,0 +1,80 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import panos.policies
import json
class Unblock_domain(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_external_Address_Group_for_domain = self.get_param('config.Address_group_for_unblock_external_domain',"TheHive Block list external domain")
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'hostname' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'hostname':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find(self.name_external_Address_Group_for_domain, panos.objects.AddressGroup)
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" in ioc_list:
ioc_list.remove(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup(self.name_external_Address_Group_for_domain, static_value=ioc_list)
fw.add(temp1)
temp1.apply()
panos.objects.AddressObject.refreshall(fw)
if f"thehive-{ioc}" in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
try:
deleted_ioc = fw.find(f"thehive-{ioc}", panos.objects.AddressObject)
deleted_ioc.delete()
except:
self.report({'message': 'Responder did not comlite. Warning in AddressObject'})
self.report({'message': 'Responder successfully deleted %s from %s' % (f"thehive-{ioc}",self.name_external_Address_Group_for_domain)})
fw.commit()
if __name__ == '__main__':
Unblock_domain().run()

View File

@ -0,0 +1,77 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import json
class Unblock_ip(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_external_Address_Group = self.get_param('config.Address_group_for_unblock_external_IP_address',"TheHive Block list external IP address")
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'ip' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'ip':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find(self.name_external_Address_Group, panos.objects.AddressGroup)
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" in ioc_list:
ioc_list.remove(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup(self.name_external_Address_Group, static_value=ioc_list)
fw.add(temp1)
temp1.apply()
panos.objects.AddressObject.refreshall(fw)
if f"thehive-{ioc}" in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
try:
deleted_ioc = fw.find(f"thehive-{ioc}", panos.objects.AddressObject)
deleted_ioc.delete()
except:
self.report({'message': 'Responder did not comlite. Warning in AddressObject'})
self.report({'message': 'Responder successfully deleted %s from %s' % (f"thehive-{ioc}",self.name_external_Address_Group)})
fw.commit()
if __name__ == '__main__':
Unblock_ip().run()

View File

@ -0,0 +1,77 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.policies
import json
class Unblock_user(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.name_security_rule','TheHive Block external user')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
user = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
user=None
user_list_alert=[]
for i in list(response.json().get("artifacts")):
if 'username' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
user_list_alert.append(i)
user="".join(user_list_alert)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'username':
user=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
user_list=[]
rule_atrib=[]
for i in current_security_rules:
if i.about().get('name') == self.name_security_rule:
rule_atrib = i.about()
user_list=i.about().get("source_user")
if user in user_list:
user_list.remove(user)
rule_atrib.update({"source_user": user_list})
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
self.report({'message': 'Responder successfully deleted %s from %s' % (user,self.name_security_rule)})
fw.commit()
if __name__ == '__main__':
Unblock_user().run()

View File

@ -0,0 +1,80 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import panos.policies
import json
class Unblock_domain(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_internal_Address_Group_for_domain = self.get_param('config.Address_group_for_unblock_internal_domain',"TheHive Block list internal domain")
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'hostname' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'hostname':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find(self.name_internal_Address_Group_for_domain, panos.objects.AddressGroup)
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" in ioc_list:
ioc_list.remove(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup(self.name_internal_Address_Group_for_domain, static_value=ioc_list)
fw.add(temp1)
temp1.apply()
panos.objects.AddressObject.refreshall(fw)
if f"thehive-{ioc}" in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
try:
deleted_ioc = fw.find(f"thehive-{ioc}", panos.objects.AddressObject)
deleted_ioc.delete()
except:
self.report({'message': 'Responder did not comlite. Warning in AddressObject'})
self.report({'message': 'Responder successfully deleted %s from %s' % (ioc,self.name_internal_Address_Group_for_domain)})
fw.commit()
if __name__ == '__main__':
Unblock_domain().run()

View File

@ -0,0 +1,78 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import json
class Unblock_ip(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_internal_Address_Group = self.get_param('config.Address_group_for_unblock_internal_IP_address',"TheHive Block list internal IP address")
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
ioc = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
ioc=None
ioc_clear=[]
for i in list(response.json().get("artifacts")):
if 'ip' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
ioc_clear.append(i)
ioc="".join(ioc_clear)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'ip':
ioc=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.AddressGroup.refreshall(fw)
block_list = fw.find(self.name_internal_Address_Group, panos.objects.AddressGroup)
ioc_list = block_list.about().get('static_value')
if f"thehive-{ioc}" in ioc_list:
ioc_list.remove(f"thehive-{ioc}")
temp1 = panos.objects.AddressGroup(self.name_internal_Address_Group, static_value=ioc_list)
fw.add(temp1)
temp1.apply()
panos.objects.AddressObject.refreshall(fw)
if f"thehive-{ioc}" in str(fw.find(f"thehive-{ioc}", panos.objects.AddressObject)):
try:
deleted_ioc = fw.find(f"thehive-{ioc}", panos.objects.AddressObject)
deleted_ioc.delete()
except:
self.report({'message': 'Responder did not comlite. Warning in AddressObject'})
self.report({'message': 'Responder successfully deleted %s from %s' % (f"thehive-{ioc}",self.name_internal_Address_Group)})
fw.commit()
if __name__ == '__main__':
Unblock_ip().run()

View File

@ -0,0 +1,77 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.policies
import json
class Unblock_user(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_security_rule = self.get_param('config.Security_rule_for_unblock_internal_user','TheHive Block internal user')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
user = self.get_param('data.data')
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
user=None
user_list_alert=[]
for i in list(response.json().get("artifacts")):
if 'username' in str(i):
ioc = i.get("data")
for i in ioc:
if i == "[" or i == "]":
continue
else:
user_list_alert.append(i)
user="".join(user_list_alert)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
for n in data:
if n.get('dataType') == 'username':
user=n.get('data')
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
rulebase = panos.policies.Rulebase()
fw.add(rulebase)
current_security_rules =panos.policies.SecurityRule.refreshall(rulebase)
user_list=[]
rule_atrib=[]
for i in current_security_rules:
if i.about().get('name') == self.name_security_rule:
rule_atrib = i.about()
user_list=i.about().get("source_user")
if user in user_list:
user_list.remove(user)
rule_atrib.update({"source_user": user_list})
desired_rule_params = rule_atrib
new_rule = panos.policies.SecurityRule(**desired_rule_params)
rulebase.add(new_rule)
new_rule.apply()
self.report({'message': 'Responder successfully deleted %s from %s' % (user,self.name_security_rule)})
fw.commit()
if __name__ == '__main__':
Unblock_user().run()

View File

@ -0,0 +1,80 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import re
import json
class Unblock_port(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_external_Service_Group = self.get_param('config.Service_group_for_unblock_external_port','TheHive Block list for external port communication')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
data = self.get_param('data.data')
port=str(data).split('-')[0]
protocol=str(data).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
data_list=[]
data=None
for i in response.json().get("artifacts"):
if "'port-protocol'," in str(i):
data_list.append(i.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
data_list=[]
for n in data:
if "'port-protocol'," in str(n):
data_list.append(n.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.ServiceGroup.refreshall(fw)
block_list = fw.find(self.name_external_Service_Group, panos.objects.ServiceGroup)
port_list = block_list.about().get('value')
if f"thehive-{port}-{protocol}" in port_list:
port_list.remove(f"thehive-{port}-{protocol}")
temp1 = panos.objects.ServiceGroup(self.name_external_Service_Group, value=port_list)
fw.add(temp1)
temp1.apply()
panos.objects.ServiceObject.refreshall(fw)
self.report({'message': 'Responder successfully deleted %s from %s' % (f"thehive-{port}-{protocol}",self.name_external_Service_Group)})
fw.commit()
if __name__ == '__main__':
Unblock_port().run()

View File

@ -0,0 +1,80 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.responder import Responder
from thehive4py.api import TheHiveApi
from panos import firewall
import panos.objects
import re
import json
class Unblock_port(Responder):
def __init__(self):
Responder.__init__(self)
self.hostname_PaloAltoNGFW = self.get_param('config.Hostname_PaloAltoNGFW')
self.User_PaloAltoNGFW = self.get_param('config.User_PaloAltoNGFW')
self.Password_PaloAltoNGFW = self.get_param('config.Password_PaloAltoNGFW')
self.name_internal_Service_Group = self.get_param('config.Internal_service_group_for_unblock_internal_port','TheHive Block list for internal port communication')
self.TheHive_instance = self.get_param('config.TheHive_instance')
self.TheHive_API_key = self.get_param('config.TheHive_API_key', 'YOUR_KEY_HERE')
self.api = TheHiveApi(self.TheHive_instance, self.TheHive_API_key)
def run(self):
self.instance_type = self.get_param('data._type')
if self.instance_type == 'case_artifact':
data = self.get_param('data.data')
port=str(data).split('-')[0]
protocol=str(data).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'alert':
alertId = self.get_param('data.id')
response = self.api.get_alert(alertId)
data_list=[]
data=None
for i in response.json().get("artifacts"):
if "'port-protocol'," in str(i):
data_list.append(i.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
if self.instance_type == 'case':
import requests
case_id = self.get_param('data._id')
payload = {
"query": { "_parent": { "_type": "case", "_query": { "_id": case_id } } },
"range": "all"
}
headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(self.TheHive_API_key) }
thehive_api_url_case_search = '{}/api/case/artifact/_search'.format(self.TheHive_instance)
r = requests.post(thehive_api_url_case_search, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
self.error(json.dumps(r.text))
a=None
data = r.json()
data_list=[]
for n in data:
if "'port-protocol'," in str(n):
data_list.append(n.get("data"))
port=str(data_list).split('-')[0]
protocol=str(data_list).split('-')[1]
protocol=re.findall(r'[a-z]+',str(protocol)); protocol=str("".join(protocol)).lower()
port=re.findall(r'[0-9]+',str(port)); port="".join(port)
fw = firewall.Firewall(self.hostname_PaloAltoNGFW, api_username=self.User_PaloAltoNGFW, api_password=self.Password_PaloAltoNGFW)
panos.objects.ServiceGroup.refreshall(fw)
block_list = fw.find(self.name_internal_Service_Group, panos.objects.ServiceGroup)
port_list = block_list.about().get('value')
if f"thehive-{port}-{protocol}" in port_list:
port_list.remove(f"thehive-{port}-{protocol}")
temp1 = panos.objects.ServiceGroup(self.name_internal_Service_Group, value=port_list)
fw.add(temp1)
temp1.apply()
panos.objects.ServiceObject.refreshall(fw)
self.report({'message': 'Responder successfully deleted %s from %s' % (port,self.name_internal_Service_Group)})
fw.commit()
if __name__ == '__main__':
Unblock_port().run()