-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'karen/main' into karenyousefi-main
- Loading branch information
Showing
6 changed files
with
364 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import json | ||
import sys | ||
import base64 | ||
import io | ||
import zipfile | ||
import requests | ||
import hashlib | ||
import re | ||
|
||
misperrors = {'error': 'Error'} | ||
mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['link']} | ||
moduleinfo = { | ||
'version': '1', | ||
'author': 'Karen Yousefi', | ||
'description': 'Module to push malware samples to MalShare', | ||
'module-type': ['expansion'], | ||
'name': 'MalShare Upload', | ||
'requirements': ['requests library'], | ||
} | ||
|
||
moduleconfig = ['malshare_apikey'] | ||
|
||
def handler(q=False): | ||
if q is False: | ||
return False | ||
request = json.loads(q) | ||
|
||
try: | ||
data = request.get("data") | ||
if 'malware-sample' in request: | ||
sample_filename = request.get("malware-sample").split("|", 1)[0] | ||
data = base64.b64decode(data) | ||
fl = io.BytesIO(data) | ||
zf = zipfile.ZipFile(fl) | ||
sample_hashname = zf.namelist()[0] | ||
data = zf.read(sample_hashname, b"infected") | ||
zf.close() | ||
elif 'attachment' in request: | ||
sample_filename = request.get("attachment") | ||
data = base64.b64decode(data) | ||
else: | ||
misperrors['error'] = "No malware sample or attachment supplied" | ||
return misperrors | ||
except Exception: | ||
misperrors['error'] = "Unable to process submitted sample data" | ||
return misperrors | ||
|
||
if request["config"].get("malshare_apikey") is None: | ||
misperrors["error"] = "Missing MalShare API key" | ||
return misperrors | ||
|
||
malshare_apikey = request["config"].get("malshare_apikey") | ||
|
||
try: | ||
url = "https://malshare.com/api.php" | ||
params = { | ||
'api_key': malshare_apikey, | ||
'action': 'upload' | ||
} | ||
files = {"upload": (sample_filename, data)} | ||
response = requests.post(url, params=params, files=files) | ||
response.raise_for_status() | ||
|
||
response_text = response.text.strip() | ||
|
||
# Calculate SHA256 of the file | ||
sha256 = hashlib.sha256(data).hexdigest() | ||
|
||
if response_text.startswith("Success"): | ||
# If upload was successful or file already exists | ||
malshare_link = f"https://malshare.com/sample.php?action=detail&hash={sha256}" | ||
elif "sample already exists" in response_text: | ||
# If file already exists, extract SHA256 from response | ||
match = re.search(r'([a-fA-F0-9]{64})', response_text) | ||
if match: | ||
sha256 = match.group(1) | ||
malshare_link = f"https://malshare.com/sample.php?action=detail&hash={sha256}" | ||
else: | ||
# If there's any other error | ||
raise Exception(f"Upload failed: {response_text}") | ||
|
||
except Exception as e: | ||
misperrors['error'] = f"Unable to send sample to MalShare: {str(e)}" | ||
return misperrors | ||
|
||
r = {'results': [{'types': 'link', 'values': malshare_link, 'comment': 'Link to MalShare analysis'}]} | ||
return r | ||
|
||
def introspection(): | ||
return mispattributes | ||
|
||
def version(): | ||
moduleinfo['config'] = moduleconfig | ||
return moduleinfo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import json | ||
import requests | ||
import base64 | ||
import io | ||
import zipfile | ||
|
||
misperrors = {'error': 'Error'} | ||
mispattributes = {'input': ['attachment', 'malware-sample', 'url'], 'output': ['link']} | ||
moduleinfo = { | ||
'version': '1', | ||
'author': 'Karen Yousefi', | ||
'description': 'Module to submit samples to tria.ge', | ||
'module-type': ['expansion', 'hover'], | ||
'name': 'Triage Submit', | ||
} | ||
|
||
moduleconfig = ['apikey', 'url_mode'] | ||
|
||
def handler(q=False): | ||
if q is False: | ||
return False | ||
|
||
request = json.loads(q) | ||
|
||
if request.get('config', {}).get('apikey') is None: | ||
misperrors['error'] = 'tria.ge API key is missing' | ||
return misperrors | ||
|
||
api_key = request['config']['apikey'] | ||
url_mode = request['config'].get('url_mode', 'submit') # 'submit' or 'fetch' | ||
base_url = 'https://tria.ge/api/v0/samples' | ||
headers = { | ||
'Authorization': f'Bearer {api_key}' | ||
} | ||
|
||
if 'attachment' in request: | ||
data = request['data'] | ||
filename = request['attachment'] | ||
return submit_file(headers, base_url, data, filename) | ||
elif 'malware-sample' in request: | ||
data = request['data'] | ||
filename = request['malware-sample'].split('|')[0] | ||
return submit_file(headers, base_url, data, filename, is_malware_sample=True) | ||
elif 'url' in request: | ||
url = request['url'] | ||
return submit_url(headers, base_url, url, url_mode) | ||
else: | ||
misperrors['error'] = 'Unsupported input type' | ||
return misperrors | ||
|
||
def submit_file(headers, base_url, data, filename, is_malware_sample=False): | ||
try: | ||
if is_malware_sample: | ||
file_data = base64.b64decode(data) | ||
zip_file = zipfile.ZipFile(io.BytesIO(file_data)) | ||
file_data = zip_file.read(zip_file.namelist()[0], pwd=b'infected') | ||
else: | ||
file_data = base64.b64decode(data) | ||
|
||
files = {'file': (filename, file_data)} | ||
response = requests.post(base_url, headers=headers, files=files) | ||
response.raise_for_status() | ||
result = response.json() | ||
|
||
sample_id = result['id'] | ||
sample_url = f'https://tria.ge/{sample_id}' | ||
|
||
return {'results': [{'types': 'link', 'values': sample_url, 'comment': 'Link to tria.ge analysis'}]} | ||
|
||
except Exception as e: | ||
misperrors['error'] = f'Error submitting to tria.ge: {str(e)}' | ||
return misperrors | ||
|
||
def submit_url(headers, base_url, url, mode): | ||
try: | ||
if mode == 'fetch': | ||
data = {'kind': 'fetch', 'url': url} | ||
else: # submit | ||
data = {'kind': 'url', 'url': url} | ||
|
||
response = requests.post(base_url, headers=headers, json=data) | ||
response.raise_for_status() | ||
result = response.json() | ||
|
||
sample_id = result['id'] | ||
sample_url = f'https://tria.ge/{sample_id}' | ||
|
||
return {'results': [{'types': 'link', 'values': sample_url, 'comment': f'Link to tria.ge analysis ({mode} mode)'}]} | ||
|
||
except Exception as e: | ||
misperrors['error'] = f'Error submitting to tria.ge: {str(e)}' | ||
return misperrors | ||
|
||
def introspection(): | ||
return mispattributes | ||
|
||
def version(): | ||
moduleinfo['config'] = moduleconfig | ||
return moduleinfo |
Oops, something went wrong.