Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Malshare, Triage, and VirusTotal #682

Merged
merged 8 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ For further Information see the [license file](https://misp.github.io/misp-modul
* [Lastline Submit](https://misp.github.io/misp-modules/expansion/#lastline-submit) - Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to submit a file or URL to Lastline.
* [Macaddress.io Lookup](https://misp.github.io/misp-modules/expansion/#macaddress.io-lookup) - MISP hover module for macaddress.io
* [Macvendors Lookup](https://misp.github.io/misp-modules/expansion/#macvendors-lookup) - Module to access Macvendors API.
* [Malshare Upload](https://misp.github.io/misp-modules/expansion/#malshare-upload) - Module to push malware samples to malshare.com .
* [Malware Bazaar Lookup](https://misp.github.io/misp-modules/expansion/#malware-bazaar-lookup) - Query Malware Bazaar to get additional information about the input hash.
* [McAfee MVISION Insights Lookup](https://misp.github.io/misp-modules/expansion/#mcafee-mvision-insights-lookup) - Lookup McAfee MVISION Insights Details
* [GeoIP Enrichment](https://misp.github.io/misp-modules/expansion/#geoip-enrichment) - A hover and expansion module to enrich an ip with geolocation and ASN information from an mmdb server instance, such as CIRCL's ip.circl.lu.
Expand Down Expand Up @@ -124,12 +125,14 @@ For further Information see the [license file](https://misp.github.io/misp-modul
* [ThreatCrowd Lookup](https://misp.github.io/misp-modules/expansion/#threatcrowd-lookup) - Module to get information from ThreatCrowd.
* [ThreadFox Lookup](https://misp.github.io/misp-modules/expansion/#threadfox-lookup) - Module to search for an IOC on ThreatFox by abuse.ch.
* [ThreatMiner Lookup](https://misp.github.io/misp-modules/expansion/#threatminer-lookup) - Module to get information from ThreatMiner.
* [Triage Submit](https://misp.github.io/misp-modules/expansion/#triage-submit) - Module to submit samples to tria.ge .
* [TruSTAR Enrich](https://misp.github.io/misp-modules/expansion/#trustar-enrich) - Module to get enrich indicators with TruSTAR.
* [URLhaus Lookup](https://misp.github.io/misp-modules/expansion/#urlhaus-lookup) - Query of the URLhaus API to get additional information about the input attribute.
* [URLScan Lookup](https://misp.github.io/misp-modules/expansion/#urlscan-lookup) - An expansion module to query urlscan.io.
* [VARIoT db Lookup](https://misp.github.io/misp-modules/expansion/#variot-db-lookup) - An expansion module to query the VARIoT db API for more information about a vulnerability.
* [VirusTotal v3 Lookup](https://misp.github.io/misp-modules/expansion/#virustotal-v3-lookup) - Enrich observables with the VirusTotal v3 API
* [VirusTotal Public API Lookup](https://misp.github.io/misp-modules/expansion/#virustotal-public-api-lookup) - Enrich observables with the VirusTotal v3 public API
* [VirusTotal Upload](https://misp.github.io/misp-modules/expansion/#virustotal-upload) - Module to push malware samples to VirusTotal v3 public API
* [VMRay Submit](https://misp.github.io/misp-modules/expansion/#vmray-submit) - Module to submit a sample to VMRay.
* [VMware NSX Defender Enrich](https://misp.github.io/misp-modules/expansion/#vmware-nsx-defender-enrich) - Module to enrich a file or URL with VMware NSX Defender.
* [VulnDB Lookup](https://misp.github.io/misp-modules/expansion/#vulndb-lookup) - Module to query VulnDB (RiskBasedSecurity.com).
Expand Down Expand Up @@ -183,5 +186,3 @@ For further Information see the [license file](https://misp.github.io/misp-modul
* [Mattermost](https://misp.github.io/misp-modules/action_mod/#mattermost) - Simplistic module to send message to a Mattermost channel.
* [Slack](https://misp.github.io/misp-modules/action_mod/#slack) - Simplistic module to send messages to a Slack channel.
* [Test action](https://misp.github.io/misp-modules/action_mod/#test-action) - This module is merely a test, always returning true. Triggers on event publishing.


88 changes: 88 additions & 0 deletions documentation/mkdocs/expansion.md
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,29 @@ Module to access Macvendors API.

-----

#### [Malshare Upload](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malshare_upload.py)

Module to push malware samples to MalShare.com
[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malshare_upload.py)]

- **features**:
>The module requires a MalShare API key to upload files, and returns the link of the MalShare analysis.

- **config**:
>api_key

- **input**:
>Attachment or malware sample

- **output**:
>Link attribute that points to the sample at the MalShare analysis instance.

- **references**:
> - https://malshare.com/
> - https://malshare.com/doc.php

-----

#### [Malware Bazaar Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malwarebazaar.py)

Query Malware Bazaar to get additional information about the input hash.
Expand Down Expand Up @@ -2454,6 +2477,42 @@ Module to get information from ThreatMiner.
- **references**:
>https://www.threatminer.org/



-----

#### [Triage Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/triage_submit.py)

Module to submit samples to tria.ge
[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/triage_submit.py)]

- **features**:
> Upload files, and returns the link of the uploaded analysis.
>
>The module can submit URLs to retrieve and analyze them directly in the browser or fetch and execute files in the sandbox.


- **config**:
>apikey
>
>url_mode ( 'submit' or 'fetch' )

- **input**:
>A MISP attribute included in the following list:
>- Attachment
>- malware-sample
>- url

- **output**:
>Link attribute that points to the sample at the Triage analysis instance.

- **references**:
> - https://tria.ge/
> - https://tria.ge/docs/cloud-api/submit/

- **requirements**:
>An access to the Triage API (apikey)

-----

#### [TruSTAR Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/trustar_enrich.py)
Expand Down Expand Up @@ -2653,6 +2712,35 @@ Enrich observables with the VirusTotal v3 public API
- **requirements**:
>An access to the VirusTotal API (apikey)


-----

#### [VirusTotal Upload](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_upload.py)

<img src=../logos/virustotal.png height=60>

Module to push malware samples to VirusTotal v3 public API
[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_upload.py)]

- **features**:
>The module requires a VirusTotal API key to Upload files, and returns the link of the uploaded analysis.

- **config**:
> - apikey

- **input**:
>Attachment or malware sample

- **output**:
>Link attribute that points to the sample at the VirusTotal analysis instance.

- **references**:
> - https://www.virustotal.com
> - https://docs.virustotal.com/reference/overview

- **requirements**:
>An access to the VirusTotal API (apikey)

-----

#### [VMRay Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py)
Expand Down
2 changes: 1 addition & 1 deletion misp_modules/modules/expansion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
'extract_url_components', 'ipinfo', 'whoisfreaks', 'ip2locationio', 'stairwell',
'google_threat_intelligence', 'vulnerability_lookup', 'vysion', 'mcafee_insights_enrich',
'threatfox', 'yeti', 'abuseipdb', 'vmware_nsx', 'sigmf_expand', 'google_safe_browsing',
'google_search']
'google_search', 'whois', 'triage_submit', 'virustotal_upload', 'malshare_upload' ]


minimum_required_fields = ('type', 'uuid', 'value')
Expand Down
94 changes: 94 additions & 0 deletions misp_modules/modules/expansion/malshare_upload.py
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
99 changes: 99 additions & 0 deletions misp_modules/modules/expansion/triage_submit.py
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
Loading