Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zerofox/add cac data #35183

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Packs/ZeroFox/Integrations/ZeroFox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,38 @@ Looks for registered exploits in ZeroFox's CTI feeds.
| ZeroFox.Exploits.CVECode | string | CVE Code to identify the exploit. |
| ZeroFox.Exploits.URLs | string | URLs associated to the threat separated by commas. |

### zerofox-get-compromised-credentials

***
Gets compromised credentials data for a given ZeroFox alert and uploads it to the current investigation War Room.

#### Base Command

`zerofox-get-compromised-credentials`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| alert_id | The ID of an alert. Can be retrieved running the zerofox-list-alerts command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| File.Size | Number | The size of the file. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| File.SHA512 | String | The SHA512 hash of the file. |
| File.Name | String | The name of the file. |
| File.SSDeep | String | The SSDeep hash of the file. |
| File.EntryID | String | The entry ID of the file. |
| File.Info | String | File information. |
| File.Type | String | The file type. |
| File.MD5 | String | The MD5 hash of the file. |
| File.Extension | String | The file extension. |


## Incident Mirroring

You can enable incident mirroring between Cortex XSOAR incidents and ZeroFox corresponding events (available from Cortex XSOAR version 6.0.0).
Expand Down
70 changes: 67 additions & 3 deletions Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import demistomock as demisto
from CommonServerPython import *


""" IMPORTS """
from dateparser import parse as parse_date
from datetime import datetime
Expand Down Expand Up @@ -43,6 +42,39 @@ def __init__(
self.only_escalated = only_escalated
self.auth_token = ""

def raw_api_request(
DNRRomero marked this conversation as resolved.
Show resolved Hide resolved
self,
method: str,
url_suffix: str = "/",
full_url: str | None = None,
params: dict[str, str] | None = None,
data: dict[str, Any] | None = None,
ok_codes: tuple[int, ...] = None,
files: dict[str, Any] | None = None,
prefix: str | None = "1.0",
empty_response: bool = False,
error_handler: Callable[[Any], Any] | None = None,
**kwargs
) -> Response:
pref_string = f"/{prefix}" if prefix else ""

headers = self.get_api_request_header()
return self._http_request(
method=method,
url_suffix=urljoin(pref_string, url_suffix),
full_url=full_url,
headers=headers,
params=params,
json_data=data,
ok_codes=ok_codes,
empty_valid_codes=(200, 201),
return_empty_response=empty_response,
error_handler=error_handler,
files=files,
resp_type="response",
**kwargs
)

def api_request(
self,
method: str,
Expand All @@ -51,11 +83,12 @@ def api_request(
headers_builder_type: str | None = 'api',
params: dict[str, str] | None = None,
data: dict[str, Any] | None = None,
retries: int = 0,
ok_codes: tuple[int, ...] = None,
files: dict[str, Any] | None = None,
prefix: str | None = "1.0",
empty_response: bool = False,
error_handler: Callable[[Any], Any] | None = None,
**kwargs
) -> dict[str, Any]:
"""
:param method: HTTP request type
Expand Down Expand Up @@ -102,11 +135,12 @@ def api_request(
headers=headers,
params=params,
json_data=data,
retries=retries,
ok_codes=ok_codes,
empty_valid_codes=(200, 201),
return_empty_response=empty_response,
error_handler=error_handler,
files=files,
**kwargs
)

def handle_auth_error(self, raw_response: Response):
Expand Down Expand Up @@ -489,6 +523,22 @@ def get_alert_attachments(self, alert_id: int) -> dict[str, Any]:
)
return response_content

def get_compromised_credentials(self, alert_id: str) -> str:
"""
:param alert_id: The ID of the alert.
:return: HTTP request content.
"""
url_suffix = f"/alerts/{alert_id}/breach_csv/"
response_content: Response = self.raw_api_request(
"GET",
prefix="2.0",
ok_codes=(200, 404),
url_suffix=url_suffix,
)
if response_content.status_code == 404:
return ""
return response_content.text

def get_cti_c2_domains(self, domain: str) -> dict[str, Any]:
"""
:param domain: The domain to lookup in c2-domains CTI Feed
Expand Down Expand Up @@ -1760,6 +1810,19 @@ def get_alert_attachments_command(
)


def get_compromised_credentials_command(
client: ZFClient,
args: dict[str, Any]
) -> CommandResults:
alert_id = args["alert_id"]
credentials = client.get_compromised_credentials(alert_id)
if credentials:
return fileResult(f"breach_{alert_id}.csv", credentials)
return CommandResults(
readable_output=f"No compromised credentials were found for {alert_id=}",
)


def compromised_domain_command(
client: ZFClient,
args: dict[str, Any]
Expand Down Expand Up @@ -1933,6 +1996,7 @@ def main():
"zerofox-submit-threat": submit_threat_command,
"zerofox-send-alert-attachment": send_alert_attachment_command,
"zerofox-get-alert-attachments": get_alert_attachments_command,
"zerofox-get-compromised-credentials": get_compromised_credentials_command,

# ZeroFox CTI Feed
"zerofox-search-compromised-domain": compromised_domain_command,
Expand Down
Loading
Loading