Exemple #1
0
    def size_cluster(self):
        db = Database()
        samples = db.find(key='all')

        cluster = {}
        for sample in samples:
            sample_path = get_sample_path(sample.sha256)
            if not os.path.exists(sample_path):
                continue

            try:
                cur_size = os.path.getsize(sample_path)
            except Exception as e:
                self.log('error', "Error {0} for sample {1}".format(e, sample.sha256))
                continue

            if cur_size not in cluster:
                cluster[cur_size] = []

            cluster[cur_size].append([sample.md5, sample.name])

        for cluster_name, cluster_members in cluster.items():
            # Skipping clusters with only one entry.
            if len(cluster_members) == 1:
                continue

            self.log('info', "Cluster size {0} with {1} elements".format(bold(cluster_name), len(cluster_members)))
            self.log('table', dict(header=['MD5', 'Name'], rows=cluster_members))
Exemple #2
0
    def run(self):
        super(Strings, self).run()
        
        if self.args is None:
            return

        if not (self.args.all or self.args.files or self.args.hosts or self.args.network or self.args.interesting):
            self.log('error', 'At least one of the parameters is required')
            self.usage()
            return

        if self.args.scan:
            db = Database()
            samples = db.find(key='all')
            for sample in samples:
                sample_path = get_sample_path(sample.sha256)
                strings = self.get_strings(File(sample_path))
                self.process_strings(strings, sample.name)
        else:
            if not __sessions__.is_set():
                self.log('error', "No open session")
                return
            if os.path.exists(__sessions__.current.file.path):
                strings = self.get_strings(__sessions__.current.file)
                self.process_strings(strings)
Exemple #3
0
    def run(self, *args):
        try:
            args = self.parser.parse_args(args)
        except SystemExit:
            return

        if not __sessions__.is_set():
            self.log('error', "No open session. This command expects a file to be open.")
            return

        if not __project__.name:
            src_project = "default"
        else:
            src_project = __project__.name

        db = Database()

        db.copied_id_sha256 = []
        res = db.copy(__sessions__.current.file.id,
                      src_project=src_project, dst_project=args.project,
                      copy_analysis=True, copy_notes=True, copy_tags=True, copy_children=args.children)

        if args.delete:
            __sessions__.close()
            for item_id, item_sha256 in db.copied_id_sha256:
                db.delete_file(item_id)
                os.remove(get_sample_path(item_sha256))
                self.log('info', "Deleted: {}".format(item_sha256))

        if res:
            self.log('success', "Successfully copied sample(s)")
            return True
        else:
            self.log('error', "Something went wrong")
            return False
Exemple #4
0
def logo():
    print("""         _
        (_)
   _   _ _ ____  _____  ____
  | | | | |  _ \| ___ |/ ___)
   \ V /| | |_| | ____| |
    \_/ |_|  __/|_____)_| v1.3-dev
          |_|
    """)

    db = Database()
    count = db.get_sample_count()

    # Handle the New database format
    try:
        db.find('all', None)
    except:
        print_error("You need to update your viper database. Run 'python update.py -d'")
        sys.exit()


    if __project__.name:
        name = __project__.name
    else:
        name = 'default'

    print(magenta("You have " + bold(count)) +
          magenta(" files in your " + bold(name) +
          magenta(" repository".format(bold(name)))))
    if cfg.autorun.enabled and len(cfg.autorun.commands) == 0:
        print_warning("You have enabled autorun but not set any commands in viper.conf.")
Exemple #5
0
def url_download():
    url = request.forms.get('url')
    tags = request.forms.get('tag_list')
    tags = "url,"+tags
    if request.forms.get("tor"):
        upload = network.download(url,tor=True)
    else:
        upload = network.download(url,tor=False)
    if upload == None:
        return template('error.tpl', error="server can't download from URL")
    # Set Project
    project = 'Main'
    db = Database()
    tf = tempfile.NamedTemporaryFile()
    tf.write(upload)
    if tf == None:
        return template('error.tpl', error="server can't download from URL")
    tf.flush()
    tf_obj = File(tf.name)
    tf_obj.name = tf_obj.sha256
    new_path = store_sample(tf_obj)
    success = False
    if new_path:
        # Add file to the database.
        success = db.add(obj=tf_obj, tags=tags)

    if success:
        #redirect("/project/{0}".format(project))
        redirect("/file/Main/"+tf_obj.sha256)
    else:
        return template('error.tpl', error="Unable to Store The File,already in database")
Exemple #6
0
    def run(self):
        if not __session__.is_set():
            print_error("No session opened")
            return

        if not HAVE_PYDEEP:
            print_error("Missing dependency, install pydeep (`pip install pydeep`)")
            return

        if not __session__.file.ssdeep:
            print_error("No ssdeep hash available for opened file")
            return

        db = Database()
        samples = db.find(key='all')

        for sample in samples:
            if sample.sha256 == __session__.file.sha256:
                continue

            if not sample.ssdeep:
                continue

            score = pydeep.compare(__session__.file.ssdeep, sample.ssdeep)
            if score > 40:
                print("Match {0}%: {1}".format(score, sample.sha256))
Exemple #7
0
def get_file(file_hash):
    key = ''
    if len(file_hash) == 32:
        key = 'md5'
    elif len(file_hash) == 64:
        key = 'sha256'
    else:
        return HTTPError(400, 'Invalid hash format (use md5 or sha256)')

    db = Database()
    rows = db.find(key=key, value=file_hash)

    if not rows:
        raise HTTPError(404, 'File not found in the database')

    path = get_sample_path(rows[0].sha256)
    if not path:
        raise HTTPError(404, 'File not found in the repository')

    response.content_length = os.path.getsize(path)
    response.content_type = 'application/octet-stream; charset=UTF-8'
    data = ''
    for chunk in File(path).get_chunks():
        data += chunk

    return data
Exemple #8
0
def logo():
    print("""         _
        (_)
   _   _ _ ____  _____  ____
  | | | | |  _ \| ___ |/ ___)
   \ V /| | |_| | ____| |
    \_/ |_|  __/|_____)_| v{}
          |_|
    """.format(__version__))

    db = Database()
    count = db.get_sample_count()

    try:
        db.find('all')
    except Exception:
        print_error("You need to update your Viper database. Run 'python update.py -d'")
        sys.exit()

    if __project__.name:
        name = __project__.name
    else:
        name = 'default'

    print(magenta("You have " + bold(count)) +
          magenta(" files in your " + bold(name)) +
          magenta(" repository"))
Exemple #9
0
def delete_file(file_hash):
    success = False
    key = ''
    if len(file_hash) == 32:
        key = 'md5'
    elif len(file_hash) == 64:
        key = 'sha256'
    else:
        return HTTPError(400, 'Invalid hash format (use md5 or sha256)')

    db = Database()
    rows = db.find(key=key, value=file_hash)

    if not rows:
        raise HTTPError(404, 'File not found in the database')
	
    if rows:
		malware_id = rows[0].id
		path = get_sample_path(rows[0].sha256)
		if db.delete(malware_id):
			success = True
		else:
			raise HTTPError(404, 'File not found in repository')

    path = get_sample_path(rows[0].sha256)
    if not path:
        raise HTTPError(404, 'File not found in file system')
    else:	
        success=os.remove(path)
    
    if success:
        return jsonize({'message' : 'deleted'})
    else:
        return HTTPError(500, 'Unable to delete file')
Exemple #10
0
 def add_file(self, file_path, tags, parent):
     obj = File(file_path)
     new_path = store_sample(obj)
     if new_path:
         # Add file to the database.
         db = Database()
         db.add(obj=obj, tags=tags, parent_sha=parent)
         return obj.sha256
Exemple #11
0
    def peid(self):

        def get_signatures():
            with file(os.path.join(VIPER_ROOT, 'data/peid/UserDB.TXT'), 'rt') as f:
                sig_data = f.read()

            signatures = peutils.SignatureDatabase(data=sig_data)

            return signatures

        def get_matches(pe, signatures):
            matches = signatures.match_all(pe, ep_only=True)
            return matches

        if not self.__check_session():
            return

        signatures = get_signatures()
        peid_matches = get_matches(self.pe, signatures)

        if peid_matches:
            self.log('info', "PEiD Signatures:")
            for sig in peid_matches:
                if type(sig) is list:
                    self.log('item', sig[0])
                else:
                    self.log('item', sig)
        else:
            self.log('info', "No PEiD signatures matched.")

        if self.args.scan and peid_matches:
            self.log('info', "Scanning the repository for matching samples...")

            db = Database()
            samples = db.find(key='all')

            matches = []
            for sample in samples:
                if sample.sha256 == __sessions__.current.file.sha256:
                    continue

                sample_path = get_sample_path(sample.sha256)
                if not os.path.exists(sample_path):
                    continue

                try:
                    cur_pe = pefile.PE(sample_path)
                    cur_peid_matches = get_matches(cur_pe, signatures)
                except:
                    continue

                if peid_matches == cur_peid_matches:
                    matches.append([sample.name, sample.sha256])

            self.log('info', "{0} relevant matches found".format(bold(len(matches))))

            if len(matches) > 0:
                self.log('table', dict(header=['Name', 'SHA256'], rows=matches))
Exemple #12
0
def _add_file(file_path, name, tags, parent_sha):
    obj = File(file_path)
    new_path = store_sample(obj)
    if new_path:
        db = Database()
        db.add(obj=obj, name=name, tags=tags, parent_sha=parent_sha)
        return obj.sha256
    else:
        return None
Exemple #13
0
def _add_file(file_path, name, tags, parent_sha):
    obj = File(file_path)
    new_path = store_sample(obj)
    if new_path:
        db = Database()
        db.add(obj=obj, name=name, tags=tags, parent_sha=parent_sha)
        return obj.sha256
    else:
        return None
Exemple #14
0
    def cmd_projects(self, *args):
        parser = argparse.ArgumentParser(
            prog="projects",
            description="Open a file",
            epilog="List or switch existing projects")
        group = parser.add_mutually_exclusive_group()
        group.add_argument('-l',
                           '--list',
                           action="store_true",
                           help="List all existing projects")
        group.add_argument('-s',
                           '--switch',
                           metavar='project_name',
                           help="Switch to the specified project")

        try:
            args = parser.parse_args(args)
        except:
            return

        projects_path = os.path.join(os.getcwd(), 'projects')

        if not os.path.exists(projects_path):
            print_info("The projects directory does not exist yet")
            return

        if args.list:
            print_info("Projects Available:")

            rows = []
            for project in os.listdir(projects_path):
                project_path = os.path.join(projects_path, project)
                if os.path.isdir(project_path):
                    current = ''
                    if __project__.name and project == __project__.name:
                        current = 'Yes'
                    rows.append([
                        project,
                        time.ctime(os.path.getctime(project_path)), current
                    ])

            print(
                table(header=['Project Name', 'Creation Time', 'Current'],
                      rows=rows))
        elif args.switch:
            if __sessions__.is_set():
                __sessions__.close()
                print_info("Closed opened session")

            __project__.open(args.switch)
            print_info("Switched to project {0}".format(bold(args.switch)))

            # Need to re-initialize the Database to open the new SQLite file.
            self.db = Database()
        else:
            parser.print_usage()
Exemple #15
0
    def pehash(self):
        if not HAVE_PEHASH:
            self.log('error', "PEhash is missing. Please copy PEhash to the modules directory of Viper")
            return

        current_pehash = None
        if __sessions__.is_set():
            current_pehash = calculate_pehash(__sessions__.current.file.path)
            self.log('info', "PEhash: {0}".format(bold(current_pehash)))

        if self.args.all or self.args.cluster or self.args.scan:
            db = Database()
            samples = db.find(key='all')

            rows = []
            for sample in samples:
                sample_path = get_sample_path(sample.sha256)
                pe_hash = calculate_pehash(sample_path)
                if pe_hash:
                    rows.append((sample.name, sample.md5, pe_hash))

        if self.args.all:
            self.log('info', "PEhash for all files:")
            header = ['Name', 'MD5', 'PEhash']
            self.log('table', dict(header=header, rows=rows))

        elif self.args.cluster:
            self.log('info', "Clustering files by PEhash...")

            cluster = {}
            for sample_name, sample_md5, pe_hash in rows:
                cluster.setdefault(pe_hash, []).append([sample_name, sample_md5])

            for item in cluster.items():
                if len(item[1]) > 1:
                    self.log('info', "PEhash cluster {0}:".format(bold(item[0])))
                    self.log('table', dict(header=['Name', 'MD5'], rows=item[1]))

        elif self.args.scan:
            if __sessions__.is_set() and current_pehash:
                self.log('info', "Finding matching samples...")

                matches = []
                for row in rows:
                    if row[1] == __sessions__.current.file.md5:
                        continue

                    if row[2] == current_pehash:
                        matches.append([row[0], row[1]])

                if matches:
                    self.log('table', dict(header=['Name', 'MD5'], rows=matches))
                else:
                    self.log('info', "No matches found")
Exemple #16
0
    def pehash(self):
        if not HAVE_PEHASH:
            self.log('error', "PEhash is missing. Please copy PEhash to the modules directory of Viper")
            return

        current_pehash = None
        if __sessions__.is_set():
            current_pehash = calculate_pehash(data=__sessions__.current.file.data)
            self.log('info', "PEhash: {0}".format(bold(current_pehash)))

        if self.args.all or self.args.cluster or self.args.scan:
            db = Database()
            samples = db.find(key='all')

            rows = []
            for sample in samples:
                sample_path = get_sample_path(sample.sha256)
                pe_hash = calculate_pehash(sample_path)
                if pe_hash:
                    rows.append((sample.name, sample.md5, pe_hash))

        if self.args.all:
            self.log('info', "PEhash for all files:")
            header = ['Name', 'MD5', 'PEhash']
            self.log('table', dict(header=header, rows=rows))

        elif self.args.cluster:
            self.log('info', "Clustering files by PEhash...")

            cluster = {}
            for sample_name, sample_md5, pe_hash in rows:
                cluster.setdefault(pe_hash, []).append([sample_name, sample_md5])

            for item in cluster.items():
                if len(item[1]) > 1:
                    self.log('info', "PEhash cluster {0}:".format(bold(item[0])))
                    self.log('table', dict(header=['Name', 'MD5'], rows=item[1]))

        elif self.args.scan:
            if __sessions__.is_set() and current_pehash:
                self.log('info', "Finding matching samples...")

                matches = []
                for row in rows:
                    if row[1] == __sessions__.current.file.md5:
                        continue

                    if row[2] == current_pehash:
                        matches.append([row[0], row[1]])

                if matches:
                    self.log('table', dict(header=['Name', 'MD5'], rows=matches))
                else:
                    self.log('info', "No matches found")
Exemple #17
0
def open_db(project):
    # Check for valid project
    if project == 'default':
        __project__.open(project)
        return Database()
    else:
        try:
            __project__.open(project)
            return Database()
        except Exception:
            return False
Exemple #18
0
    def compiletime(self):
        def get_compiletime(pe):
            return datetime.datetime.fromtimestamp(
                pe.FILE_HEADER.TimeDateStamp)

        if not self.__check_session():
            return

        compile_time = get_compiletime(self.pe)
        self.log('info', "Compile Time: {0}".format(bold(compile_time)))

        if self.args.scan:
            self.log('info', "Scanning the repository for matching samples...")

            db = Database()
            samples = db.find(key='all')

            matches = []
            for sample in samples:
                if sample.sha256 == __sessions__.current.file.sha256:
                    continue

                sample_path = get_sample_path(sample.sha256)
                if not os.path.exists(sample_path):
                    continue

                try:
                    cur_pe = pefile.PE(sample_path)
                    cur_compile_time = get_compiletime(cur_pe)
                except:
                    continue

                if compile_time == cur_compile_time:
                    matches.append([sample.name, sample.md5, cur_compile_time])
                else:
                    if self.args.window:
                        if cur_compile_time > compile_time:
                            delta = (cur_compile_time - compile_time)
                        elif cur_compile_time < compile_time:
                            delta = (compile_time - cur_compile_time)

                        delta_minutes = int(delta.total_seconds()) / 60
                        if delta_minutes <= self.args.window:
                            matches.append(
                                [sample.name, sample.md5, cur_compile_time])

            self.log('info',
                     "{0} relevant matches found".format(bold(len(matches))))

            if len(matches) > 0:
                self.log(
                    'table',
                    dict(header=['Name', 'MD5', 'Compile Time'], rows=matches))
Exemple #19
0
 def _search_local_hashes(self, event, open_session=True):
     local = []
     samples_count = 0
     if isinstance(event, MISPEvent):
         misp_event = event
     elif event.get('Event') is None:
         self.log('error', event)
         return
     else:
         misp_event = MISPEvent()
         misp_event.load(event)
     if not hasattr(misp_event, 'id'):
         # The event doesn't exists upstream, breaking.
         return
     for a in misp_event.attributes + [
             attribute for obj in misp_event.objects
             for attribute in obj.attributes
     ]:
         row = None
         if a.type == 'malware-sample':
             samples_count += 1
         if a.type in ('md5', 'sha1', 'sha256'):
             row = Database().find(key=a.type, value=a.value)
         elif a.type in ('filename|md5', 'filename|sha1',
                         'filename|sha256'):
             row = Database().find(key=a.type.split('|')[1],
                                   value=a.value.split('|')[1])
         elif a.type == 'malware-sample':
             row = Database().find(key='md5', value=a.value.split('|')[1])
         if row:
             local.append(row[0])
     self.log(
         'info',
         'Event {} contains {} samples.'.format(misp_event.id,
                                                samples_count))
     if not open_session:
         return
     shas = set([l.sha256 for l in local])
     if len(shas) == 1:
         __sessions__.new(get_sample_path(shas.pop()),
                          MispEvent(misp_event, self.offline_mode))
     elif len(shas) > 1:
         self.log('success',
                  'The following samples are in this viper instance:')
         __sessions__.new(
             misp_event=MispEvent(misp_event, self.offline_mode))
         for s in shas:
             self.log('item', s)
     else:
         __sessions__.new(
             misp_event=MispEvent(misp_event, self.offline_mode))
         self.log('info', 'No known (in Viper) samples in that event.')
Exemple #20
0
def add_file():
    tags = request.forms.get('tag_list')
    uploads = request.files.getlist('file')

    # Set Project
    project = request.forms.get('project')
    if project in project_list():
        __project__.open(project)
    else:
        __project__.open('../')
        project = 'Main'
    db = Database()
    file_list = []
    # Write temp file to disk
    with upload_temp() as temp_dir:
        for upload in uploads:
            file_path = os.path.join(temp_dir, upload.filename)
            with open(file_path, 'w') as tmp_file:
                tmp_file.write(upload.file.read())
            # Zip Files
            if request.forms.get('unzip'):
                zip_pass = request.forms.get('zip_pass')
                try:
                    with ZipFile(file_path) as zf:
                        zf.extractall(temp_dir, pwd=zip_pass)
                    for root, dirs, files in os.walk(temp_dir, topdown=False):
                        for name in files:
                            if not name == upload.filename:
                                file_list.append(os.path.join(root, name))
                except Exception as e:
                    return template('error.tpl',
                                    error="Error with zipfile - {0}".format(e))
            # Non zip files
            else:
                file_list.append(file_path)

        # Add each file
        for new_file in file_list:
            print new_file
            obj = File(new_file)
            new_path = store_sample(obj)
            success = True
            if new_path:
                # Add file to the database.
                success = db.add(obj=obj, tags=tags)
                if not success:
                    return template(
                        'error.tpl',
                        error="Unable to Store The File: {0}".format(
                            upload.filename))
    redirect("/project/{0}".format(project))
Exemple #21
0
    def cmd_tags(self, *args):
        parser = argparse.ArgumentParser(
            prog="tags", description="Modify tags of the opened file")
        parser.add_argument(
            '-a',
            '--add',
            help="Add tags to the opened file (comma separated)")
        parser.add_argument('-d',
                            '--delete',
                            help="Delete a tag from the opened file")
        try:
            args = parser.parse_args(args)
        except:
            return

        # This command requires a session to be opened.
        if not __sessions__.is_set():
            print_error("No session opened")
            parser.print_usage()
            return

        # If no arguments are specified, there's not much to do.
        # However, it could make sense to also retrieve a list of existing
        # tags from this command, and not just from the "find" command alone.
        if args.add is None and args.delete is None:
            parser.print_usage()
            return

        # TODO: handle situation where addition or deletion of a tag fail.

        if args.add:
            # Add specified tags to the database's entry belonging to
            # the opened file.
            db = Database()
            db.add_tags(__sessions__.current.file.sha256, args.add)
            print_info("Tags added to the currently opened file")

            # We refresh the opened session to update the attributes.
            # Namely, the list of tags returned by the "info" command
            # needs to be re-generated, or it wouldn't show the new tags
            # until the existing session is closed a new one is opened.
            print_info("Refreshing session to update attributes...")
            __sessions__.new(__sessions__.current.file.path)

        if args.delete:
            # Delete the tag from the database.
            Database().delete_tag(args.delete)
            # Refresh the session so that the attributes of the file are
            # updated.
            print_info("Refreshing session to update attributes...")
            __sessions__.new(__sessions__.current.file.path)
Exemple #22
0
    def parse_message(self, message_folder):
        db = Database()
        email_header = os.path.join(message_folder, 'InternetHeaders.txt')
        email_body = os.path.join(message_folder, 'Message.txt')

        envelope = headers = email_text = ''
        if os.path.exists(email_header):
            envelope, headers = self.email_headers(email_header)
        if os.path.exists(email_body):
            email_text = open(email_body, 'rb').read()

        tags = 'pst, {0}'.format(message_folder)
        if os.path.exists(os.path.join(message_folder, 'Attachments')):
            for filename in os.listdir(
                    os.path.join(message_folder, 'Attachments')):
                if os.path.isfile(
                        os.path.join(message_folder, 'Attachments', filename)):
                    obj = File(
                        os.path.join(message_folder, 'Attachments', filename))
                    sha256 = hashlib.sha256(
                        open(
                            os.path.join(message_folder, 'Attachments',
                                         filename), 'rb').read()).hexdigest()
                    new_path = store_sample(obj)
                    if new_path:
                        # Add file to the database.
                        db.add(obj=obj, tags=tags)
                    # Add Email Details as a Note
                    # To handle duplicates we use multiple notes
                    headers_body = 'Envelope: \n{0}\nHeaders: \n{1}\n'.format(
                        envelope, headers)
                    db.add_note(sha256, 'Headers', headers_body)

                    # Add a note with email body
                    db.add_note(sha256, 'Email Body', string_clean(email_text))
Exemple #23
0
    def run(self):
        super(Fuzzy, self).run()

        if not __sessions__.is_set():
            self.log('error', "No session opened")
            return

        if not HAVE_PYDEEP:
            self.log(
                'error',
                "Missing dependency, install pydeep (`pip install pydeep`)")
            return

        if not __sessions__.current.file.ssdeep:
            self.log('error', "No ssdeep hash available for opened file")
            return

        arg_verbose = False
        if self.args and self.args.verbose:
            arg_verbose = True

        db = Database()
        samples = db.find(key='all')

        matches = []
        for sample in samples:
            if sample.sha256 == __sessions__.current.file.sha256:
                continue

            if not sample.ssdeep:
                continue

            score = pydeep.compare(__sessions__.current.file.ssdeep,
                                   sample.ssdeep)
            if score > 40:
                matches.append(
                    ['{0}%'.format(score), sample.name, sample.sha256])

            if arg_verbose:
                self.log(
                    'info',
                    "Match {0}%: {2} [{1}]".format(score, sample.name,
                                                   sample.sha256))

        self.log('info',
                 "{0} relevant matches found".format(bold(len(matches))))

        if len(matches) > 0:
            self.log('table',
                     dict(header=['Score', 'Name', 'SHA256'], rows=matches))
Exemple #24
0
    def run(self, *args):
        try:
            args = self.parser.parse_args(args)
        except SystemExit:
            return

        if not __sessions__.is_set():
            self.log(
                'error',
                "No open session. This command expects a file to be open.")
            return

        db = Database()

        # check if the file is already stores, otherwise exit
        malware = db.find(key='sha256', value=__sessions__.current.file.sha256)
        if not malware:
            self.log(
                'error',
                "The opened file doesn't appear to be in the database, have you stored it yet?"
            )
            return

        if args.list:
            # Retrieve all analysis for the currently opened file.

            analysis_list = malware[0].analysis
            if not analysis_list:
                self.log('info', "No analysis available for this file yet")
                return

            # Populate table rows.
            rows = [[analysis.id, analysis.cmd_line, analysis.stored_at]
                    for analysis in analysis_list]

            # Display list of existing results.
            self.log(
                'table',
                dict(header=['ID', 'Cmd Line', 'Saved On (UTC)'], rows=rows))

        elif args.view:
            # Retrieve analysis with the specified ID and print it.
            result = db.get_analysis(args.view)
            if result:
                self.log('info', bold('Cmd Line: ') + result.cmd_line)
                for line in json.loads(result.results):
                    self.log(line['type'], line['data'])
            else:
                self.log('info',
                         "There is no analysis with ID {0}".format(args.view))
Exemple #25
0
    def compiletime(self):

        def get_compiletime(pe):
            return datetime.datetime.fromtimestamp(pe.FILE_HEADER.TimeDateStamp)

        if not self.__check_session():
            return

        compile_time = get_compiletime(self.pe)
        self.log('info', "Compile Time: {0}".format(bold(compile_time)))

        if self.args.scan:
            self.log('info', "Scanning the repository for matching samples...")

            db = Database()
            samples = db.find(key='all')

            matches = []
            for sample in samples:
                if sample.sha256 == __sessions__.current.file.sha256:
                    continue

                sample_path = get_sample_path(sample.sha256)
                if not os.path.exists(sample_path):
                    continue

                try:
                    cur_pe = pefile.PE(sample_path)
                    cur_compile_time = get_compiletime(cur_pe)
                except:
                    continue

                if compile_time == cur_compile_time:
                    matches.append([sample.name, sample.md5, cur_compile_time])
                else:
                    if self.args.window:
                        if cur_compile_time > compile_time:
                            delta = (cur_compile_time - compile_time)
                        elif cur_compile_time < compile_time:
                            delta = (compile_time - cur_compile_time)

                        delta_minutes = int(delta.total_seconds()) / 60
                        if delta_minutes <= self.args.window:
                            matches.append([sample.name, sample.md5, cur_compile_time])

            self.log('info', "{0} relevant matches found".format(bold(len(matches))))

            if len(matches) > 0:
                self.log('table', dict(header=['Name', 'MD5', 'Compile Time'], rows=matches))
Exemple #26
0
    def run(self):
        # TODO: this function needs to be refactored.

        super(Strings, self).run()
        if self.args is None:
            return

        arg_all = self.args.all
        arg_hosts = self.args.hosts
        arg_scan = self.args.scan

        regexp = '[\x20\x30-\x39\x41-\x5a\x61-\x7a\-\.:]{4,}'

        if arg_scan:
            db = Database()
            samples = db.find(key='all')

            rows = []
            for sample in samples:
                sample_path = get_sample_path(sample.sha256)

                strings = re.findall(regexp, File(sample_path).data)
                results = self.extract_hosts(strings)

                if results:
                    self.log('info', sample.name)

                    for result in results:
                        self.log('item', result)
        else:
            if not __sessions__.is_set():
                self.log('error', "No open session")
                return

            if os.path.exists(__sessions__.current.file.path):
                strings = re.findall(regexp, __sessions__.current.file.data)

            if arg_all:
                for entry in strings:
                    self.log('', entry)
            elif arg_hosts:
                results = self.extract_hosts(strings)
                for result in results:
                    self.log('item', result)

        if not arg_all and not arg_hosts and not arg_scan:
            self.log('error', 'At least one of the parameters is required')
            self.usage()
Exemple #27
0
    def run(self):
        # TODO: this function needs to be refactored.

        super(Strings, self).run()
        if self.args is None:
            return

        arg_all = self.args.all
        arg_hosts = self.args.hosts
        arg_scan = self.args.scan

        regexp = '[\x20\x30-\x39\x41-\x5a\x61-\x7a\-\.:]{4,}'

        if arg_scan:
            db = Database()
            samples = db.find(key='all')

            rows = []
            for sample in samples:
                sample_path = get_sample_path(sample.sha256)

                strings = re.findall(regexp, File(sample_path).data)
                results = self.extract_hosts(strings)

                if results:
                    self.log('info', sample.name)

                    for result in results:
                        self.log('item', result)
        else:
            if not __sessions__.is_set():
                self.log('error', "No open session")
                return

            if os.path.exists(__sessions__.current.file.path):
                strings = re.findall(regexp, __sessions__.current.file.data)

            if arg_all:
                for entry in strings:
                    self.log('', entry)
            elif arg_hosts:
                results = self.extract_hosts(strings)
                for result in results:
                    self.log('item', result)
        
        if not arg_all and not arg_hosts and not arg_scan:
            self.log('error', 'At least one of the parameters is required')
            self.usage()
Exemple #28
0
def file_info(file_hash, project=False):
    contents = {}
    if project in project_list():
        __project__.open(project)
        contents['project'] = project
    else:
        __project__.open('../')
        contents['project'] = 'Main'
    # Open the Database
    db = Database()
    # Open a session
    try:
        path = get_sample_path(file_hash)
        __sessions__.new(path)
    except:
        return template('error.tpl', error="{0} Does not match any hash in the Database".format(file_hash))
    
    # Get the file info
    contents['file_info'] = [
                __sessions__.current.file.name,
                __sessions__.current.file.tags,
                __sessions__.current.file.path,
                __sessions__.current.file.size,
                __sessions__.current.file.type,
                __sessions__.current.file.mime,
                __sessions__.current.file.md5,
                __sessions__.current.file.sha1,
                __sessions__.current.file.sha256,
                __sessions__.current.file.sha512,
                __sessions__.current.file.ssdeep,
                __sessions__.current.file.crc32                
                ]
                
    # Get Any Notes
    note_list = []
    malware = db.find(key='sha256', value=file_hash)
    if malware:
        notes = malware[0].note
        if notes:
            rows = []
            for note in notes:
                note_list.append([note.title, note.body, note.id])
    contents['notes'] = note_list
    
    # Close the session
    __sessions__.close()
    # Return the page
    return template('file.tpl', **contents)
Exemple #29
0
def tags():
    # Set DB
    db = Database()
    
    # Search or Delete
    if request.method == 'GET':
        action = request.query.action
        value = request.query.value.strip()
        
        if value:
            if action == 'delete':
                # Delete individual tags is not in viper yet
                pass
            elif action == 'search':
                # This will search all projects
                # Get project list
                projects = project_list()
                # Add Main db to list.
                projects.append('../')
                # Search All projects
                p_list = []
                results = {}
                for project in projects:
                    __project__.open(project)
                    # Init DB
                    db = Database()
                    #get results
                    proj_results = []
                    rows = db.find(key='tag', value=value)
                    for row in rows:
                        if project == '../':
                            project = 'Main'
                        proj_results.append([row.name, row.sha256])
                    results[project] = proj_results
                    p_list.append(project)
                # Return the search template
                return template('search.tpl', projects=p_list, results=results)
            else:
                return template('error.tpl', error="'{0}' Is not a valid tag action".format(action))
                             
    # Add New Tags
    if request.method == 'POST':
        file_hash = request.forms.get('sha256')
        project = request.forms.get('project')
        if file_hash and project:
            tags = request.forms.get('tags')
            db.add_tags(file_hash, tags)
            redirect('/file/{0}/{1}'.format(project, file_hash))
Exemple #30
0
    def run(self, *args):
        try:
            args = self.parser.parse_args(args)
        except SystemExit:
            return

        if __sessions__.is_set():
            if not __sessions__.current.file.id:
                self.log(
                    'error',
                    "The opened file does not have an ID, have you stored it yet?"
                )
                return

            self.log(
                'info', "Current name is: {}".format(
                    bold(__sessions__.current.file.name)))

            new_name = input("New name: ")
            if not new_name:
                self.log('error', "File name can't  be empty!")
                return

            Database().rename(__sessions__.current.file.id, new_name)

            self.log('info', "Refreshing session to update attributes...")
            __sessions__.new(__sessions__.current.file.path)
        else:
            self.log(
                'error',
                "No open session. This command expects a file to be open.")
Exemple #31
0
    def new(self, path):
        session = Session()

        total = len(self.sessions)
        session.id = total + 1

        # Open a section on the given file.
        session.file = File(path)

        # Try to lookup the file in the database. If it is already present
        # we get file name and 
        row = Database().find(key='sha256', value=session.file.sha256)
        if row:
            session.file.name = row[0].name
            session.file.tags = ', '.join(tag.to_dict()['tag'] for tag in row[0].tag)

        # Loop through all existing sessions and check whether there's another
        # session open on the same file and delete it. This is to avoid
        # duplicates in sessions.
        # NOTE: in the future we might want to remove this if sessions have
        # unique attributes (for example, an history just for each of them).
        for entry in self.sessions:
            if entry.file.sha256 == session.file.sha256:
                self.sessions.remove(entry)

        # Add new session to the list.
        self.sessions.append(session)
        # Mark the new session as the current one.
        self.current = session

        print_info("Session opened on {0}".format(path))
Exemple #32
0
def module_cmdline(project=None, cmd_line=None, file_hash=None):
    html = ""
    cmd = Commands()
    split_commands = cmd_line.split(';')
    for split_command in split_commands:
        split_command = split_command.strip()
        if not split_command:
            continue
        root, args = parse(split_command)
        try:
            if root in cmd.commands:
                cmd.commands[root]['obj'](*args)
                html += print_output(cmd.output)
                del (cmd.output[:])
            elif root in __modules__:
                # if prev commands did not open a session open one on the current file
                if file_hash:
                    __project__.open(project)
                    path = get_sample_path(file_hash)
                    __sessions__.new(path)
                module = __modules__[root]['obj']()
                module.set_commandline(args)
                module.run()

                html += print_output(module.output)
                if cfg.modules.store_output and __sessions__.is_set():
                    Database().add_analysis(file_hash, split_command, module.output)
                del (module.output[:])
            else:
                html += '<p class="text-danger">{0} is not a valid command</p>'.format(cmd_line)
        except Exception:
            html += '<p class="text-danger">We were unable to complete the command {0}</p>'.format(cmd_line)
    __sessions__.close()
    return html
Exemple #33
0
    def __init__(self):
        # Open connection to the database.
        self.db = Database()

        # Map commands to their related functions.
        self.commands = dict(
            help=dict(obj=self.cmd_help, description="Show this help message"),
            open=dict(obj=self.cmd_open, description="Open a file"),
            new=dict(obj=self.cmd_new, description="Create new file"),
            close=dict(obj=self.cmd_close, description="Close the current session"),
            info=dict(obj=self.cmd_info, description="Show information on the opened file"),
            notes=dict(obj=self.cmd_notes, description="View, add and edit notes on the opened file"),
            clear=dict(obj=self.cmd_clear, description="Clear the console"),
            store=dict(obj=self.cmd_store, description="Store the opened file to the local repository"),
            delete=dict(obj=self.cmd_delete, description="Delete the opened file"),
            find=dict(obj=self.cmd_find, description="Find a file"),
            tags=dict(obj=self.cmd_tags, description="Modify tags of the opened file"),
            sessions=dict(obj=self.cmd_sessions, description="List or switch sessions"),
            stats=dict(obj=self.cmd_stats, description="Viper Collection Statistics"),
            projects=dict(obj=self.cmd_projects, description="List or switch existing projects"),
            parent=dict(obj=self.cmd_parent, description="Add or remove a parent file"),
            export=dict(obj=self.cmd_export, description="Export the current session to file or zip"),
            analysis=dict(obj=self.cmd_analysis, description="View the stored analysis"),
            rename=dict(obj=self.cmd_rename, description="Rename the file in the database"),
        )
Exemple #34
0
    def post(self, request, *args, **kwargs):
        # Get the project and hash of the file we want to run a command against
        project = kwargs.get('project', 'default')
        file_hash = request.POST.get('file_hash')

        if len(file_hash) != 64:
            file_hash = False
        # Lot of logic here to decide what command you entered.
        module_name = request.POST.get('module')
        print("Here: {}".format(module_name))
        if module_name == "module":
            return HttpResponse("<pre>Error: No Module selected!</pre>")
        module_args = request.POST.get('args')
        cmd_line = request.POST.get('cmdline')
        module_history = request.POST.get('moduleHistory', ' ')
        cmd_string = ''
        # Order of precedence
        # moduleHistory, cmd_line, module_name

        if module_history != ' ':
            result = Database().get_analysis(module_history)
            module_results = print_output(json.loads(result.results))
            html = '<p class="text-success">Result for "{0}" stored on {1}</p>'.format(result.cmd_line, result.stored_at)
            html += str(parse_text(module_results))
            return HttpResponse('<pre>{0}</pre>'.format(html))
        if cmd_line:
            cmd_string = cmd_line
        elif module_args:
            cmd_string = '{0} {1}'.format(module_name, mod_dict[module_name][module_args])
        module_results = module_cmdline(project=project, file_hash=file_hash, cmd_line=cmd_string)
        return HttpResponse('<pre>{0}</pre>'.format(str(parse_text(module_results))))
Exemple #35
0
 def __init__(self):
     super(ClamAV, self).__init__()
     self.parser.add_argument(
         '-s',
         '--socket',
         help='Specify an unix socket (default: Clamd Unix Socket)')
     self.parser.add_argument('-a',
                              '--all',
                              action='store_true',
                              help='Scan all files')
     self.parser.add_argument(
         '-t',
         '--tag',
         action='store_true',
         help='Tag file(s) with the signature name when detect as malware')
     self.db = Database()
Exemple #36
0
def autorun_module(file_hash):
    if not file_hash:
        return
    # We need an open session
    if not __sessions__.is_set():
        # Open session
        __sessions__.new(get_sample_path(file_hash))
    for cmd_line in cfg.autorun.commands.split(','):
        split_commands = cmd_line.split(';')
        for split_command in split_commands:
            split_command = split_command.strip()
            if not split_command:
                continue
            root, args = parse(split_command)
            try:
                if root in __modules__:
                    module = __modules__[root]['obj']()
                    module.set_commandline(args)
                    module.run()
                    print_info("Running Command {0}".format(split_command))
                    if cfg.modules.store_output and __sessions__.is_set():
                        Database().add_analysis(file_hash, split_command,
                                                module.output)
                    if cfg.autorun.verbose:
                        print_output(module.output)
                    del (module.output[:])
                else:
                    print_error(
                        '{0} is not a valid command. Please check your viper.conf file.'
                        .format(cmd_line))
            except:
                print_error(
                    'Viper was unable to complete the command {0}'.format(
                        cmd_line))
    return
Exemple #37
0
def tags(tag_action=False):
    # Set DB
    db = Database()

    # Search or Delete
    if request.method == 'GET':
        action = request.query.action
        value = request.query.value.strip()

        if value:
            if action == 'search':
                # This will search all projects
                # Get project list
                projects = project_list()
                # Add Main db to list.
                projects.append('../')
                # Search All projects
                p_list = []
                results = {}
                for project in projects:
                    __project__.open(project)
                    # Init DB
                    db = Database()
                    #get results
                    proj_results = []
                    rows = db.find(key='tag', value=value)
                    for row in rows:
                        if project == '../':
                            project = 'Main'
                        proj_results.append([row.name, row.sha256])
                    results[project] = proj_results
                    p_list.append(project)
                # Return the search template
                return template('search.tpl', projects=p_list, results=results)
            else:
                return template(
                    'error.tpl',
                    error="'{0}' Is not a valid tag action".format(action))

    # Add / Delete
    if request.method == 'POST':
        file_hash = request.forms.get('sha256')
        project = request.forms.get('project')
        tag_name = request.forms.get('tag')
        if tag_action == 'add':
            if file_hash and project:
                tags = request.forms.get('tags')
                db.add_tags(file_hash, tags)
        if tag_action == 'del':
            if file_hash and tag_name:
                db.delete_tag(tag_name, file_hash)
        redirect('/file/{0}/{1}'.format(project, file_hash))
Exemple #38
0
def add_file():
    tags = request.forms.get('tag_list')
    upload = request.files.get('file')

    # Set Project
    project = request.forms.get('project')
    if project in project_list():
        __project__.open(project)
    else:
        __project__.open('../')
        project = 'Main'
    db = Database()    

    # Write temp file to disk
    with upload_temp() as temp_dir:
        file_path = os.path.join(temp_dir, upload.filename)
        with open(file_path, 'w') as tmp_file:
            tmp_file.write(upload.file.read())
        file_list = []
        # Zip Files
        if request.forms.get('unzip'):
            zip_pass = request.forms.get('zip_pass')
            try:
                with ZipFile(file_path) as zf:
                    zf.extractall(temp_dir, pwd=zip_pass)            
                for root, dirs, files in os.walk(temp_dir, topdown=False):
                    for name in files:
                        if not name == upload.filename:
                            file_list.append(os.path.join(root, name))
            except Exception as e:
                return template('error.tpl', error="Error with zipfile - {0}".format(e))
        # Non zip files
        else:
            file_list.append(file_path)
        
        # Add each file
        for new_file in file_list:
            obj = File(new_file)
            new_path = store_sample(obj)
            success = False
            if new_path:
                # Add file to the database.
                success = db.add(obj=obj, tags=tags)
    if success:
        redirect("/project/{0}".format(project))
    else:
        return template('error.tpl', error="Unable to Store The File")
Exemple #39
0
    def cmd_analysis(self, *args):
        parser = argparse.ArgumentParser(prog="analysis", description="Show stored module results")
        group = parser.add_mutually_exclusive_group()
        group.add_argument('-l', '--list', action='store_true',
                           help="List all module results available for the current file")
        group.add_argument('-v', '--view', metavar='ANALYSIS ID', type=int, help="View the specified analysis")
        group.add_argument('-d', '--delete', metavar='ANALYSIS ID', type=int, help="Delete an existing analysis")

        try:
            args = parser.parse_args(args)
        except:
            return

        if not __sessions__.is_set():
            self.log('error', "No open session")
            return

        # check if the file is already stores, otherwise exit
        malware = Database().find(key='sha256', value=__sessions__.current.file.sha256)
        if not malware:
            self.log('error', "The opened file doesn't appear to be in the database, have you stored it yet?")
            return

        if args.list:
            # Retrieve all analysis for the currently opened file.

            analysis_list = malware[0].analysis
            if not analysis_list:
                self.log('info', "No analysis available for this file yet")
                return

            # Populate table rows.
            rows = [[analysis.id, analysis.cmd_line, analysis.stored_at] for analysis in analysis_list]

            # Display list of existing results.
            self.log('table', dict(header=['ID', 'Cmd Line', 'Saved On'], rows=rows))

        elif args.view:
            # Retrieve analysis wth the specified ID and print it.
            result = Database().get_analysis(args.view)
            if result:
                self.log('info', bold('Cmd Line: ') + result.cmd_line)
                for line in json.loads(result.results):
                    self.log(line['type'], line['data'])
            else:
                self.log('info', "There is no analysis with ID {0}".format(args.view))
Exemple #40
0
    def cmd_tags(self, *args):
        parser = argparse.ArgumentParser(prog="tags", description="Modify tags of the opened file")
        parser.add_argument('-a', '--add', help="Add tags to the opened file (comma separated)")
        parser.add_argument('-d', '--delete', help="Delete a tag from the opened file")
        try:
            args = parser.parse_args(args)
        except:
            return

        # This command requires a session to be opened.
        if not __sessions__.is_set():
            self.log("error", "No session opened")
            parser.print_usage()
            return

        # If no arguments are specified, there's not much to do.
        # However, it could make sense to also retrieve a list of existing
        # tags from this command, and not just from the "find" command alone.
        if args.add is None and args.delete is None:
            parser.print_usage()
            return

        # TODO: handle situation where addition or deletion of a tag fail.

        if args.add:
            # Add specified tags to the database's entry belonging to
            # the opened file.
            db = Database()
            db.add_tags(__sessions__.current.file.sha256, args.add)
            self.log("info", "Tags added to the currently opened file")

            # We refresh the opened session to update the attributes.
            # Namely, the list of tags returned by the "info" command
            # needs to be re-generated, or it wouldn't show the new tags
            # until the existing session is closed a new one is opened.
            self.log("info", "Refreshing session to update attributes...")
            __sessions__.new(__sessions__.current.file.path)

        if args.delete:
            # Delete the tag from the database.
            Database().delete_tag(args.delete)
            # Refresh the session so that the attributes of the file are
            # updated.
            self.log("info", "Refreshing session to update attributes...")
            __sessions__.new(__sessions__.current.file.path)
Exemple #41
0
 def parse_message(self, message_folder):
     db = Database()
     email_header = os.path.join(message_folder, 'InternetHeaders.txt')
     email_body = os.path.join(message_folder, 'Message.txt')
     
     envelope = headers = email_text = ''
     if os.path.exists(email_header):
         envelope, headers = self.email_headers(email_header)
     if os.path.exists(email_body):
         email_text = open(email_body, 'rb').read()
     
     tags = 'pst, {0}'.format(message_folder)
     if os.path.exists(os.path.join(message_folder, 'Attachments')):
         for filename in os.listdir(os.path.join(message_folder, 'Attachments')):
             if os.path.isfile(os.path.join(message_folder, 'Attachments', filename)):
                 obj = File(os.path.join(message_folder, 'Attachments', filename))
                 sha256 = hashlib.sha256(open(os.path.join(message_folder, 'Attachments', filename), 'rb').read()).hexdigest()
                 new_path = store_sample(obj)
                 if new_path:
                     # Add file to the database.
                     db.add(obj=obj, tags=tags)
                 # Add Email Details as a Note
                 # To handle duplicates we use multiple notes
                 headers_body = 'Envelope: \n{0}\nHeaders: \n{1}\n'.format(envelope, headers)
                 db.add_note(sha256, 'Headers', headers_body)
                 
                 # Add a note with email body
                 db.add_note(sha256, 'Email Body', string_clean(email_text))
Exemple #42
0
 def _search_local_hashes(self, event, open_session=True):
     local = []
     samples_count = 0
     if event.get('Event') is None:
         self.log('error', event)
         return
     for a in event['Event']['Attribute']:
         row = None
         if a['type'] == 'malware-sample':
             samples_count += 1
         if a['type'] in ('malware-sample', 'filename|md5', 'md5'):
             h = a['value']
             if '|' in a['type']:
                 h = a['value'].split('|')[1]
             row = Database().find(key='md5', value=h)
         elif a['type'] in ('sha1', 'filename|sha1'):
             h = a['value']
             if '|' in a['type']:
                 h = a['value'].split('|')[1]
             row = Database().find(key='sha1', value=h)
         elif a['type'] in ('sha256', 'filename|sha256'):
             h = a['value']
             if '|' in a['type']:
                 h = a['value'].split('|')[1]
             row = Database().find(key='sha256', value=h)
         if row:
             local.append(row[0])
     self.log(
         'info',
         'Event {} contains {} samples.'.format(event['Event']['id'],
                                                samples_count))
     if not open_session:
         return
     shas = set([l.sha256 for l in local])
     if len(shas) == 1:
         __sessions__.new(get_sample_path(shas.pop()), MispEvent(event))
     elif len(shas) > 1:
         self.log('success',
                  'The following samples are in this viper instance:')
         __sessions__.new(misp_event=MispEvent(event))
         for s in shas:
             self.log('item', s)
     else:
         __sessions__.new(misp_event=MispEvent(event))
         self.log('info', 'No known (in Viper) samples in that event.')
Exemple #43
0
 def test_notes_existing(self, capsys):
     self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe"))
     Database().add_note(__sessions__.current.file.sha256, 'Note test', 'This is the content')
     self.cmd['notes']['obj']('-l')
     self.cmd['notes']['obj']('-v', '1')
     self.cmd['notes']['obj']('-d', '1')
     out, err = capsys.readouterr()
     assert re.search(".*1  | Note test.*", out)
     assert re.search(".*This is the content.*", out)
Exemple #44
0
def add_tags():
    tags = request.forms.get('tags')
    for entry in ['md5', 'sha256', 'ssdeep', 'tag', 'name', 'all']:
        value = request.forms.get(entry)
        if value:
            key = entry
            break
    db = Database()
    rows = db.find(key=key, value=value)
    
    if not rows:
        raise HTTPError(404, 'File not found in the database')
          
    for row in rows:
        malware_sha256=row.sha256
        db.add_tags(malware_sha256, tags)

    return jsonize({'message' : 'added'})
Exemple #45
0
def add_tags():
    tags = request.forms.get('tags')
    for entry in ['md5', 'sha256', 'ssdeep', 'tag', 'name', 'all']:
        value = request.forms.get(entry)
        if value:
            key = entry
            break
    db = Database()
    rows = db.find(key=key, value=value)

    if not rows:
        raise HTTPError(404, 'File not found in the database')

    for row in rows:
        malware_sha256 = row.sha256
        db.add_tags(malware_sha256, tags)

    return jsonize({'message': 'added'})
Exemple #46
0
    def new(self, path=None, misp_event=None):
        if path is None and misp_event is None:
            print_error(
                "You have to open a session on a path or on a misp event.")
            return

        session = Session()

        total = len(self.sessions)
        session.id = total + 1

        if path is not None:
            if self.is_set() and self.current.misp_event:
                session.misp_event = self.current.misp_event

            # Open a section on the given file.
            session.file = File(path)
            # Try to lookup the file in the database. If it is already present
            # we get file name and
            row = Database().find(key='sha256', value=session.file.sha256)
            if row:
                session.file.name = row[0].name
                session.file.tags = ', '.join(tag.to_dict()['tag']
                                              for tag in row[0].tag)
            print_info("Session opened on {0}".format(path))
        if misp_event is not None:
            if self.is_set() and self.current.file:
                session.file = self.current.file
            refresh = False
            if self.current is not None and self.current.misp_event is not None \
                    and self.current.misp_event.event_id == misp_event.event_id:
                refresh = True
            session.misp_event = misp_event
            if refresh:
                print_info("Session on MISP event {0} refreshed.".format(
                    misp_event.event_id))
            else:
                print_info("Session opened on MISP event {0}.".format(
                    misp_event.event_id))

        if session.file is not None:
            # Loop through all existing sessions and check whether there's another
            # session open on the same file and delete it. This is to avoid
            # duplicates in sessions.
            # NOTE: in the future we might want to remove this if sessions have
            # unique attributes (for example, an history just for each of them).
            for entry in self.sessions:
                if entry.file is not None and entry.file.sha256 == session.file.sha256:
                    self.sessions.remove(entry)

        # Add new session to the list.
        self.sessions.append(session)
        # Mark the new session as the current one.
        self.current = session
Exemple #47
0
def add_file(file_path, tags, parent):
    obj = File(file_path)
    new_path = store_sample(obj)
    print new_path
    success = True
    if new_path:
        # Add file to the database.
        db = Database()
        success = db.add(obj=obj, tags=tags, parent_sha=parent)

        # AutoRun Modules
        if cfg.autorun.enabled:
            autorun_module(obj.sha256)
            # Close the open session to keep the session table clean
            __sessions__.close()
        return obj.sha256

    else:
        # ToDo Remove the stored file if we cant write to DB
        return
Exemple #48
0
    def run(self):
        super(Template, self).run()

        if self.args is None:
            return

        # Check arguments and scan accordingly
        if self.args.all:
            db = Database()
            samples = db.find(key='all')
            for sample in samples:
                self.scan(get_sample_path(sample.sha256))
            if self.args.emails:
                self.log('success', "Found emails: ")
                self.log('success', str(set(self.emails)))

        elif __sessions__.is_set():
            self.scan(__sessions__.current.file.path)
        else:
            self.usage()
Exemple #49
0
 def test_notes_existing(self, capsys):
     commands.Open().run(
         '-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe"))
     Database().add_note(commands.__sessions__.current.file.sha256,
                         'Note test', 'This is the content')
     commands.Notes().run('-l')
     commands.Notes().run('-v', '1')
     commands.Notes().run('-d', '1')
     out, err = capsys.readouterr()
     assert re.search(".*1  | Note test.*", out)
     assert re.search(".*This is the content.*", out)
Exemple #50
0
    def run(self):
        super(Fuzzy, self).run()

        if not __sessions__.is_set():
            self.log('error', "No session opened")
            return

        if not HAVE_PYDEEP:
            self.log('error', "Missing dependency, install pydeep (`pip install pydeep`)")
            return

        if not __sessions__.current.file.ssdeep:
            self.log('error', "No ssdeep hash available for opened file")
            return

        arg_verbose = False
        if self.args and self.args.verbose:
            arg_verbose = True

        db = Database()
        samples = db.find(key='all')

        matches = []
        for sample in samples:
            if sample.sha256 == __sessions__.current.file.sha256:
                continue

            if not sample.ssdeep:
                continue

            score = pydeep.compare(__sessions__.current.file.ssdeep, sample.ssdeep)
            if score > 40:
                matches.append(['{0}%'.format(score), sample.name, sample.sha256])

            if arg_verbose:
                self.log('info', "Match {0}%: {2} [{1}]".format(score, sample.name, sample.sha256))

        self.log('info', "{0} relevant matches found".format(bold(len(matches))))

        if len(matches) > 0:
            self.log('table', dict(header=['Score', 'Name', 'SHA256'], rows=matches))
Exemple #51
0
    def cmd_parent(self, *args):
        parser = argparse.ArgumentParser(prog='tags', description="Set the Parent for this file.")
        parser.add_argument('-a', '--add', metavar='SHA256', help="Add parent file by sha256")
        parser.add_argument('-d', '--delete', action='store_true', help="Delete Parent")
        parser.add_argument('-o', '--open', action='store_true', help="Open The Parent")
        try:
            args = parser.parse_args(args)
        except:
            return

        # This command requires a session to be opened.
        if not __sessions__.is_set():
            self.log('error', "No open session")
            parser.print_usage()
            return


        # If no arguments are specified, there's not much to do.
        if args.add is None and args.delete is None and args.open is None:
            parser.print_usage()
            return

        db = Database()
        if not db.find(key='sha256', value=__sessions__.current.file.sha256):
            self.log('error', "The opened file is not stored in the database. "
                              "If you want to add it use the `store` command.")
            return

        if args.add:
            if not db.find(key='sha256', value=args.add):
                self.log('error', "the parent file is not found in the database. ")
                return
            db.add_parent(__sessions__.current.file.sha256, args.add)
            self.log('info', "parent added to the currently opened file")

            self.log('info', "Refreshing session to update attributes...")
            __sessions__.new(__sessions__.current.file.path)

        if args.delete:
            db.delete_parent(__sessions__.current.file.sha256)
            self.log('info', "parent removed from the currently opened file")

            self.log('info', "Refreshing session to update attributes...")
            __sessions__.new(__sessions__.current.file.path)

        if args.open:
            # Open a session on the parent
            if __sessions__.current.file.parent:
                __sessions__.new(get_sample_path(__sessions__.current.file.parent[-64:]))
            else:
                self.log('info', "No parent set for this sample")
Exemple #52
0
    def run(self, *args):
        try:
            args = self.parser.parse_args(args)
        except SystemExit:
            return

        while True:
            choice = input("Are you sure? It can't be reverted! [y/n] ")
            if choice == 'y':
                break
            elif choice == 'n':
                return

        db = Database()

        if args.all:
            if __sessions__.is_set():
                __sessions__.close()

            samples = db.find('all')
            for sample in samples:
                db.delete_file(sample.id)
                os.remove(get_sample_path(sample.sha256))

            self.log('info', "Deleted a total of {} files.".format(len(samples)))
        elif args.find:
            if __sessions__.find:
                samples = __sessions__.find
                for sample in samples:
                    db.delete_file(sample.id)
                    os.remove(get_sample_path(sample.sha256))
                self.log('info', "Deleted {} files.".format(len(samples)))
            else:
                self.log('error', "No find result")

        else:
            if __sessions__.is_set():
                rows = db.find('sha256', __sessions__.current.file.sha256)
                if rows:
                    malware_id = rows[0].id
                    if db.delete_file(malware_id):
                        self.log("success", "File deleted")
                    else:
                        self.log('error', "Unable to delete file")

                os.remove(__sessions__.current.file.path)
                __sessions__.close()

                self.log('info', "Deleted opened file.")
            else:
                self.log('error', "No session open, and no --all argument. Nothing to delete.")
Exemple #53
0
    def run(self, *args):
        try:
            args = self.parser.parse_args(args)
        except SystemExit:
            return

        if not __sessions__.is_set():
            self.log('error', "No open session. This command expects a file to be open.")
            return

        db = Database()

        # check if the file is already stores, otherwise exit
        malware = db.find(key='sha256', value=__sessions__.current.file.sha256)
        if not malware:
            self.log('error', "The opened file doesn't appear to be in the database, have you stored it yet?")
            return

        if args.list:
            # Retrieve all analysis for the currently opened file.

            analysis_list = malware[0].analysis
            if not analysis_list:
                self.log('info', "No analysis available for this file yet")
                return

            # Populate table rows.
            rows = [[analysis.id, analysis.cmd_line, analysis.stored_at] for analysis in analysis_list]

            # Display list of existing results.
            self.log('table', dict(header=['ID', 'Cmd Line', 'Saved On (UTC)'], rows=rows))

        elif args.view:
            # Retrieve analysis wth the specified ID and print it.
            result = db.get_analysis(args.view)
            if result:
                self.log('info', bold('Cmd Line: ') + result.cmd_line)
                for line in json.loads(result.results):
                    self.log(line['type'], line['data'])
            else:
                self.log('info', "There is no analysis with ID {0}".format(args.view))
Exemple #54
0
    def __init__(self):
        # Open connection to the database.
        self.db = Database()

        # Map commands to their related functions.
        self.commands = dict(
            help=dict(obj=self.cmd_help, description="Show this help message"),
            open=dict(obj=self.cmd_open, description="Open a file"),
            new=dict(obj=self.cmd_new, description="Create new file"),
            close=dict(obj=self.cmd_close,
                       description="Close the current session"),
            info=dict(obj=self.cmd_info,
                      description="Show information on the opened file"),
            notes=dict(
                obj=self.cmd_notes,
                description="View, add and edit notes on the opened file"),
            clear=dict(obj=self.cmd_clear, description="Clear the console"),
            store=dict(
                obj=self.cmd_store,
                description="Store the opened file to the local repository"),
            delete=dict(obj=self.cmd_delete,
                        description="Delete the opened file"),
            find=dict(obj=self.cmd_find, description="Find a file"),
            tags=dict(obj=self.cmd_tags,
                      description="Modify tags of the opened file"),
            sessions=dict(obj=self.cmd_sessions,
                          description="List or switch sessions"),
            stats=dict(obj=self.cmd_stats,
                       description="Viper Collection Statistics"),
            projects=dict(obj=self.cmd_projects,
                          description="List or switch existing projects"),
            parent=dict(obj=self.cmd_parent,
                        description="Add or remove a parent file"),
            export=dict(
                obj=self.cmd_export,
                description="Export the current session to file or zip"),
            analysis=dict(obj=self.cmd_analysis,
                          description="View the stored analysis"),
            rename=dict(obj=self.cmd_rename,
                        description="Rename the file in the database"),
        )
Exemple #55
0
def logo():
    print("""         _                   
        (_) 
   _   _ _ ____  _____  ____ 
  | | | | |  _ \| ___ |/ ___)
   \ V /| | |_| | ____| |    
    \_/ |_|  __/|_____)_| v1.2
          |_|
    """)

    db = Database()
    count = db.get_sample_count()

    if __project__.name:
        name = __project__.name
    else:
        name = 'default'

    print(magenta("You have " + bold(count)) + 
          magenta(" files in your " + bold(name) + 
          magenta(" repository".format(bold(name)))))
Exemple #56
0
    def size_all(self):
        db = Database()
        samples = db.find(key='all')

        rows = []
        for sample in samples:
            sample_path = get_sample_path(sample.sha256)
            if not os.path.exists(sample_path):
                continue

            try:
                cur_size = os.path.getsize(sample_path)
            except Exception as e:
                self.log('error', "Error {0} for sample {1}".format(e, sample.sha256))
                continue

            rows.append([sample.md5, sample.name, cur_size])

        self.log('table', dict(header=['MD5', 'Name', 'Size (B)'], rows=rows))

        return
Exemple #57
0
    def edit(self):
        db = Database()
        samples = db.find(key='all')

        filenames = []
        for sample in samples:
            if sample.sha256 == __sessions__.current.file.sha256:
                continue

            filenames.append(sample.name)

        
        # from http://hetland.org/coding/python/levenshtein.py
        def levenshtein(a, b):
            "Calculates the Levenshtein distance between a and b."
            n, m = len(a), len(b)
            if n > m:
                # Make sure n <= m, to use O(min(n,m)) space
                a,b = b,a
                n,m = m,n

            current = range(n+1)
            for i in range(1,m+1):
                previous, current = current, [i]+[0]*n
                for j in range(1,n+1):
                    add, delete = previous[j]+1, current[j-1]+1
                    change = previous[j-1]
                    if a[j-1] != b[i-1]:
                        change = change + 1
                    current[j] = min(add, delete, change)

            return current[n]

        distance = []
        for i in itertools.combinations(filenames, 2): 
            edit = levenshtein(i[0], i[1])
            distance.append(edit)
 
        print_info("Average Edit distance: {0}".format(sum(distance)/len(distance))) 
Exemple #58
0
def landing(p=False):
    contents = {}
    if p in project_list():
        __project__.open(p)
        contents['p'] = p
    else:
        __project__.open("../")
        contents['p'] = 'Main'
    db = Database() 
    # Pagination
    # 25 per page
    value = 25
    offset = 0
    contents['count'] = db.get_sample_count()
    page = request.query.page
    if not page:
        page = 0
    offset = int(page) * int(value) 
    contents['act_page'] = page   
    contents['latest'] = db.find('latest', value=value, offset=offset)
    # return the Template
    return template('index.tpl', **contents)