From 4a187f3a980c3f61991f65b2d31bf99fee649168 Mon Sep 17 00:00:00 2001 From: Martin Jaan Leesment Date: Wed, 8 Feb 2023 12:14:31 +0200 Subject: [PATCH] Search users in Okta. --- analyzers/OktaUserLookup/OktaUserLookup.json | 31 +++++++++ .../OktaUserLookup/oktauserlookup_analyzer.py | 63 +++++++++++++++++++ analyzers/OktaUserLookup/requirements.txt | 3 + .../OktaUserLookup_1_0/long.html | 26 ++++++++ .../OktaUserLookup_1_0/short.html | 6 ++ 5 files changed, 129 insertions(+) create mode 100644 analyzers/OktaUserLookup/OktaUserLookup.json create mode 100644 analyzers/OktaUserLookup/oktauserlookup_analyzer.py create mode 100644 analyzers/OktaUserLookup/requirements.txt create mode 100644 thehive-templates/OktaUserLookup_1_0/long.html create mode 100644 thehive-templates/OktaUserLookup_1_0/short.html diff --git a/analyzers/OktaUserLookup/OktaUserLookup.json b/analyzers/OktaUserLookup/OktaUserLookup.json new file mode 100644 index 000000000..d9b37d5ef --- /dev/null +++ b/analyzers/OktaUserLookup/OktaUserLookup.json @@ -0,0 +1,31 @@ +{ + "name": "OktaUserLookup", + "author": "Martin Jaan Leesment", + "license": "AGPL-V3", + "url": "https://github.com/TheHive-Project/Cortex-Analyzers", + "version": "1.0", + "description": "Okta User Lookup is an analyzer for TheHive to enrich mail observables from data through the Okta users API", + "dataTypeList": ["mail"], + "baseConfig": "OktaUserLookup", + "configurationItems": [ + { + "name": "OktaOrgUrl", + "description": "Must contain your okta organisation URL. Eg: https://.okta.com", + "type": "string", + "multi": false, + "required": true + }, + { + "name": "OktaToken", + "description": "Must contain the Okta access token.", + "type": "string", + "multi": false, + "required": true + } + ], + "command": "OktaUserLookup/oktauserlookup_analyzer.py", + "registration_required": true, + "subscription_required": false, + "free_subscription": false, + "service_homepage": "https://developer.okta.com/docs/reference/api/users/" +} diff --git a/analyzers/OktaUserLookup/oktauserlookup_analyzer.py b/analyzers/OktaUserLookup/oktauserlookup_analyzer.py new file mode 100644 index 000000000..fe159319c --- /dev/null +++ b/analyzers/OktaUserLookup/oktauserlookup_analyzer.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# encoding: utf-8 + +import asyncio +from cortexutils.analyzer import Analyzer +from okta.client import Client as OktaClient + +class OktaUserlookupAnalyzer(Analyzer): + def __init__(self): + Analyzer.__init__(self) + self.url = self.get_param('config.OktaOrgUrl', None, 'Missing Okta Organisation URL') + self.okta_token = self.get_param('config.OktaToken', None, 'Missing Okta Token') + + def summary(self, raw): + taxonomies = [] + level = "info" + namespace = "Okta" + predicate = "Query" + + for key, value in raw["results"].items(): + if key in ["Country Code", "Supervisory Org", "Company"]: + taxonomies.append(self.build_taxonomy(level, namespace, predicate, value)) + return {"taxonomies": taxonomies} + + def run(self): + if self.data_type == 'mail': + try: + data = self.get_param("data", None, "Data is missing") + query_parameters = {'q':f'{data}'} + okta_client = OktaClient({'orgUrl':self.url, 'token':self.okta_token}) + async_couroutine = okta_client.list_users(query_parameters) + + response = asyncio.run(async_couroutine) + + userData = dict() + if response[0]: + udt = response[0][0] + userData['Activated'] = udt.activated + userData['City'] = udt.profile.city + userData['Country Code'] = udt.profile.countryCode + userData['Department'] = udt.profile.department + userData['First Name'] = udt.profile.firstName + userData['Last Name'] = udt.profile.lastName + userData['Organization'] = udt.profile.organization + userData['Street Address'] = udt.profile.streetAddress + userData['Title'] = udt.profile.title + if 'workerStatus' in udt.profile.as_dict().keys(): + userData['Worker Status'] = udt.profile.workerStatus + userData['Identity Type'] = udt.profile.identityType + userData['Company'] = udt.profile.company + if 'on_long_leave' in udt.profile.as_dict().keys(): + userData['On Long Leave'] = udt.profile.on_long_leave + if 'supervisoryOrg' in udt.profile.as_dict().keys(): + userData['Supervisory Org'] = udt.profile.supervisoryOrg + userData['Status'] = udt.status.value + userData['Transitioning to Status'] = udt.transitioning_to_status + + self.report({"results": userData}) + except Exception as e: + self.error(str(e)) + +if __name__ == '__main__': + OktaUserlookupAnalyzer().run() diff --git a/analyzers/OktaUserLookup/requirements.txt b/analyzers/OktaUserLookup/requirements.txt new file mode 100644 index 000000000..fdaf0b263 --- /dev/null +++ b/analyzers/OktaUserLookup/requirements.txt @@ -0,0 +1,3 @@ +asyncio +cortexutils +okta diff --git a/thehive-templates/OktaUserLookup_1_0/long.html b/thehive-templates/OktaUserLookup_1_0/long.html new file mode 100644 index 000000000..aa37f1ad1 --- /dev/null +++ b/thehive-templates/OktaUserLookup_1_0/long.html @@ -0,0 +1,26 @@ +
+ + +
+
+ Okta User Lookup Results +
+
+
+ No records found +
+
+
+
{{key}}:
+
{{value}}
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/thehive-templates/OktaUserLookup_1_0/short.html b/thehive-templates/OktaUserLookup_1_0/short.html new file mode 100644 index 000000000..acc0c81a6 --- /dev/null +++ b/thehive-templates/OktaUserLookup_1_0/short.html @@ -0,0 +1,6 @@ + + {{t.namespace}}:{{t.predicate}}={{t.value}} +