Skip to content

Commit

Permalink
Fixed full scans iteration and updated documentation (#23)
Browse files Browse the repository at this point in the history
* Fixed full scans iteration and updated documentation

* Removed incorrect return comment

* Updated README.md to use the same example as in the example script for setting from_time

* Update documentation to remove unneeded environment variable example
  • Loading branch information
dacoburn authored Jan 20, 2025
1 parent a377e69 commit 0ac14f8
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 36 deletions.
90 changes: 62 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This tool supports the following connectors:
- Elasticsearch
- WebHook
- Slack
- SumoLogic

### Other SIEM Integrations

Expand Down Expand Up @@ -38,14 +39,14 @@ The connectors supported by this script have some shared configuration in order
```python
import os
from socketsync.core import Core
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
days_ago = os.getenv("DAYS_AGO") or exit(1)

from_time = days_ago * 24 * 60 * 60 #Convert days to seconds

core = Core(
api_key=api_key,
from_time=from_time,
Expand Down Expand Up @@ -73,15 +74,16 @@ Initializing Options:
import os
from socketsync.core import Core
from socketsync.connectors.csv import CSV
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
days_ago = os.getenv("DAYS_AGO") or exit(1)

report_id = os.getenv("SOCKET_REPORT_ID")

from_time = days_ago * 24 * 60 * 60 #Convert days to seconds

core = Core(
api_key=api_key,
from_time=from_time,
Expand Down Expand Up @@ -114,15 +116,15 @@ Initializing Options:
import os
from socketsync.core import Core
from socketsync.connectors.bigquery import BigQuery
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
days_ago = os.getenv("DAYS_AGO") or exit(1)
report_id = os.getenv("SOCKET_REPORT_ID")

from_time = days_ago * 24 * 60 * 60 #Convert days to seconds

core = Core(
api_key=api_key,
from_time=from_time,
Expand All @@ -134,6 +136,38 @@ if __name__ == '__main__':
errors = bigquery.add_dataset(issue_data, streaming=True)
```

### SumoLogic

The SumoLogic plugin will send results to a HTTP Collector URL for SumoLogic

Initializing Options:

| Option | Required | Default | Description |
|--------|----------|---------|---------------------------------------------------|
| http_source_url | True | None | This is the HTTP Collector URL to send results to |

```python
import os
from socketsync.core import Core
from socketsync.connectors.sumologic import Sumologic
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
http_source_url = os.getenv("SUMO_HTTP_URL")
core = Core(
api_key=api_key,
from_time=from_time,
)
issue_data = core.get_issues()
sumo = Sumologic(http_source_url=http_source_url)
sumo.send_events(issue_data, "socket-sync-alerts")
```

### Panther
The Panther connector requires you to have an HTTP connector setup in the Panther UI. In this example I used a bearer token but this can be overriden by using custom headers if desired.

Expand All @@ -151,15 +185,15 @@ Initializing Options:
import os
from socketsync.core import Core
from socketsync.connectors.panther import Panther
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
days_ago = os.getenv("DAYS_AGO") or exit(1)
report_id = os.getenv("SOCKET_REPORT_ID")

from_time = days_ago * 24 * 60 * 60 #Convert days to seconds

core = Core(
api_key=api_key,
from_time=from_time,
Expand All @@ -185,15 +219,15 @@ The Elasticsearch connector should work with on prem or cloud hosted Elastic sea
import os
from socketsync.core import Core
from socketsync.connectors.elastic import Elastic
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
days_ago = os.getenv("DAYS_AGO") or exit(1)
report_id = os.getenv("SOCKET_REPORT_ID")

from_time = days_ago * 24 * 60 * 60 #Convert days to seconds

core = Core(
api_key=api_key,
from_time=from_time,
Expand Down Expand Up @@ -228,15 +262,15 @@ Initialize Options:
import os
from socketsync.core import Core
from socketsync.connectors.webhook import Webhook
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
days_ago = os.getenv("DAYS_AGO") or exit(1)
report_id = os.getenv("SOCKET_REPORT_ID")

from_time = days_ago * 24 * 60 * 60 #Convert days to seconds

core = Core(
api_key=api_key,
from_time=from_time,
Expand Down Expand Up @@ -269,15 +303,15 @@ Initialize Options:
import os
from socketsync.core import Core
from socketsync.connectors.slack import Slack
from datetime import datetime, timezone
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())


if __name__ == '__main__':
socket_org = os.getenv("SOCKET_ORG") or exit(1)
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
days_ago = os.getenv("DAYS_AGO") or exit(1)
report_id = os.getenv("SOCKET_REPORT_ID")

from_time = days_ago * 24 * 60 * 60 #Convert days to seconds

core = Core(
api_key=api_key,
from_time=from_time,
Expand Down
17 changes: 11 additions & 6 deletions socket-integration-example.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import logging
import os
from socketsync.core import Core
from socketsync.connectors.elastic import Elastic
Expand All @@ -8,12 +7,11 @@
from socketsync.connectors.csv import CSV
from socketsync.connectors.webhook import Webhook
from socketsync.connectors.slack import Slack
from socketsync.connectors.sumologic import Sumologic

from datetime import datetime, timezone
start_date = "2024-09-10 10:00"
start_time = datetime.strptime(start_date, "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
end_time = datetime.now(timezone.utc)
from_time = int((end_time - start_time).total_seconds())
start_time = datetime.strptime("2024-09-10 10:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc)
from_time = int((datetime.now(timezone.utc) - start_time).total_seconds())

if __name__ == '__main__':
api_key = os.getenv("SOCKET_API_KEY") or exit(1)
Expand All @@ -25,7 +23,8 @@
core = Core(
api_key=api_key,
from_time=from_time,
request_timeout=300
request_timeout=300,
report_id="a96abb17-5750-4452-9e7e-33673070f0f2"
)
# logging.basicConfig(level=logging.DEBUG)
# core.set_log_level(logging.DEBUG)
Expand All @@ -38,6 +37,12 @@
)
csv.write_csv(issue_data)

# Sumologic Example
sumo_logic_http_source_url = os.getenv("SUMO_LOGIC_HTTP_SOURCE_URL", None)
sumo = Sumologic(sumo_logic_http_source_url)
sumo_status = sumo.send_events(issue_data, "socket-siem-connector")
print(f"Sumologic Result: {sumo_status}")

# Elasticsearch Example
elastic_token = os.getenv('ELASTIC_TOKEN') or exit(1)
elastic_cloud_id = os.getenv('ELASTIC_CLOUD_ID') or exit(1)
Expand Down
2 changes: 1 addition & 1 deletion socketsync/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


__author__ = "socket.dev"
__version__ = "1.0.21"
__version__ = "1.0.22"
__all__ = ["log", "__version__", "columns", "default_headers"]

log = logging.getLogger("socketdev")
Expand Down
61 changes: 61 additions & 0 deletions socketsync/connectors/sumologic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import requests
import io
import json
from socketsync.classes import IssueRecord


class Sumologic:
def __init__(self, http_source_url: str):
"""
Initializes the Sumo Logic client with credentials and HTTP source URL.
:param http_source_url: The Sumo Logic HTTP source URL
"""
self.http_source_url = http_source_url

def send_events(self, events: list, plugin_name: str) -> None:
"""
Will iterate through events and send to SIEM
:param events: A list containing the events to send:
:param plugin_name: A string of the plugin name to use for the file name
:return:
"""

for event in events:
event_file = io.StringIO()
event: IssueRecord
event_json = json.dumps(event.__dict__)
event_file.write(event_json + "\n")

# Reset the cursor of the file-like object to the start
event_file.seek(0)
file_name = f"{plugin_name}.json"
files = {
file_name: (file_name, event_file)
}
self.send_event(files)

def send_event(self, event_data: dict) -> dict:
"""
Sends an event to the Sumo Logic HTTP source.
:param event_data: A dictionary containing the event data
:return: A dictionary with the response status and content
"""

try:
response = requests.post(
self.http_source_url,
files=event_data
)
if response.status_code == 200:
return {"status": "success", "message": "Event sent successfully."}
else:
return {
"status": "error",
"message": f"Failed to send event. Status code: {response.status_code}",
"response": response.text
}
except requests.exceptions.RequestException as e:
return {"status": "error", "message": f"An error occurred: {str(e)}"}

2 changes: 1 addition & 1 deletion socketsync/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def get_reports(self) -> list:
next_page = None
while not done:
results = socket.fullscans.get(org_slug, {"from": int(report_from_time), "page": next_page})
if next_page == 1:
if next_page == 0:
done = True
next_page = results.get("nextPage")
if results.get("success") is False:
Expand Down

0 comments on commit 0ac14f8

Please sign in to comment.