From 77af074ebea99d0da1a18e66cf4123a40be37041 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Sun, 26 Jan 2020 03:49:50 +0000 Subject: [PATCH 1/5] Add CyberChef analyzer --- analyzers/CyberChef/CyberChefFromBase64.json | 24 +++++++++ .../CyberChef/CyberChefFromCharCode.json | 24 +++++++++ analyzers/CyberChef/CyberChefFromHex.json | 24 +++++++++ analyzers/CyberChef/cyberchef.py | 54 +++++++++++++++++++ analyzers/CyberChef/long.html | 16 ++++++ analyzers/CyberChef/requirements.txt | 1 + analyzers/CyberChef/short.html | 3 ++ 7 files changed, 146 insertions(+) create mode 100644 analyzers/CyberChef/CyberChefFromBase64.json create mode 100644 analyzers/CyberChef/CyberChefFromCharCode.json create mode 100644 analyzers/CyberChef/CyberChefFromHex.json create mode 100755 analyzers/CyberChef/cyberchef.py create mode 100644 analyzers/CyberChef/long.html create mode 100644 analyzers/CyberChef/requirements.txt create mode 100644 analyzers/CyberChef/short.html diff --git a/analyzers/CyberChef/CyberChefFromBase64.json b/analyzers/CyberChef/CyberChefFromBase64.json new file mode 100644 index 000000000..794963796 --- /dev/null +++ b/analyzers/CyberChef/CyberChefFromBase64.json @@ -0,0 +1,24 @@ +{ + "name": "CyberChef_FromBase64", + "version": "1.0", + "author": "Wes Lambert", + "url": "https://github.com/TheHive-Project/Cortex-Analyzers", + "license": "AGPL-V3", + "description": "Convert Base64 with CyberChef Server", + "dataTypeList": ["other"], + "baseConfig": "CyberChef", + "config": { + "service": "FromBase64" + }, + "command": "CyberChef/cyberchef.py", + "configurationItems": [ + { + "name": "url", + "description": "CyberChef Server URL", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "http://192.168.1.178:3000/" + } + ] +} diff --git a/analyzers/CyberChef/CyberChefFromCharCode.json b/analyzers/CyberChef/CyberChefFromCharCode.json new file mode 100644 index 000000000..cf77d7f67 --- /dev/null +++ b/analyzers/CyberChef/CyberChefFromCharCode.json @@ -0,0 +1,24 @@ +{ + "name": "CyberChef_FromCharCode", + "version": "1.0", + "author": "Wes Lambert", + "url": "https://github.com/TheHive-Project/Cortex-Analyzers", + "license": "AGPL-V3", + "description": "Convert Char Code with CyberChef Server", + "dataTypeList": ["other"], + "baseConfig": "CyberChef", + "config": { + "service": "FromCharCode" + }, + "command": "CyberChef/cyberchef.py", + "configurationItems": [ + { + "name": "url", + "description": "CyberChef Server URL", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "http://192.168.1.178:3000/" + } + ] +} diff --git a/analyzers/CyberChef/CyberChefFromHex.json b/analyzers/CyberChef/CyberChefFromHex.json new file mode 100644 index 000000000..ab97d10cb --- /dev/null +++ b/analyzers/CyberChef/CyberChefFromHex.json @@ -0,0 +1,24 @@ +{ + "name": "CyberChef_FromHex", + "version": "1.0", + "author": "Wes Lambert", + "url": "https://github.com/TheHive-Project/Cortex-Analyzers", + "license": "AGPL-V3", + "description": "Convert Hex with CyberChef Server", + "dataTypeList": ["other"], + "baseConfig": "CyberChef", + "config": { + "service": "FromHex" + }, + "command": "CyberChef/cyberchef.py", + "configurationItems": [ + { + "name": "url", + "description": "CyberChef Server URL", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "http://192.168.1.178:3000/" + } + ] +} diff --git a/analyzers/CyberChef/cyberchef.py b/analyzers/CyberChef/cyberchef.py new file mode 100755 index 000000000..a61d66d20 --- /dev/null +++ b/analyzers/CyberChef/cyberchef.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# encoding: utf-8 + +import json +import requests +from cortexutils.analyzer import Analyzer + +class CyberchefAnalyzer(Analyzer): + def __init__(self): + Analyzer.__init__(self) + self.observable = self.get_param('data', None, 'Data missing!') + self.service = self.get_param('config.service', None, 'Service is missing') + self.url = self.get_param('config.url', None, 'URL is missing') + + def summary(self, raw): + taxonomies = [] + level = 'info' + namespace = 'CyberChef' + + # Set predicate for input + predicate = 'input_data' + taxonomies.append(self.build_taxonomy(level, namespace, predicate, raw['input_data'])) + + # Set predicate for output_data + predicate = 'output_data' + taxonomies.append(self.build_taxonomy(level, namespace, predicate, raw['output_data'])) + + return {"taxonomies": taxonomies} + + def run(self): + try: + observable = str(self.observable) + url = self.url + if self.service == 'FromHex': + data = {"input": observable, "recipe":{"op":"From Hex", "args": ["Auto"]}} + elif self.service == "FromBase64": + data = { "input": observable, "recipe":[{"op":"From Base64","args":["A-Za-z0-9+/=",True]}]} + elif self.service == "FromCharCode": + # Recipe from https://github.com/mattnotmax/cyberchef-recipes#recipe-3---from-charcode + data = { "input": observable, "recipe":[{"op":"Regular expression","args":["User defined","([0-9]{2,3}(,\\s|))+",True,True,False,False,False,False,"List matches"]},{"op":"From Charcode","args":["Comma",10]},{"op":"Regular expression","args":["User defined","([0-9]{2,3}(,\\s|))+",True,True,False,False,False,False,"List matches"]},{"op":"From Charcode","args":["Space",10]}]} + headers = { 'Content-Type': 'application/json' } + r = requests.post(url.strip('/') + '/bake', headers=headers, data=json.dumps(data)) + response_bytes = r.text + clean_bytes = response_bytes.strip('[').strip(']').split(',') + output_data = "" + for i in clean_bytes: + output_data = str(output_data + str(chr(int(i)))) + self.report({ 'input_data': observable, 'output_data': output_data }) + except: + self.error("Could not convert provided data.") + +if __name__ == '__main__': + CyberchefAnalyzer().run() + diff --git a/analyzers/CyberChef/long.html b/analyzers/CyberChef/long.html new file mode 100644 index 000000000..e4be416d8 --- /dev/null +++ b/analyzers/CyberChef/long.html @@ -0,0 +1,16 @@ +
+
+ CyberChef Data Conversion +
+
+ + + + + + + + +
InputOutput
{{content.input_data | ellipsis:40}}{{content.output_data}}
+
+
diff --git a/analyzers/CyberChef/requirements.txt b/analyzers/CyberChef/requirements.txt new file mode 100644 index 000000000..0b72e19b9 --- /dev/null +++ b/analyzers/CyberChef/requirements.txt @@ -0,0 +1 @@ +dnyspython diff --git a/analyzers/CyberChef/short.html b/analyzers/CyberChef/short.html new file mode 100644 index 000000000..5fc0dabfb --- /dev/null +++ b/analyzers/CyberChef/short.html @@ -0,0 +1,3 @@ + + {{t.namespace}}:{{t.predicate}}="{{t.value}}" + From 181794b8dcc3785281d45fa453548d8efc96bb38 Mon Sep 17 00:00:00 2001 From: weslambert Date: Thu, 13 Feb 2020 20:15:12 -0500 Subject: [PATCH 2/5] Add cortexutils --- analyzers/CyberChef/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/analyzers/CyberChef/requirements.txt b/analyzers/CyberChef/requirements.txt index 0b72e19b9..dabc6930f 100644 --- a/analyzers/CyberChef/requirements.txt +++ b/analyzers/CyberChef/requirements.txt @@ -1 +1,2 @@ +cortexutils dnyspython From 752a3cb4b8901a95350466578faf0a89f4b3a14e Mon Sep 17 00:00:00 2001 From: weslambert Date: Thu, 13 Feb 2020 20:17:18 -0500 Subject: [PATCH 3/5] Fix typo --- analyzers/CyberChef/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analyzers/CyberChef/requirements.txt b/analyzers/CyberChef/requirements.txt index dabc6930f..ea4658251 100644 --- a/analyzers/CyberChef/requirements.txt +++ b/analyzers/CyberChef/requirements.txt @@ -1,2 +1,2 @@ cortexutils -dnyspython +dnspython From 427a9a7182738ffb94bba8f555540ddc6fc8673a Mon Sep 17 00:00:00 2001 From: weslambert Date: Sat, 21 Mar 2020 19:24:11 -0400 Subject: [PATCH 4/5] Updated script, as results are currently failing --- analyzers/CyberChef/cyberchef.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/analyzers/CyberChef/cyberchef.py b/analyzers/CyberChef/cyberchef.py index a61d66d20..16a1ce867 100755 --- a/analyzers/CyberChef/cyberchef.py +++ b/analyzers/CyberChef/cyberchef.py @@ -40,11 +40,7 @@ def run(self): data = { "input": observable, "recipe":[{"op":"Regular expression","args":["User defined","([0-9]{2,3}(,\\s|))+",True,True,False,False,False,False,"List matches"]},{"op":"From Charcode","args":["Comma",10]},{"op":"Regular expression","args":["User defined","([0-9]{2,3}(,\\s|))+",True,True,False,False,False,False,"List matches"]},{"op":"From Charcode","args":["Space",10]}]} headers = { 'Content-Type': 'application/json' } r = requests.post(url.strip('/') + '/bake', headers=headers, data=json.dumps(data)) - response_bytes = r.text - clean_bytes = response_bytes.strip('[').strip(']').split(',') - output_data = "" - for i in clean_bytes: - output_data = str(output_data + str(chr(int(i)))) + output_data = "".join([chr(x) for x in r.json().get('value', [])]) self.report({ 'input_data': observable, 'output_data': output_data }) except: self.error("Could not convert provided data.") From 0ccadcce42e2a1efb04d45777b22da4e0da67906 Mon Sep 17 00:00:00 2001 From: Arcuri Davide Date: Sun, 22 Mar 2020 12:34:00 +0100 Subject: [PATCH 5/5] check server response before decode --- analyzers/CyberChef/cyberchef.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/analyzers/CyberChef/cyberchef.py b/analyzers/CyberChef/cyberchef.py index 16a1ce867..b3392e9c2 100755 --- a/analyzers/CyberChef/cyberchef.py +++ b/analyzers/CyberChef/cyberchef.py @@ -40,8 +40,11 @@ def run(self): data = { "input": observable, "recipe":[{"op":"Regular expression","args":["User defined","([0-9]{2,3}(,\\s|))+",True,True,False,False,False,False,"List matches"]},{"op":"From Charcode","args":["Comma",10]},{"op":"Regular expression","args":["User defined","([0-9]{2,3}(,\\s|))+",True,True,False,False,False,False,"List matches"]},{"op":"From Charcode","args":["Space",10]}]} headers = { 'Content-Type': 'application/json' } r = requests.post(url.strip('/') + '/bake', headers=headers, data=json.dumps(data)) - output_data = "".join([chr(x) for x in r.json().get('value', [])]) - self.report({ 'input_data': observable, 'output_data': output_data }) + if r.status_code == 200: + output_data = "".join([chr(x) for x in r.json().get('value', [])]) + self.report({ 'input_data': observable, 'output_data': output_data }) + else: + self.error('Server responded with %d: %s' % (r.status_code, r.text)) except: self.error("Could not convert provided data.")