Skip to content
This repository has been archived by the owner on Jun 7, 2023. It is now read-only.

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
frennkie committed May 12, 2017
1 parent 8d7ad1f commit 53f98cd
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 16 deletions.
63 changes: 63 additions & 0 deletions viper/common/abstracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@
# This file is part of Viper - https://github.com/viper-framework/viper
# See the file 'LICENSE' for copying permission.

import sys
import argparse
from distutils.spawn import find_executable
import pkg_resources

import logging

import viper.common.out as out
from viper.core.config import console_output
from viper.common.exceptions import ArgumentErrorCallback

log = logging.getLogger('viper')


class ArgumentParser(argparse.ArgumentParser):
def print_usage(self, file=None):
Expand All @@ -31,9 +39,64 @@ class Module(object):
authors = []
output = []

min_python_version = (2, 7)
dependency_list_python = []
dependency_list_system = []

def __init__(self):
self.parser = ArgumentParser(prog=self.cmd, description=self.description)

def check(self):
min_python_version = self._check_min_python_version()
dep_python = self._check_dependencies_python()
dep_system = self._check_dependencies_system()
if min_python_version and dep_python and dep_system:
return True
else:
return False

def _check_min_python_version(self):
if sys.version_info >= self.min_python_version:
log.debug("{}: Python Version ok".format(self.__class__.__name__))
return True
else:
log.warning("{}: Python Version NOT ok".format(self.__class__.__name__))
return False

def _check_dependencies_python(self):
if not self.dependency_list_python:
return True

missing = []

for item in self.dependency_list_python:
try:
pkg_resources.require(item)
except pkg_resources.DistributionNotFound as err:
log.debug("{}: Missing Python dependency: {}".format(self.__class__.__name__, err))
missing.append(item)
except pkg_resources.VersionConflict as err:
log.debug("{}: Python dependency wrong version: {}".format(self.__class__.__name__, err))
missing.append(item)

if missing:
log.warning("{}: Missing/Failed Python dependencies: {}".format(self.__class__.__name__, missing))
return False

return True

def _check_dependencies_system(self):
if not self.dependency_list_system:
return True

missing = [item for item in self.dependency_list_system if not find_executable(item)]

if missing:
log.warning("{}: Missing System dependencies: {}".format(self.__class__.__name__, missing))
return False
else:
return True

def set_commandline(self, command):
self.command_line = command

Expand Down
42 changes: 28 additions & 14 deletions viper/core/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@

import pkgutil
import inspect
import logging
import importlib

from viper.common.abstracts import Module
from viper.common.abstracts import get_argparse_parser_actions
from viper.common.abstracts import get_argparse_subparser_actions
from viper.common.out import print_warning

log = logging.getLogger('viper')


def load_modules():
# Import modules package.
import viper.modules as modules

plugins = dict()
working_plugins = dict()
failed_plugins = dict()

# Walk recursively through all modules and packages.
for loader, module_name, ispkg in pkgutil.walk_packages(modules.__path__, modules.__name__ + '.'):
Expand All @@ -32,16 +36,26 @@ def load_modules():

# Walk through all members of currently imported modules.
for member_name, member_object in inspect.getmembers(module):
# Check if current member is a class.
if inspect.isclass(member_object):
# Yield the class if it's a subclass of Module.
if issubclass(member_object, Module) and member_object is not Module:
plugins[member_object.cmd] = dict(obj=member_object,
description=member_object.description,
parser_args=get_argparse_parser_actions(member_object().parser),
subparser_args=get_argparse_subparser_actions(member_object().parser))

return plugins


__modules__ = load_modules()
if not inspect.isclass(member_object):
continue
# Yield the class if it's a subclass of Module.
if issubclass(member_object, Module) and member_object is not Module:
# run dependency check on each module and only add to working list if successful
if member_object().check():
log.debug("Module: {} - dependency check ok".format(member_name))
working_plugins[member_object.cmd] = dict(obj=member_object,
description=member_object.description,
parser_args=get_argparse_parser_actions(member_object().parser),
subparser_args=get_argparse_subparser_actions(member_object().parser))
else:
log.warning("Module: {} - failed dependency check".format(member_name))
print_warning("Module: {} - failed dependency check".format(member_name))
failed_plugins[member_object.cmd] = dict(obj=member_object,
description=member_object.description,
parser_args=get_argparse_parser_actions(member_object().parser),
subparser_args=get_argparse_subparser_actions(member_object().parser))

return working_plugins, failed_plugins


__modules__, __failed_modules__ = load_modules()
29 changes: 27 additions & 2 deletions viper/core/ui/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from viper.common.version import __version__
from viper.core.session import __sessions__
from viper.core.project import __project__
from viper.core.plugins import __modules__
from viper.core.plugins import __modules__, __failed_modules__
from viper.core.database import Database
from viper.core.storage import store_sample, get_sample_path
from viper.core.config import Config, console_output
Expand Down Expand Up @@ -107,9 +107,13 @@ class About(Command):
cmd = "about"
description = "Show information about this Viper instance"

def __init__(self):
super(About, self).__init__()
self.parser.add_argument('-m', '--modules', action='store_true', help="Show info about modules")

def run(self, *args):
try:
self.parser.parse_args(args)
args = self.parser.parse_args(args)
except:
return

Expand All @@ -128,6 +132,27 @@ def run(self, *args):

self.log('table', dict(header=['Configuration', ''], rows=rows))

if args.modules:
rows = list()
for key, value in __modules__.items():
min_python_version_str = ".".join([str(x) for x in value['obj'].min_python_version])
dependency_python = ",".join(value['obj'].dependency_list_python)
dependency_system = ",".join(value['obj'].dependency_list_system)

rows.append([key, dependency_system, min_python_version_str, dependency_python])

self.log('table', dict(header=['Active Modules', 'System dependencies', 'Min Python Version', 'Python requirements'], rows=rows))

rows = list()
for key, value in __failed_modules__.items():
min_python_version_str = ".".join([str(x) for x in value['obj'].min_python_version])
dependency_python = ",".join(value['obj'].dependency_list_python)
dependency_system = ",".join(value['obj'].dependency_list_system)

rows.append([key, dependency_system, min_python_version_str, dependency_python])

self.log('table', dict(header=['Failed Modules', 'System dependencies', 'Min Python Version', 'Python requirements'], rows=rows))


class Analysis(Command):
##
Expand Down
3 changes: 3 additions & 0 deletions viper/modules/exif.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class Exif(Module):
description = 'Extract Exif MetaData'
authors = ['Kevin Breen']

dependency_list_python = ["exiftool"]
dependency_list_system = ["exif"]

def __init__(self):
super(Exif, self).__init__()

Expand Down
2 changes: 2 additions & 0 deletions viper/modules/misp.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class MISP(Module):
description = 'Upload and query IOCs to/from a MISP instance'
authors = ['Raphaël Vinot']

dependency_list_python = ["pymisp", "pytaxonomies", "requests"]

def __init__(self):
super(MISP, self).__init__()
self.cur_path = __project__.get_path()
Expand Down

0 comments on commit 53f98cd

Please sign in to comment.