fix host log level
This commit is contained in:
Родитель
64e95691e1
Коммит
6f780c820b
|
@ -0,0 +1 @@
|
|||
.venv
|
Двоичный файл не отображается.
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,18 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_advanced_dark_web(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_advanced_dark_web(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -37,16 +39,21 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_botnet_compromised_credentials(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
user = os.environ.get("ZeroFoxUsername")
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_botnet(
|
||||
zerofox, listed_after=query_from
|
||||
)
|
||||
batches = get_cti_botnet(zerofox, listed_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
user = os.environ.get("ZeroFoxUsername")
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_breaches(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_breaches(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
user = os.environ.get("ZeroFoxUsername")
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_c2_domains(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_c2_domains(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
user = os.environ.get("ZeroFoxUsername")
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_compromised_credentials(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_compromised_credentials(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
@ -55,8 +59,7 @@ def get_zf_client():
|
|||
return ZeroFoxClient(user, token)
|
||||
|
||||
|
||||
def get_cti_compromised_credentials(
|
||||
client: ZeroFoxClient, created_after: str):
|
||||
def get_cti_compromised_credentials(client: ZeroFoxClient, created_after: str):
|
||||
url_suffix = "compromised-credentials/"
|
||||
params = dict(created_after=created_after)
|
||||
return client.cti_request(
|
||||
|
|
|
@ -46,16 +46,18 @@ class SentinelConnector:
|
|||
if not data:
|
||||
return
|
||||
split_data = self._split_big_request(data)
|
||||
await asyncio.gather(*[
|
||||
self._post_data(
|
||||
session=self.session,
|
||||
customer_id=self.customer_id,
|
||||
shared_key=self.shared_key,
|
||||
body=d,
|
||||
log_type=self.log_type
|
||||
)
|
||||
for d in split_data
|
||||
])
|
||||
await asyncio.gather(
|
||||
*[
|
||||
self._post_data(
|
||||
session=self.session,
|
||||
customer_id=self.customer_id,
|
||||
shared_key=self.shared_key,
|
||||
body=d,
|
||||
log_type=self.log_type,
|
||||
)
|
||||
for d in split_data
|
||||
]
|
||||
)
|
||||
|
||||
async def __aenter__(self):
|
||||
return self
|
||||
|
@ -88,20 +90,20 @@ class SentinelConnector:
|
|||
bytes_to_hash = bytes(string_to_hash, encoding="utf-8")
|
||||
decoded_key = base64.b64decode(shared_key)
|
||||
encoded_hash = base64.b64encode(
|
||||
hmac.new(decoded_key, bytes_to_hash,
|
||||
digestmod=hashlib.sha256).digest()
|
||||
hmac.new(decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest()
|
||||
).decode()
|
||||
authorization = f"SharedKey {customer_id}:{encoded_hash}"
|
||||
return authorization
|
||||
|
||||
async def _post_data(self, session: aiohttp.ClientSession, customer_id, shared_key, body, log_type):
|
||||
async def _post_data(
|
||||
self, session: aiohttp.ClientSession, customer_id, shared_key, body, log_type
|
||||
):
|
||||
events_number = len(body)
|
||||
body = json.dumps(body)
|
||||
method = "POST"
|
||||
content_type = "application/json"
|
||||
resource = "/api/logs"
|
||||
rfc1123date = datetime.now(timezone.utc).strftime(
|
||||
"%a, %d %b %Y %H:%M:%S GMT")
|
||||
rfc1123date = datetime.now(timezone.utc).strftime("%a, %d %b %Y %H:%M:%S GMT")
|
||||
content_length = len(body)
|
||||
signature = self._build_signature(
|
||||
customer_id,
|
||||
|
@ -122,7 +124,7 @@ class SentinelConnector:
|
|||
}
|
||||
|
||||
async with session.post(uri, data=body, headers=headers) as response:
|
||||
if (200 <= response.status <= 299):
|
||||
if 200 <= response.status <= 299:
|
||||
logging.info(
|
||||
f"{events_number} events have been successfully sent to Microsoft Sentinel"
|
||||
)
|
||||
|
|
|
@ -3,6 +3,7 @@ from typing import Dict
|
|||
import requests
|
||||
|
||||
from connections.exceptions import ApiResponseException
|
||||
|
||||
TIMEOUT = 30
|
||||
|
||||
|
||||
|
@ -59,8 +60,7 @@ class ZeroFoxClient:
|
|||
**kwargs,
|
||||
)
|
||||
if response.status_code != ok_code:
|
||||
logging.error(
|
||||
f"Failed to {method} {url}. Response: {response.text}")
|
||||
logging.error(f"Failed to {method} {url}. Response: {response.text}")
|
||||
raise ApiResponseException(method, url=url, res=response)
|
||||
if response.status_code == requests.codes["no_content"]:
|
||||
return None
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_credit_cards(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_credit_cards(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
@ -55,9 +59,7 @@ def get_zf_client():
|
|||
return ZeroFoxClient(user, token)
|
||||
|
||||
|
||||
def get_cti_credit_cards(
|
||||
client: ZeroFoxClient, created_after: str
|
||||
):
|
||||
def get_cti_credit_cards(client: ZeroFoxClient, created_after: str):
|
||||
url_suffix = "credit-cards/"
|
||||
params = dict(created_after=created_after)
|
||||
return client.cti_request(
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_dark_web(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_dark_web(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_discord(
|
||||
zerofox, timestamp_after=query_from
|
||||
)
|
||||
batches = get_cti_discord(zerofox, timestamp_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
user = os.environ.get("ZeroFoxUsername")
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_disruption(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_disruption(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
user = os.environ.get("ZeroFoxUsername")
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_email_addresses(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_email_addresses(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
user = os.environ.get("ZeroFoxUsername")
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_exploits(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_exploits(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
"logLevel": {
|
||||
"default": "Debug",
|
||||
"Host.Results": "Debug",
|
||||
"Function": "Debug",
|
||||
"default": "Information",
|
||||
"Host.Results": "Information",
|
||||
"Function": "Information",
|
||||
"Host.Aggregator": "Information"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,18 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_irc(
|
||||
zerofox, timestamp_after=query_from
|
||||
)
|
||||
batches = get_cti_irc(zerofox, timestamp_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_malware(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_malware(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_national_ids(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_national_ids(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
@ -55,9 +59,7 @@ def get_zf_client():
|
|||
return ZeroFoxClient(user, token)
|
||||
|
||||
|
||||
def get_cti_national_ids(
|
||||
client: ZeroFoxClient, created_after: str
|
||||
):
|
||||
def get_cti_national_ids(client: ZeroFoxClient, created_after: str):
|
||||
url_suffix = "national-ids/"
|
||||
params = dict(created_after=created_after)
|
||||
return client.cti_request(
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_phishing(
|
||||
zerofox, scanned_after=query_from
|
||||
)
|
||||
batches = get_cti_phishing(zerofox, scanned_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_phone_numbers(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_phone_numbers(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
@ -55,9 +59,7 @@ def get_zf_client():
|
|||
return ZeroFoxClient(user, token)
|
||||
|
||||
|
||||
def get_cti_phone_numbers(
|
||||
client: ZeroFoxClient, created_after: str
|
||||
):
|
||||
def get_cti_phone_numbers(client: ZeroFoxClient, created_after: str):
|
||||
url_suffix = "phone-numbers/"
|
||||
params = dict(created_after=created_after)
|
||||
return client.cti_request(
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_ransomware(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_ransomware(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,18 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_telegram(
|
||||
zerofox, timestamp_after=query_from
|
||||
)
|
||||
batches = get_cti_telegram(zerofox, timestamp_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
@ -56,9 +60,7 @@ def get_zf_client():
|
|||
return ZeroFoxClient(user, token)
|
||||
|
||||
|
||||
def get_cti_telegram(
|
||||
client: ZeroFoxClient, timestamp_after: str
|
||||
):
|
||||
def get_cti_telegram(client: ZeroFoxClient, timestamp_after: str):
|
||||
url_suffix = "telegram/"
|
||||
params = dict(timestamp_after=timestamp_after)
|
||||
return client.cti_request(
|
||||
|
|
|
@ -13,8 +13,8 @@ SECOND_PAGE_URL = "https://second_page"
|
|||
URL = "https://api.zerofox.com"
|
||||
|
||||
|
||||
class TestZeroFoxCTI():
|
||||
|
||||
class TestZeroFoxCTI:
|
||||
|
||||
@responses.activate
|
||||
def test_cti_generator_is_provided(self):
|
||||
zerofox = ZeroFoxClient(user=USER, token=TOKEN)
|
||||
|
@ -30,8 +30,8 @@ class TestZeroFoxCTI():
|
|||
"""Prepare mock responses for queries through the requests package."""
|
||||
responses.post(
|
||||
url=f"{URL}/auth/token/",
|
||||
match=[matchers.urlencoded_params_matcher(
|
||||
dict(username=USER, password=TOKEN))
|
||||
match=[
|
||||
matchers.urlencoded_params_matcher(dict(username=USER, password=TOKEN))
|
||||
],
|
||||
json=dict(access=CTI_TOKEN),
|
||||
)
|
||||
|
@ -43,18 +43,17 @@ class TestZeroFoxCTI():
|
|||
}
|
||||
|
||||
endpoint_first_page_json = dict(
|
||||
next=SECOND_PAGE_URL, results=[
|
||||
dict(index=f"r{i}") for i in range(2)]
|
||||
next=SECOND_PAGE_URL, results=[dict(index=f"r{i}") for i in range(2)]
|
||||
)
|
||||
responses.get(
|
||||
url=f"{URL}/cti/{ENDPOINT}", headers=cti_header,
|
||||
json=endpoint_first_page_json
|
||||
url=f"{URL}/cti/{ENDPOINT}",
|
||||
headers=cti_header,
|
||||
json=endpoint_first_page_json,
|
||||
)
|
||||
|
||||
endpoint_second_page_json = dict(
|
||||
next=None, results=[dict(index=f"r{i}") for i in range(2, 4)]
|
||||
)
|
||||
responses.get(
|
||||
url=SECOND_PAGE_URL, headers=cti_header,
|
||||
json=endpoint_second_page_json
|
||||
url=SECOND_PAGE_URL, headers=cti_header, json=endpoint_second_page_json
|
||||
)
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,18 +38,20 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_threat_actors(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_threat_actors(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
|
|
@ -6,13 +6,12 @@ import aiohttp
|
|||
import azure.functions as func
|
||||
from connections.sentinel import SentinelConnector
|
||||
from connections.zerofox import ZeroFoxClient
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
utc_timestamp = (
|
||||
now.isoformat()
|
||||
)
|
||||
utc_timestamp = now.isoformat()
|
||||
|
||||
if mytimer.past_due:
|
||||
logging.info("The timer is past due!")
|
||||
|
@ -20,8 +19,11 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
customer_id = os.environ.get("WorkspaceID")
|
||||
shared_key = os.environ.get("WorkspaceKey")
|
||||
|
||||
query_from = max(
|
||||
mytimer.schedule_status["Last"], (now - timedelta(days=1)).isoformat())
|
||||
query_from = (
|
||||
max(parse_last_update(mytimer), (now - timedelta(days=1)))
|
||||
.replace(tzinfo=None)
|
||||
.isoformat()
|
||||
)
|
||||
logging.info(f"Querying ZeroFox since {query_from}")
|
||||
|
||||
zerofox = get_zf_client()
|
||||
|
@ -36,17 +38,19 @@ async def main(mytimer: func.TimerRequest) -> None:
|
|||
log_type=log_type,
|
||||
)
|
||||
async with sentinel:
|
||||
batches = get_cti_vulnerabilities(
|
||||
zerofox, created_after=query_from
|
||||
)
|
||||
batches = get_cti_vulnerabilities(zerofox, created_after=query_from)
|
||||
for batch in batches:
|
||||
await sentinel.send(batch)
|
||||
if sentinel.failed_sent_events_number:
|
||||
logging.error(
|
||||
f"Failed to send {sentinel.failed_sent_events_number} events"
|
||||
)
|
||||
logging.info(f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel.")
|
||||
logging.error(f"Failed to send {sentinel.failed_sent_events_number} events")
|
||||
logging.info(
|
||||
f"Connector {log_type} ran at {utc_timestamp}, \
|
||||
sending {sentinel.successfull_sent_events_number} events to Sentinel."
|
||||
)
|
||||
|
||||
|
||||
def parse_last_update(mytimer):
|
||||
return parser.parse(mytimer.schedule_status["Last"])
|
||||
|
||||
|
||||
def get_zf_client():
|
||||
|
@ -55,9 +59,7 @@ def get_zf_client():
|
|||
return ZeroFoxClient(user, token)
|
||||
|
||||
|
||||
def get_cti_vulnerabilities(
|
||||
client: ZeroFoxClient, created_after: str
|
||||
):
|
||||
def get_cti_vulnerabilities(client: ZeroFoxClient, created_after: str):
|
||||
url_suffix = "vulnerabilities/"
|
||||
params = dict(created_after=created_after)
|
||||
return client.cti_request(
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
# Do not include azure-functions-worker in this file
|
||||
# The Python Worker is managed by the Azure Functions platform
|
||||
# Manually managing azure-functions-worker may cause unexpected issues
|
||||
|
||||
requests==2.32.2
|
||||
azure-functions==1.19.0
|
||||
responses==0.25.0
|
||||
pytest==8.2.0
|
||||
aiohttp==3.9.5
|
||||
python-dateutil==2.9.0.post0
|
||||
|
|
Двоичные данные
Solutions/ZeroFox/Package/3.0.0.zip
Двоичные данные
Solutions/ZeroFox/Package/3.0.0.zip
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -63,13 +63,6 @@
|
|||
"text": "This Solution installs the data connector for ZeroFox. You can get ZeroFox custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dataconnectors2-text",
|
||||
"type": "Microsoft.Common.TextBlock",
|
||||
"options": {
|
||||
"text": "This Solution installs the data connector for ZeroFox. You can get ZeroFox custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dataconnectors-link2",
|
||||
"type": "Microsoft.Common.TextBlock",
|
||||
|
|
|
@ -1158,10 +1158,10 @@
|
|||
"status": "Available",
|
||||
"requiredDataConnectors": [
|
||||
{
|
||||
"connectorId": "ZeroFox_Alert_Polling",
|
||||
"dataTypes": [
|
||||
"ZeroFoxAlertPoller_CL"
|
||||
],
|
||||
"connectorId": "ZeroFox_Alert_Polling"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tactics": [
|
||||
|
@ -1268,10 +1268,10 @@
|
|||
"status": "Available",
|
||||
"requiredDataConnectors": [
|
||||
{
|
||||
"connectorId": "ZeroFox_Alert_Polling",
|
||||
"dataTypes": [
|
||||
"ZeroFoxAlertPoller_CL"
|
||||
],
|
||||
"connectorId": "ZeroFox_Alert_Polling"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tactics": [
|
||||
|
@ -1378,10 +1378,10 @@
|
|||
"status": "Available",
|
||||
"requiredDataConnectors": [
|
||||
{
|
||||
"connectorId": "ZeroFox_Alert_Polling",
|
||||
"dataTypes": [
|
||||
"ZeroFoxAlertPoller_CL"
|
||||
],
|
||||
"connectorId": "ZeroFox_Alert_Polling"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tactics": [
|
||||
|
@ -1488,10 +1488,10 @@
|
|||
"status": "Available",
|
||||
"requiredDataConnectors": [
|
||||
{
|
||||
"connectorId": "ZeroFox_Alert_Polling",
|
||||
"dataTypes": [
|
||||
"ZeroFoxAlertPoller_CL"
|
||||
],
|
||||
"connectorId": "ZeroFox_Alert_Polling"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tactics": [
|
||||
|
|
Загрузка…
Ссылка в новой задаче