diff --git a/AirlockTools.py b/AirlockTools.py index de6960b..2458e07 100644 --- a/AirlockTools.py +++ b/AirlockTools.py @@ -2,7 +2,9 @@ import dotenv import os import utils.getdeviceevents import utils.allowlist +import utils.hashfunctions import urllib3 +import pandas as pd urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @@ -26,9 +28,13 @@ def menu(): while True: choice = input("Enter Menu Item: ") if choice == '1': - utils.getdeviceevents.devicehistory(url) + utils.getdeviceevents.devicehistory(url,False) if choice == '2': - utils.allowlist.allowlistexechistories(url) + utils.allowlist.allowlistexechistories(url,False) + if choice == '3': + executionhist = utils.allowlist.allowlistexechistories(url,True) + aggregated = utils.hashfunctions.aggregateHashes(executionhist) + print(aggregated) if __name__ == "__main__": apivalidation() \ No newline at end of file diff --git a/utils/__pycache__/allowlist.cpython-313.pyc b/utils/__pycache__/allowlist.cpython-313.pyc index f029c4b..83afc71 100644 Binary files a/utils/__pycache__/allowlist.cpython-313.pyc and b/utils/__pycache__/allowlist.cpython-313.pyc differ diff --git a/utils/__pycache__/getdeviceevents.cpython-313.pyc b/utils/__pycache__/getdeviceevents.cpython-313.pyc index a7fc471..6613a36 100644 Binary files a/utils/__pycache__/getdeviceevents.cpython-313.pyc and b/utils/__pycache__/getdeviceevents.cpython-313.pyc differ diff --git a/utils/__pycache__/hashfunctions.cpython-313.pyc b/utils/__pycache__/hashfunctions.cpython-313.pyc new file mode 100644 index 0000000..dd4bdff Binary files /dev/null and b/utils/__pycache__/hashfunctions.cpython-313.pyc differ diff --git a/utils/allowlist.py b/utils/allowlist.py index c8bbbdb..2279917 100644 --- a/utils/allowlist.py +++ b/utils/allowlist.py @@ -3,7 +3,7 @@ import requests import json import os -def allowlistexechistories(url): +def allowlistexechistories(url, outputjson: bool): endpoint = url + '/v1/group' print("[+] Grabbing All Policies") payload = {} @@ -23,11 +23,14 @@ def allowlistexechistories(url): endpoint = url + '/v1/logging/exechistories' payload_dict = { "type":[1,2,6,7], + "checkpoint":"000000000000000000000" "policy": [policiesnames[choice]] } payload = json.dumps(payload_dict) print(payload) response = requests.request("POST", endpoint, headers=headers, data=payload, verify=False) + if outputjson == True: + return response parse_text = json.loads(response.text) for item in parse_text['response']['exechistories']: print(item['checkpoint']) \ No newline at end of file diff --git a/utils/getdeviceevents.py b/utils/getdeviceevents.py index d9261ae..fb86053 100644 --- a/utils/getdeviceevents.py +++ b/utils/getdeviceevents.py @@ -3,7 +3,7 @@ import requests import json import os -def devicehistory(url): +def devicehistory(url, outputjson: bool): endpoint = url + '/v1/getexechistory' print("\n") print("1. Today") @@ -43,7 +43,12 @@ def devicehistory(url): } response = requests.request("POST", endpoint, headers=headers, data=payload, verify=False) + + if outputjson == True: + return response + parse_text = json.loads(response.text) + for block in parse_text['response']['exechistory']: print(f"Command: {block['commandline']}") print(f"Date: {block['datetime']}") diff --git a/utils/hashfunctions.py b/utils/hashfunctions.py index ff57f43..550cb22 100644 --- a/utils/hashfunctions.py +++ b/utils/hashfunctions.py @@ -1,22 +1,45 @@ import pandas as pd import requests import os +import json -def aggregateHashes(executions_json: dict) -> pd.DataFrame: + +def aggregateHashes(executions_json) -> pd.DataFrame: """ Takes the executions, aggregates all the data with sha256 as primary, then returns aggregated dataframe """ + """ + old version + data = executions_json.json() - exechistories = executions_json.get("response", {}).get("exechistories", []) - df = pd.DataFrame(exechistories) - + df = pd.DataFrame(data["response"]["exechistories"]) + print(df) if df.empty: return df - # Aggregate by sha256 - keep all entries in lists + #Aggregate by sha256 - keep all entries in lists agg_df = df.groupby("sha256").agg(lambda x: list(x)).reset_index() return agg_df + """ + + + data = executions_json.json() + df = pd.DataFrame(data["response"]["exechistories"]) + + if df.empty: + return df + + # Aggregate by sha256, deduplicate lists, and preserve order + agg_df = df.groupby("sha256").agg(lambda x: list(dict.fromkeys(x))).reset_index() + + # Add a column for the number of unique hostnames + agg_df["num_devices"] = agg_df["hostname"].apply(len) + + # Sort by num_devices in descending order + agg_df = agg_df.sort_values("num_devices", ascending=False) + + return agg_df def augmentAggregatedHashes(url, agg_df: pd.DataFrame) -> pd.DataFrame: """ @@ -66,7 +89,7 @@ def categorize_hashes(aug_df: pd.DataFrame, threat_tolerance: int, untrusted_pub untrusted_publishers = [] # Flatten threatlevel from nested reputation dict - df = df.copy() + df = aug_df.copy() df["threatlevel"] = df["reputation"].apply(lambda x: x.get("threatlevel") if pd.notnull(x) else None) # Masks for each category