mirror of https://github.com/MISP/PyMISP
Initial commit supporting MISP Objects
parent
14fcc5f586
commit
78488db7aa
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "pymisp/data/misp-objects"]
|
||||||
|
path = pymisp/data/misp-objects
|
||||||
|
url = https://github.com/MISP/misp-objects
|
|
@ -3,5 +3,6 @@ __version__ = '2.4.77'
|
||||||
from .exceptions import PyMISPError, NewEventError, NewAttributeError, MissingDependency, NoURL, NoKey
|
from .exceptions import PyMISPError, NewEventError, NewAttributeError, MissingDependency, NoURL, NoKey
|
||||||
from .api import PyMISP
|
from .api import PyMISP
|
||||||
from .mispevent import MISPEvent, MISPAttribute, EncodeUpdate, EncodeFull
|
from .mispevent import MISPEvent, MISPAttribute, EncodeUpdate, EncodeFull
|
||||||
from .tools.neo4j import Neo4j
|
from .tools import Neo4j
|
||||||
from .tools import stix
|
from .tools import stix
|
||||||
|
from .tools import MISPObjectGenerator
|
||||||
|
|
|
@ -1578,6 +1578,18 @@ class PyMISP(object):
|
||||||
response = session.post(url)
|
response = session.post(url)
|
||||||
return self._check_response(response)
|
return self._check_response(response)
|
||||||
|
|
||||||
|
# ###################
|
||||||
|
# ### Objects ###
|
||||||
|
# ###################
|
||||||
|
|
||||||
|
def add_object(self, event_id, template_id, misp_object):
|
||||||
|
session = self.__prepare_session()
|
||||||
|
url = urljoin(self.root_url, 'objectTemplates/add/{}/{}'.format(event_id, template_id))
|
||||||
|
if not misp_object.get('object'):
|
||||||
|
misp_object = {'object': misp_object}
|
||||||
|
response = session.post(url, data=json.dumps(misp_object))
|
||||||
|
return self._check_response(response)
|
||||||
|
|
||||||
# ###########################
|
# ###########################
|
||||||
# ####### Deprecated ########
|
# ####### Deprecated ########
|
||||||
# ###########################
|
# ###########################
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ca24684e2f49bcfbd886212ff003472716c26de9
|
|
@ -0,0 +1,5 @@
|
||||||
|
from .neo4j import Neo4j
|
||||||
|
from .objectgenerator import MISPObjectGenerator, MISPObjectException, InvalidMISPObject
|
||||||
|
from .fileobject import FileObject
|
||||||
|
from .peobject import PEObject, PESectionObject
|
||||||
|
from .create_misp_object import make_binary_objects
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from pymisp.tools import FileObject, PEObject, MISPObjectException
|
||||||
|
|
||||||
|
try:
|
||||||
|
import lief
|
||||||
|
HAS_LIEF = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_LIEF = False
|
||||||
|
|
||||||
|
|
||||||
|
class FileTypeNotImplemented(MISPObjectException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def make_pe_objects(lief_parsed, misp_file):
|
||||||
|
misp_pe = PEObject(parsed=lief_parsed)
|
||||||
|
misp_file.add_link(misp_pe.uuid, 'PE indicators')
|
||||||
|
file_object = misp_file.dump()
|
||||||
|
pe_object = misp_pe.dump()
|
||||||
|
pe_sections = []
|
||||||
|
for s in misp_pe.sections:
|
||||||
|
pe_sections.append(s.dump())
|
||||||
|
return file_object, pe_object, pe_sections
|
||||||
|
|
||||||
|
|
||||||
|
def make_binary_objects(filepath):
|
||||||
|
if not HAS_LIEF:
|
||||||
|
raise ImportError('Please install lief, documentation here: https://github.com/lief-project/LIEF')
|
||||||
|
misp_file = FileObject(filepath)
|
||||||
|
try:
|
||||||
|
lief_parsed = lief.parse(filepath)
|
||||||
|
if isinstance(lief_parsed, lief.PE.Binary):
|
||||||
|
make_pe_objects(lief_parsed, misp_file)
|
||||||
|
elif isinstance(lief_parsed, lief.ELF.Binary):
|
||||||
|
raise FileTypeNotImplemented('ELF not implemented yet.')
|
||||||
|
elif isinstance(lief_parsed, lief.MachO.Binary):
|
||||||
|
raise FileTypeNotImplemented('MachO not implemented yet.')
|
||||||
|
except lief.bad_format as e:
|
||||||
|
print('\tBad format: ', e)
|
||||||
|
except lief.bad_file as e:
|
||||||
|
print('\tBad file: ', e)
|
||||||
|
except lief.parser_error as e:
|
||||||
|
print('\tParser error: ', e)
|
||||||
|
except FileTypeNotImplemented as e:
|
||||||
|
print(e)
|
||||||
|
file_object = misp_file.dump()
|
||||||
|
return file_object, None, None
|
|
@ -0,0 +1,92 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from pymisp.tools import MISPObjectGenerator
|
||||||
|
import os
|
||||||
|
from io import BytesIO
|
||||||
|
from hashlib import md5, sha1, sha256, sha512
|
||||||
|
import math
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pydeep
|
||||||
|
HAS_PYDEEP = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_PYDEEP = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
import magic
|
||||||
|
HAS_MAGIC = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_MAGIC = False
|
||||||
|
|
||||||
|
|
||||||
|
class FileObject(MISPObjectGenerator):
|
||||||
|
|
||||||
|
def __init__(self, filepath=None, pseudofile=None, filename=None):
|
||||||
|
if not HAS_PYDEEP:
|
||||||
|
raise ImportError("Please install pydeep: pip install git+https://github.com/kbandla/pydeep.git")
|
||||||
|
if not HAS_MAGIC:
|
||||||
|
raise ImportError("Please install python-magic: pip install python-magic.")
|
||||||
|
if filepath:
|
||||||
|
self.filepath = filepath
|
||||||
|
self.filename = os.path.basename(self.filepath)
|
||||||
|
with open(filepath, 'rb') as f:
|
||||||
|
self.pseudofile = BytesIO(f.read())
|
||||||
|
elif pseudofile and isinstance(pseudofile, BytesIO):
|
||||||
|
# WARNING: lief.parse requires a path
|
||||||
|
self.filepath = None
|
||||||
|
self.pseudofile = pseudofile
|
||||||
|
self.filename = filename
|
||||||
|
else:
|
||||||
|
raise Exception('File buffer (BytesIO) or a path is required.')
|
||||||
|
MISPObjectGenerator.__init__(self, 'file')
|
||||||
|
self.data = self.pseudofile.getvalue()
|
||||||
|
self.generate_attributes()
|
||||||
|
|
||||||
|
def generate_attributes(self):
|
||||||
|
self.size = len(self.data)
|
||||||
|
if self.size > 0:
|
||||||
|
self.entropy = self.__entropy_H(self.data)
|
||||||
|
self.md5 = md5(self.data).hexdigest()
|
||||||
|
self.sha1 = sha1(self.data).hexdigest()
|
||||||
|
self.sha256 = sha256(self.data).hexdigest()
|
||||||
|
self.sha512 = sha512(self.data).hexdigest()
|
||||||
|
self.filetype = magic.from_buffer(self.data)
|
||||||
|
self.ssdeep = pydeep.hash_buf(self.data).decode()
|
||||||
|
|
||||||
|
def __entropy_H(self, data):
|
||||||
|
"""Calculate the entropy of a chunk of data."""
|
||||||
|
# NOTE: copy of the entropy function from pefile
|
||||||
|
|
||||||
|
if len(data) == 0:
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
occurences = Counter(bytearray(data))
|
||||||
|
|
||||||
|
entropy = 0
|
||||||
|
for x in occurences.values():
|
||||||
|
p_x = float(x) / len(data)
|
||||||
|
entropy -= p_x * math.log(p_x, 2)
|
||||||
|
|
||||||
|
return entropy
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
file_object = {}
|
||||||
|
file_object['filename'] = {'value': self.filename}
|
||||||
|
file_object['size-in-bytes'] = {'value': self.size}
|
||||||
|
if self.size > 0:
|
||||||
|
file_object['entropy'] = {'value': self.entropy}
|
||||||
|
file_object['ssdeep'] = {'value': self.ssdeep}
|
||||||
|
file_object['sha512'] = {'value': self.sha512}
|
||||||
|
file_object['md5'] = {'value': self.md5}
|
||||||
|
file_object['sha1'] = {'value': self.sha1}
|
||||||
|
file_object['sha256'] = {'value': self.sha256}
|
||||||
|
file_object['malware-sample'] = {'value': '{}|{}'.format(self.filename, self.md5), 'data': self.pseudofile}
|
||||||
|
# file_object['authentihash'] = self.
|
||||||
|
# file_object['sha-224'] = self.
|
||||||
|
# file_object['sha-384'] = self.
|
||||||
|
# file_object['sha512/224'] = self.
|
||||||
|
# file_object['sha512/256'] = self.
|
||||||
|
# file_object['tlsh'] = self.
|
||||||
|
return self._fill_object(file_object)
|
|
@ -0,0 +1,102 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from pymisp import MISPEvent, MISPAttribute
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import uuid
|
||||||
|
import abc
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class MISPObjectException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidMISPObject(MISPObjectException):
|
||||||
|
"""Exception raised when an object doesn't contains the required field(s)"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MISPObjectGenerator(metaclass=abc.ABCMeta):
|
||||||
|
|
||||||
|
def __init__(self, template_dir):
|
||||||
|
"""This class is used to fill a new MISP object with the default values defined in the object template
|
||||||
|
* template is the path to the template within the misp-object repository
|
||||||
|
* misp_objects_path is the path to the misp-object repository
|
||||||
|
"""
|
||||||
|
self.misp_objects_path = os.path.join(
|
||||||
|
os.path.abspath(os.path.dirname(sys.modules['pymisp'].__file__)),
|
||||||
|
'data', 'misp-objects', 'objects')
|
||||||
|
with open(os.path.join(self.misp_objects_path, template_dir, 'definition.json'), 'r') as f:
|
||||||
|
self.definition = json.load(f)
|
||||||
|
self.misp_event = MISPEvent()
|
||||||
|
self.uuid = str(uuid.uuid4())
|
||||||
|
self.links = []
|
||||||
|
|
||||||
|
def _fill_object(self, values, strict=True):
|
||||||
|
"""Create a new object with the values gathered by the sub-class, use the default values from the template if needed"""
|
||||||
|
if strict:
|
||||||
|
self._validate(values)
|
||||||
|
# Create an empty object based om the object definition
|
||||||
|
new_object = self.__new_empty_object(self.definition)
|
||||||
|
if self.links:
|
||||||
|
# Set the links to other objects
|
||||||
|
new_object["ObjectReference"] = []
|
||||||
|
for link in self.links:
|
||||||
|
uuid, comment = link
|
||||||
|
new_object['ObjectReference'].append({'referenced_object_uuid': uuid, 'comment': comment})
|
||||||
|
for object_type, value in values.items():
|
||||||
|
# Add all the values as MISPAttributes to the current object
|
||||||
|
if value.get('value') is None:
|
||||||
|
continue
|
||||||
|
# Initialize the new MISPAttribute
|
||||||
|
attribute = MISPAttribute(self.misp_event.describe_types)
|
||||||
|
# Get the misp attribute type from the definition
|
||||||
|
value['type'] = self.definition['attributes'][object_type]['misp-attribute']
|
||||||
|
if value.get('disable_correlation') is None:
|
||||||
|
# The correlation can be disabled by default in the object definition.
|
||||||
|
# Use this value if it isn't overloaded by the object
|
||||||
|
value['disable_correlation'] = self.definition['attributes'][object_type].get('disable_correlation')
|
||||||
|
if value.get('to_ids') is None:
|
||||||
|
# Same for the to_ids flag
|
||||||
|
value['to_ids'] = self.definition['attributes'][object_type].get('to_ids')
|
||||||
|
# Set all the values in the MISP attribute
|
||||||
|
attribute.set_all_values(**value)
|
||||||
|
# Finalize the actual MISP Object
|
||||||
|
new_object['ObjectAttribute'].append({'type': object_type, 'Attribute': attribute._json()})
|
||||||
|
return new_object
|
||||||
|
|
||||||
|
def _validate(self, dump):
|
||||||
|
"""Make sure the object we're creating has the required fields"""
|
||||||
|
all_attribute_names = set(dump.keys())
|
||||||
|
if self.definition.get('requiredOneOf'):
|
||||||
|
if not set(self.definition['requiredOneOf']) & all_attribute_names:
|
||||||
|
raise InvalidMISPObject('At least one of the following attributes is required: {}'.format(', '.join(self.definition['requiredOneOf'])))
|
||||||
|
if self.definition.get('required'):
|
||||||
|
for r in self.definition.get('required'):
|
||||||
|
if r not in all_attribute_names:
|
||||||
|
raise InvalidMISPObject('{} is required is required'.format(r))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def add_link(self, uuid, comment=None):
|
||||||
|
"""Add a link (uuid) to an other object"""
|
||||||
|
self.links.append((uuid, comment))
|
||||||
|
|
||||||
|
def __new_empty_object(self, object_definiton):
|
||||||
|
"""Create a new empty object out of the template"""
|
||||||
|
return {'name': object_definiton['name'], 'meta-category': object_definiton['meta-category'],
|
||||||
|
'uuid': self.uuid, 'description': object_definiton['description'],
|
||||||
|
'version': object_definiton['version'], 'ObjectAttribute': []}
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def generate_attributes(self):
|
||||||
|
"""Contains the logic where all the values of the object are gathered"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def dump(self):
|
||||||
|
"""This method normalize the attributes to add to the object.
|
||||||
|
It returns an python dictionary where the key is the type defined in the object,
|
||||||
|
and the value the value of the MISP Attribute"""
|
||||||
|
pass
|
|
@ -0,0 +1,172 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from pymisp.tools import MISPObjectGenerator
|
||||||
|
from io import BytesIO
|
||||||
|
from hashlib import md5, sha1, sha256, sha512
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
import lief
|
||||||
|
HAS_LIEF = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_LIEF = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pydeep
|
||||||
|
HAS_PYDEEP = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_PYDEEP = False
|
||||||
|
|
||||||
|
|
||||||
|
class PEObject(MISPObjectGenerator):
|
||||||
|
|
||||||
|
def __init__(self, parsed=None, filepath=None, pseudofile=None):
|
||||||
|
if not HAS_PYDEEP:
|
||||||
|
raise ImportError("Please install pydeep: pip install git+https://github.com/kbandla/pydeep.git")
|
||||||
|
if not HAS_LIEF:
|
||||||
|
raise ImportError('Please install lief, documentation here: https://github.com/lief-project/LIEF')
|
||||||
|
if pseudofile:
|
||||||
|
if isinstance(pseudofile, BytesIO):
|
||||||
|
self.pe = lief.PE.parse(raw=pseudofile.getvalue())
|
||||||
|
elif isinstance(pseudofile, bytes):
|
||||||
|
self.pe = lief.PE.parse(raw=pseudofile)
|
||||||
|
else:
|
||||||
|
raise Exception('Pseudo file can be BytesIO or bytes got {}'.format(type(pseudofile)))
|
||||||
|
elif filepath:
|
||||||
|
self.pe = lief.PE.parse(filepath)
|
||||||
|
elif parsed:
|
||||||
|
# Got an already parsed blob
|
||||||
|
if isinstance(parsed, lief.PE.Binary):
|
||||||
|
self.pe = parsed
|
||||||
|
else:
|
||||||
|
raise Exception('Not a lief.PE.Binary: {}'.format(type(parsed)))
|
||||||
|
MISPObjectGenerator.__init__(self, 'pe')
|
||||||
|
self.generate_attributes()
|
||||||
|
|
||||||
|
def _is_exe(self):
|
||||||
|
if not self._is_dll() and not self._is_driver():
|
||||||
|
return self.pe.header.has_characteristic(lief.PE.HEADER_CHARACTERISTICS.EXECUTABLE_IMAGE)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _is_dll(self):
|
||||||
|
return self.pe.header.has_characteristic(lief.PE.HEADER_CHARACTERISTICS.DLL)
|
||||||
|
|
||||||
|
def _is_driver(self):
|
||||||
|
# List from pefile
|
||||||
|
system_DLLs = set(('ntoskrnl.exe', 'hal.dll', 'ndis.sys', 'bootvid.dll', 'kdcom.dll'))
|
||||||
|
if system_DLLs.intersection([imp.lower() for imp in self.pe.libraries]):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def generate_attributes(self):
|
||||||
|
if self._is_dll():
|
||||||
|
self.pe_type = 'dll'
|
||||||
|
elif self._is_driver():
|
||||||
|
self.pe_type = 'driver'
|
||||||
|
elif self._is_exe():
|
||||||
|
self.pe_type = 'exe'
|
||||||
|
else:
|
||||||
|
self.pe_type = 'unknown'
|
||||||
|
# General information
|
||||||
|
self.entrypoint_address = self.pe.entrypoint
|
||||||
|
self.compilation_timestamp = datetime.utcfromtimestamp(self.pe.header.time_date_stamps).isoformat()
|
||||||
|
# self.imphash = self.pe.get_imphash()
|
||||||
|
try:
|
||||||
|
if (self.pe.has_resources and
|
||||||
|
self.pe.resources_manager.has_version and
|
||||||
|
self.pe.resources_manager.version.has_string_file_info and
|
||||||
|
self.pe.resources_manager.version.string_file_info.langcode_items):
|
||||||
|
fileinfo = dict(self.pe.resources_manager.version.string_file_info.langcode_items[0].items.items())
|
||||||
|
self.original_filename = fileinfo.get('OriginalFilename')
|
||||||
|
self.internal_filename = fileinfo.get('InternalName')
|
||||||
|
self.file_description = fileinfo.get('FileDescription')
|
||||||
|
self.file_version = fileinfo.get('FileVersion')
|
||||||
|
self.lang_id = self.pe.resources_manager.version.string_file_info.langcode_items[0].key
|
||||||
|
self.product_name = fileinfo.get('ProductName')
|
||||||
|
self.product_version = fileinfo.get('ProductVersion')
|
||||||
|
self.company_name = fileinfo.get('CompanyName')
|
||||||
|
self.legal_copyright = fileinfo.get('LegalCopyright')
|
||||||
|
except lief.read_out_of_bound:
|
||||||
|
# The file is corrupted
|
||||||
|
pass
|
||||||
|
# Sections
|
||||||
|
self.sections = []
|
||||||
|
if self.pe.sections:
|
||||||
|
pos = 0
|
||||||
|
for section in self.pe.sections:
|
||||||
|
s = PESectionObject(section)
|
||||||
|
self.add_link(s.uuid, 'Section {} of PE'.format(pos))
|
||||||
|
if ((self.entrypoint_address >= section.virtual_address) and
|
||||||
|
(self.entrypoint_address < (section.virtual_address + section.virtual_size))):
|
||||||
|
self.entrypoint_section = (section.name, pos) # Tuple: (section_name, position)
|
||||||
|
pos += 1
|
||||||
|
self.sections.append(s)
|
||||||
|
self.nb_sections = len(self.sections)
|
||||||
|
# TODO: TLSSection / DIRECTORY_ENTRY_TLS
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
pe_object = {}
|
||||||
|
pe_object['type'] = {'value': self.pe_type}
|
||||||
|
if hasattr(self, 'imphash'):
|
||||||
|
pe_object['imphash'] = {'value': self.imphash}
|
||||||
|
if hasattr(self, 'original_filename'):
|
||||||
|
pe_object['original-filename'] = {'value': self.original_filename}
|
||||||
|
if hasattr(self, 'internal_filename'):
|
||||||
|
pe_object['internal-filename'] = {'value': self.internal_filename}
|
||||||
|
if hasattr(self, 'compilation_timestamp'):
|
||||||
|
pe_object['compilation-timestamp'] = {'value': self.compilation_timestamp}
|
||||||
|
if hasattr(self, 'entrypoint_section'):
|
||||||
|
pe_object['entrypoint-section|position'] = {'value': '{}|{}'.format(*self.entrypoint_section)}
|
||||||
|
if hasattr(self, 'entrypoint_address'):
|
||||||
|
pe_object['entrypoint-address'] = {'value': self.entrypoint_address}
|
||||||
|
if hasattr(self, 'file_description'):
|
||||||
|
pe_object['file-description'] = {'value': self.file_description}
|
||||||
|
if hasattr(self, 'file_version'):
|
||||||
|
pe_object['file-version'] = {'value': self.file_version}
|
||||||
|
if hasattr(self, 'lang_id'):
|
||||||
|
pe_object['lang-id'] = {'value': self.lang_id}
|
||||||
|
if hasattr(self, 'product_name'):
|
||||||
|
pe_object['product-name'] = {'value': self.product_name}
|
||||||
|
if hasattr(self, 'product_version'):
|
||||||
|
pe_object['product-version'] = {'value': self.product_version}
|
||||||
|
if hasattr(self, 'company_name'):
|
||||||
|
pe_object['company-name'] = {'value': self.company_name}
|
||||||
|
if hasattr(self, 'nb_sections'):
|
||||||
|
pe_object['number-sections'] = {'value': self.nb_sections}
|
||||||
|
return self._fill_object(pe_object)
|
||||||
|
|
||||||
|
|
||||||
|
class PESectionObject(MISPObjectGenerator):
|
||||||
|
|
||||||
|
def __init__(self, section):
|
||||||
|
MISPObjectGenerator.__init__(self, 'pe-section')
|
||||||
|
self.section = section
|
||||||
|
self.data = bytes(self.section.content)
|
||||||
|
self.generate_attributes()
|
||||||
|
|
||||||
|
def generate_attributes(self):
|
||||||
|
self.name = self.section.name
|
||||||
|
self.size = self.section.size
|
||||||
|
if self.size > 0:
|
||||||
|
self.entropy = self.section.entropy
|
||||||
|
self.md5 = md5(self.data).hexdigest()
|
||||||
|
self.sha1 = sha1(self.data).hexdigest()
|
||||||
|
self.sha256 = sha256(self.data).hexdigest()
|
||||||
|
self.sha512 = sha512(self.data).hexdigest()
|
||||||
|
if HAS_PYDEEP:
|
||||||
|
self.ssdeep = pydeep.hash_buf(self.data).decode()
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
section = {}
|
||||||
|
section['name'] = {'value': self.name}
|
||||||
|
section['size-in-bytes'] = {'value': self.size}
|
||||||
|
if self.size > 0:
|
||||||
|
section['entropy'] = {'value': self.entropy}
|
||||||
|
section['md5'] = {'value': self.md5}
|
||||||
|
section['sha1'] = {'value': self.sha1}
|
||||||
|
section['sha256'] = {'value': self.sha256}
|
||||||
|
section['sha512'] = {'value': self.sha512}
|
||||||
|
section['ssdeep'] = {'value': self.ssdeep}
|
||||||
|
return self._fill_object(section)
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from pymisp import PyMISP
|
||||||
|
from pymisp.tools import FileObject, PEObject
|
||||||
|
from pymisp.tools import make_binary_objects
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
import lief
|
||||||
|
HAS_LIEF = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_LIEF = False
|
||||||
|
raise ImportError("Please install lief: https://github.com/lief-project/LIEF")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
pymisp = PyMISP('https://mispbeta.circl.lu', 'et9ZEgn70YJ6URkCr6741LpJNAVUMYD1rM063od3')
|
||||||
|
|
||||||
|
|
||||||
|
# fo, peo, seos = make_objects('/home/raphael/.viper/projects/troopers17/vt_samples/1189/566ab945f61be016bfd9e83cc1b64f783b9b8deb891e6d504d3442bc8281b092')
|
||||||
|
import glob
|
||||||
|
for f in glob.glob('/home/raphael/.viper/projects/troopers17/vt_samples/*/*'):
|
||||||
|
#for f in glob.glob('/home/raphael/gits/pefile-tests/tests/corkami/*/*.exe'):
|
||||||
|
#for f in glob.glob('/home/raphael/gits/pefile-tests/tests/corkami/pocs/version_mini.exe'):
|
||||||
|
#for f in glob.glob('/home/raphael/gits/pefile-tests/tests/corkami/pocs/version_cust.exe'):
|
||||||
|
#for f in glob.glob('/home/raphael/gits/pefile-tests/tests/data/*.dll'):
|
||||||
|
print('\n', f)
|
||||||
|
try:
|
||||||
|
fo, peo, seos = make_binary_objects(f)
|
||||||
|
except Exception as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
continue
|
||||||
|
continue
|
||||||
|
if fo:
|
||||||
|
response = pymisp.add_object(2221, 7, fo)
|
||||||
|
print(response)
|
||||||
|
if peo:
|
||||||
|
pymisp.add_object(2221, 11, peo)
|
||||||
|
if seos:
|
||||||
|
for s in seos:
|
||||||
|
pymisp.add_object(2221, 12, s)
|
||||||
|
|
||||||
|
#with open('fileobj.json', 'w') as f:
|
||||||
|
# json.dump(fo, f)
|
||||||
|
#with open('peobj.json', 'w') as f:
|
||||||
|
# json.dump(peo, f)
|
||||||
|
#with open('seobj.json', 'w') as f:
|
||||||
|
# json.dump(seos, f)
|
||||||
|
break
|
5
setup.py
5
setup.py
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
import pymisp
|
import pymisp
|
||||||
|
@ -29,5 +29,6 @@ setup(
|
||||||
test_suite="tests",
|
test_suite="tests",
|
||||||
install_requires=['requests', 'python-dateutil', 'jsonschema'],
|
install_requires=['requests', 'python-dateutil', 'jsonschema'],
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
package_data={'data': ['schema.json', 'schema-lax.json', 'describeTypes.json']},
|
package_data={'pymisp': ['data/*.json', 'data/misp-objects/schema.json',
|
||||||
|
'data/misp-objects/objects/*/definition.json']},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue