Example #1
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')
Example #2
0
    def cmd_delete(self, *args):
        parser = argparse.ArgumentParser(prog='delete', description="Delete a file")
        parser.add_argument('-a', '--all', action='store_true', help="Delete ALL files in this project")
        parser.add_argument('-f', '--find', action="store_true", help="Delete ALL files from last find")

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

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

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

            samples = self.db.find('all')
            for sample in samples:
                self.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:
                    self.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 = self.db.find('sha256', __sessions__.current.file.sha256)
                if rows:
                    malware_id = rows[0].id
                    if self.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.")
Example #3
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.")
Example #4
0
    def destroy(self, request, project=None, db=None, *args, **kwargs):
        """Delete a Malware instance"""

        instance = self.get_object()

        try:
            log.debug("deleting (os.remove) Malware sample at path: {}".format(get_sample_path(instance.sha256)))
            os.remove(get_sample_path(instance.sha256))
        except OSError:
            log.error("failed to delete Malware sample: {}".format(get_sample_path(instance.sha256)))

        log.debug("deleting (db.delete_file) from DB for Malware ID: {}".format(instance.id))
        db.delete_file(instance.id)

        return Response(status=status.HTTP_204_NO_CONTENT)
Example #5
0
def run_module():
    project = request.forms.get('project')
    if project:
        __project__.open(project)

    sha256 = request.forms.get('sha256')
    if sha256:
        file_path = get_sample_path(sha256)
        if file_path:
            __sessions__.new(file_path)

    module_name = request.forms.get('module')
    if module_name in __modules__:
        module = __modules__[module_name]['obj']()
        module.run()

        module_output = copy.deepcopy(module.output)
        del (module.output[:])

        if module_output:
            return jsonize(
                dict(project=project,
                     module=module_name,
                     sha256=sha256,
                     output=module_output))
Example #6
0
def hex_viewer():
    # get post data
    file_hash = request.forms.get('file_hash')
    try:
        hex_offset = int(request.forms.get('hex_start'))
    except:
        return '<p class="text-danger">Error Generating Request</p>'
    hex_length = 256

    # get file path
    hex_path = get_sample_path(file_hash)

    # create the command string
    hex_cmd = 'hd -s {0} -n {1} {2}'.format(hex_offset, hex_length, hex_path)

    # get the output
    hex_string = getoutput(hex_cmd)

    # Format the data
    html_string = ''
    hex_rows = hex_string.split('\n')
    for row in hex_rows:
        if len(row) > 9:
            off_str = row[0:8]
            hex_str = row[9:58]
            asc_str = row[58:78]
            asc_str = asc_str.replace('"', '&quot;')
            asc_str = asc_str.replace('<', '&lt;')
            asc_str = asc_str.replace('>', '&gt;')
            html_string += '<div class="row"><span class="text-primary mono">{0}</span> <span class="text-muted mono">{1}</span> <span class="text-success mono">{2}</span></div>'.format(
                off_str, hex_str, asc_str)
    # return the data
    return html_string
Example #7
0
def file_download(file_hash, project=False):
    if project in project_list():
        __project__.open(project)
    else:
        __project__.open('default')
        project = 'default'
    # Open the Database
    db = Database()
    # Open a session
    rows = db.find(key='sha256', value=file_hash)
    if not rows:
        return template(
            'error.tpl',
            error="{0} Does not match any hash in the Database".format(
                file_hash))

    path = get_sample_path(rows[0].sha256)
    if not path:
        return template('error.tpl', error="File not found on disk")

    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
Example #8
0
        def add_file(obj, tags=None):
            if get_sample_path(obj.sha256):
                self.log('warning', "Skip, file \"{0}\" appears to be already stored".format(obj.name))
                return False

            if __sessions__.is_attached_misp(quiet=True):
                if tags is not None:
                    tags += ',misp:{}'.format(__sessions__.current.misp_event.event.id)
                else:
                    tags = 'misp:{}'.format(__sessions__.current.misp_event.event.id)

            # Try to store file object into database.
            status = db.add(obj=obj, tags=tags)
            if status:
                # If succeeds, store also in the local repository.
                # If something fails in the database (for example unicode strings)
                # we don't want to have the binary lying in the repository with no
                # associated database record.
                new_path = store_sample(obj)
                self.log("success", "Stored file \"{0}\" to {1}".format(obj.name, new_path))

            else:
                return False

            # Delete the file if requested to do so.
            if args.delete:
                try:
                    os.unlink(obj.path)
                except Exception as e:
                    self.log('warning', "Failed deleting file: {0}".format(e))

            return True
Example #9
0
 def get_files_from_last_find(self):
     files = []
     if __sessions__.find:
         for item in __sessions__.find:
             path = get_sample_path(item.sha256)
             files.append((path, item.name))
     return files
Example #10
0
def hex_view(request):
    # get post data
    file_hash = request.POST['file_hash']
    try:
        hex_offset = int(request.POST['hex_start'])
    except:
        return '<p class="text-danger">Error Generating Request</p>'
    hex_length = 256

    # get file path
    hex_path = get_sample_path(file_hash)

    # create the command string
    hex_cmd = 'hd -s {0} -n {1} {2}'.format(hex_offset, hex_length, hex_path)

    # get the output
    hex_string = getoutput(hex_cmd)
    # Format the data
    html_string = ''
    hex_rows = hex_string.split('\n')
    for row in hex_rows:
        if len(row) > 9:
            off_str = row[0:8]
            hex_str = row[9:58]
            asc_str = row[58:78]
            asc_str = asc_str.replace('"', '&quot;')
            asc_str = asc_str.replace('<', '&lt;')
            asc_str = asc_str.replace('>', '&gt;')
            html_string += '<div class="row"><span class="text-primary mono">{0}</span> \
                            <span class="text-muted mono">{1}</span> <span class="text-success mono"> \
                            {2}</span></div>'.format(off_str, hex_str, asc_str)
    # return the data
    return HttpResponse(html_string)
Example #11
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))
Example #12
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")
            return

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

        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
Example #13
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))
Example #14
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 or self.args.search_string):
            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_base(sample_path, xor_key=self.args.xor, rabin_extract=self.args.rabin2)
                self.process_strings(strings, sample.name)
        else:
            if not __sessions__.is_set():
                self.log('error', "No open session. This command expects a file to be open.")
                return
            if os.path.exists(__sessions__.current.file.path):
                strings = self.get_strings_base(__sessions__.current.file.path, xor_key=self.args.xor, rabin_extract=self.args.rabin2)
                self.process_strings(strings)
Example #15
0
def hex_viewer():
    # get post data
    file_hash = request.forms.get("file_hash")
    try:
        hex_offset = int(request.forms.get("hex_start"))
    except:
        return '<p class="text-danger">Error Generating Request</p>'
    hex_length = 256

    # get file path
    hex_path = get_sample_path(file_hash)

    # create the command string
    hex_cmd = "hd -s {0} -n {1} {2}".format(hex_offset, hex_length, hex_path)

    # get the output
    hex_string = getoutput(hex_cmd)

    # Format the data
    html_string = ""
    hex_rows = hex_string.split("\n")
    for row in hex_rows:
        if len(row) > 9:
            off_str = row[0:8]
            hex_str = row[9:58]
            asc_str = row[58:78]
            asc_str = asc_str.replace('"', "&quot;")
            asc_str = asc_str.replace("<", "&lt;")
            asc_str = asc_str.replace(">", "&gt;")
            html_string += '<div class="row"><span class="text-primary mono">{0}</span> <span class="text-muted mono">{1}</span> <span class="text-success mono">{2}</span></div>'.format(
                off_str, hex_str, asc_str
            )
    # return the data
    return html_string
Example #16
0
    def size_scan(self):
        db = Database()
        samples = db.find(key='all')

        rows = []
        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_size = os.path.getsize(sample_path)
            except Exception:
                continue

            if self.file_size == cur_size:
                rows.append([sample.md5, sample.name])

        if len(rows) > 0:
            self.log(
                'info', "Following are samples with size {0}".format(
                    bold(self.file_size)))
            self.log('table', dict(header=['MD5', 'Name'], rows=rows))
Example #17
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 
Example #18
0
File: api.py Project: blaquee/viper
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
Example #19
0
def module_cmdline(cmd_line, file_hash):
    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:
                    path = get_sample_path(file_hash)
                    __sessions__.new(path)
                module = __modules__[root]['obj']()
                module.set_commandline(args)
                module.run()

                html += print_output(module.output)
                del (module.output[:])
            else:
                html += '<p class="text-danger">{0} is not a valid command</p>'.format(
                    cmd_line)
        except:
            html += '<p class="text-danger">We were unable to complete the command {0}</p>'.format(
                cmd_line)
    __sessions__.close()
    return html
Example #20
0
    def post(self, request, *args, **kwargs):
        # Get the project and hash of the file
        project = kwargs.get('project', 'default')
        file_hash = request.POST.get('file_hash')
        try:
            hex_offset = int(request.POST.get('hex_start'))
        except Exception:
            return '<p class="text-danger">Error Generating Request</p>'
        hex_length = 256

        # get file path
        __project__.open(project)
        hex_path = get_sample_path(file_hash)

        # create the command string
        hex_cmd = 'hd -s {0} -n {1} {2}'.format(hex_offset, hex_length, hex_path)

        # get the output
        hex_string = getoutput(hex_cmd)
        # Format the data
        html_string = ''
        hex_rows = hex_string.split('\n')
        for row in hex_rows:
            if len(row) > 9:
                off_str = row[0:8]
                hex_str = row[9:58]
                asc_str = row[58:78]
                asc_str = asc_str.replace('"', '&quot;')
                asc_str = asc_str.replace('<', '&lt;')
                asc_str = asc_str.replace('>', '&gt;')
                html_string += '<div class="row"><span class="text-primary mono">{0}</span> \
                                <span class="text-muted mono">{1}</span> <span class="text-success mono"> \
                                {2}</span></div>'.format(off_str, hex_str, asc_str)
        # return the data
        return HttpResponse(html_string)
Example #21
0
        def add_file(obj, tags=None):
            if get_sample_path(obj.sha256):
                self.log("warning", 'Skip, file "{0}" appears to be already stored'.format(obj.name))
                return False

            # Try to store file object into database.
            status = self.db.add(obj=obj, tags=tags)
            if status:
                # If succeeds, store also in the local repository.
                # If something fails in the database (for example unicode strings)
                # we don't want to have the binary lying in the repository with no
                # associated database record.
                new_path = store_sample(obj)
                self.log("success", 'Stored file "{0}" to {1}'.format(obj.name, new_path))
            else:
                return False

            # Delete the file if requested to do so.
            if args.delete:
                try:
                    os.unlink(obj.path)
                except Exception as e:
                    self.log("warning", "Failed deleting file: {0}".format(e))

            return True
Example #22
0
def get_file(file_hash):
    key = ''
    if len(file_hash) == 32:
        key = 'md5'
    elif len(file_hash) == 64:
        key = 'sha256'
    else:
        response.code = 400
        return jsonize({'message':'Invalid hash format (use md5 or sha256)'})

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

    if not rows:
        response.code = 404
        return jsonize({'message':'File not found in the database'})

    path = get_sample_path(rows[0].sha256)
    if not path:
        response.code = 404
        return jsonize({'message':'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
Example #23
0
    def post(self, request, *args, **kwargs):
        # Get the project and hash of the file
        project = kwargs.get('project', 'default')
        file_hash = request.POST.get('file_hash')
        try:
            hex_offset = int(request.POST.get('hex_start'))
        except:
            return '<p class="text-danger">Error Generating Request</p>'
        hex_length = 256

        # get file path
        __project__.open(project)
        hex_path = get_sample_path(file_hash)

        # create the command string
        hex_cmd = 'hd -s {0} -n {1} {2}'.format(hex_offset, hex_length, hex_path)

        # get the output
        hex_string = getoutput(hex_cmd)
        # Format the data
        html_string = ''
        hex_rows = hex_string.split('\n')
        for row in hex_rows:
            if len(row) > 9:
                off_str = row[0:8]
                hex_str = row[9:58]
                asc_str = row[58:78]
                asc_str = asc_str.replace('"', '&quot;')
                asc_str = asc_str.replace('<', '&lt;')
                asc_str = asc_str.replace('>', '&gt;')
                html_string += '<div class="row"><span class="text-primary mono">{0}</span> \
                                <span class="text-muted mono">{1}</span> <span class="text-success mono"> \
                                {2}</span></div>'.format(off_str, hex_str, asc_str)
        # return the data
        return HttpResponse(html_string)
Example #24
0
        def add_file(obj, tags=None):
            if get_sample_path(obj.sha256):
                self.log('warning', "Skip, file \"{0}\" appears to be already stored".format(obj.name))
                return False

            # Try to store file object into database.
            status = self.db.add(obj=obj, tags=tags)
            if status:
                # If succeeds, store also in the local repository.
                # If something fails in the database (for example unicode strings)
                # we don't want to have the binary lying in the repository with no
                # associated database record.
                new_path = store_sample(obj)
                self.log("success", "Stored file \"{0}\" to {1}".format(obj.name, new_path))
            else:
                return False

            # Delete the file if requested to do so.
            if args.delete:
                try:
                    os.unlink(obj.path)
                except Exception as e:
                    self.log('warning', "Failed deleting file: {0}".format(e))

            return True
Example #25
0
def module_cmdline(cmd_line, file_hash):
    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:
                    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 as e:
            html += '<p class="text-danger">We were unable to complete the command {0}</p>'.format(cmd_line)
    __sessions__.close()
    return html
Example #26
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)
Example #27
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 {0} was calculated on files:".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")
Example #28
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))
Example #29
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)
Example #30
0
    def get(self, request, *args, **kwargs):
        template_name = "viperweb/file.html"

        # default to "default" project if none given
        project = kwargs.get('project', 'default')
        db = open_db(project)

        sha256 = kwargs.get('sha256')
        if not sha256:
            log.error("no sha256 hashed provided")
            raise Http404("no sha256 hashed provided")

        path = get_sample_path(sha256)
        if not path:
            raise Http404(
                "could not retrieve file for sha256 hash: {}".format(sha256))

        # Get additional details for file
        malware = db.find(key='sha256', value=sha256)
        try:
            malware_obj = malware[0]
        except IndexError:
            raise Http404(
                "could not find file for sha256 hash: {}".format(sha256))

        note_list = []
        notes = malware_obj.note
        if notes:
            for note in notes:
                note_list.append({
                    'title': note.title,
                    'body': note.body,
                    'id': note.id
                })

        module_history = []
        analysis_list = malware_obj.analysis
        if analysis_list:
            for item in analysis_list:
                module_history.append({
                    'id': item.id,
                    'cmd_line': item.cmd_line
                })

        tag_list = db.list_tags_for_malware(sha256)
        children = db.list_children(malware_obj.id)
        parent = db.get_parent(malware_obj.id)

        return render(
            request, template_name, {
                'malware': malware_obj,
                'note_list': note_list,
                'tag_list': tag_list,
                'children': children,
                'parent': parent,
                'module_history': module_history,
                'project': project,
                'projects': get_project_list()
            })
Example #31
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))
Example #32
0
def file_view(request, sha256=False, project='default'):
    if not sha256:
        return render(request, '404.html')
    print sha256
    db = open_db(project)
    # Open a session
    try:
        path = get_sample_path(sha256)
        __sessions__.new(path)
    except:
        return render(request, '404.html')

    # Get the file info
    file_info = {
        'name': __sessions__.current.file.name,
        'tags': __sessions__.current.file.tags.split(','),
        'path': __sessions__.current.file.path,
        'size': __sessions__.current.file.size,
        'type': __sessions__.current.file.type,
        'mime': __sessions__.current.file.mime,
        'md5': __sessions__.current.file.md5,
        'sha1': __sessions__.current.file.sha1,
        'sha256': __sessions__.current.file.sha256,
        'sha512': __sessions__.current.file.sha512,
        'ssdeep': __sessions__.current.file.ssdeep,
        'crc32': __sessions__.current.file.crc32,
        'parent': __sessions__.current.file.parent,
        'children': __sessions__.current.file.children.split(',')
    }

    # Get Any Notes
    note_list = []
    module_history = []
    malware = db.find(key='sha256', value=sha256)
    if malware:
        notes = malware[0].note
        if notes:
            for note in notes:
                note_list.append({'title': note.title,
                                  'body': note.body,
                                  'id': note.id
                                  })
        analysis_list = malware[0].analysis
        if analysis_list:
            for ana in analysis_list:
                module_history.append({'id': ana.id,
                                       'cmd_line': ana.cmd_line
                                       })

    # Return the page
    return render(request, 'file.html', {'file_info': file_info,
                                         'note_list': note_list,
                                         'error_line': False,
                                         'project': project,
                                         'projects': project_list(),
                                         'module_history': module_history
                                         })
Example #33
0
    def destroy(self, request, project=None, db=None, *args, **kwargs):
        """Delete a Malware instance"""

        instance = self.get_object()

        try:
            log.debug("deleting (os.remove) Malware sample at path: {}".format(
                get_sample_path(instance.sha256)))
            os.remove(get_sample_path(instance.sha256))
        except OSError:
            log.error("failed to delete Malware sample: {}".format(
                get_sample_path(instance.sha256)))

        log.debug(
            "deleting (db.delete_file) from DB for Malware ID: {}".format(
                instance.id))
        db.delete_file(instance.id)

        return Response(status=status.HTTP_204_NO_CONTENT)
Example #34
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")
Example #35
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))
Example #36
0
File: api.py Project: RATBORG/viper
def get_file(sha256):
    path = get_sample_path(sha256)
    if not path:
        raise HTTPError(404, 'File not found')

    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
Example #37
0
def file_view(request, sha256, project):
    if not sha256:
        return JsonResponse({'response': '404', 'data': 'Requires a SHA256'})
    db = open_db(project)
    # Open a session
    try:
        path = get_sample_path(sha256)
        __sessions__.new(path)
    except:
        return JsonResponse({'response': '404', 'data': 'Unabel to access file'})

    # Get the file info
    file_info = {
        'name': __sessions__.current.file.name,
        'tags': __sessions__.current.file.tags.split(','),
        'path': __sessions__.current.file.path,
        'size': __sessions__.current.file.size,
        'type': __sessions__.current.file.type,
        'mime': __sessions__.current.file.mime,
        'md5': __sessions__.current.file.md5,
        'sha1': __sessions__.current.file.sha1,
        'sha256': __sessions__.current.file.sha256,
        'sha512': __sessions__.current.file.sha512,
        'ssdeep': __sessions__.current.file.ssdeep,
        'crc32': __sessions__.current.file.crc32,
        'parent': __sessions__.current.file.parent,
        'children': __sessions__.current.file.children.split(',')
    }

    # Get Any Notes
    note_list = []
    module_history = []
    malware = db.find(key='sha256', value=sha256)
    if malware:
        notes = malware[0].note
        if notes:
            for note in notes:
                note_list.append({'title': note.title,
                                  'body': note.body,
                                  'id': note.id
                                  })
        analysis_list = malware[0].analysis
        if analysis_list:
            for ana in analysis_list:
                module_history.append({'id': ana.id,
                                       'cmd_line': ana.cmd_line
                                       })

    # Return the page
    return JsonResponse({'response': '200', 'data': {'file_info': file_info,
                                                     'note_list': note_list,
                                                     'module_history': module_history
                                                     }})
Example #38
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.')
Example #39
0
def delete_file(file_hash):
    success = False
    key = ''
    if len(file_hash) == 32:
        key = 'md5'
    elif len(file_hash) == 64:
        key = 'sha256'
    else:
        response.code = 400
        return jsonize({'message':'Invalid hash format (use md5 or sha256)'})

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

    if not rows:
        response.code = 404
        return jsonize({'message':'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:
            response.code = 404
            return jsonize({'message':'File not found in repository'})

    path = get_sample_path(rows[0].sha256)
    if not path:
        response.code = 404
        return jsonize({'message':'File not found in file system'})
    else:
        success=os.remove(path)
    
    if success:
        return jsonize({'message' : 'deleted'})
    else:
        response.code = 500
        return jsonize({'message':'Unable to delete file'})
Example #40
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")
Example #41
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")
Example #42
0
    def get(self, request, *args, **kwargs):
        project = kwargs.get("project", "default")
        if project not in get_project_list():
            raise Http404("unknown project: {}".format(project))

        sha256 = kwargs.get("sha256")
        if not sha256:
            log.error("no sha256 hashed provided")
            raise Http404("no sha256 hashed provided")

        # Open a session
        try:
            path = get_sample_path(sha256)
            __sessions__.new(path)
        except Exception as err:
            log.error("Error: {}".format(err))
            return HttpResponse('<span class="alert alert-danger">Invalid Submission</span>'.format())

        try:
            task_list_url = '{0}/tasks/list'.format(cfg.cuckoo.cuckoo_host)
            task_list_response = requests.get(task_list_url)
            if task_list_response.status_code == 200:
                task_list = task_list_response.json()
                task_list_filtered = [x for x in task_list["tasks"] if x["sample"]["sha256"] == sha256]
                if task_list_filtered:
                    task_list_filtered_sorted = sorted(task_list_filtered, key=itemgetter("added_on"), reverse=True)
                    task_id = task_list_filtered_sorted[0]["id"]
                    return HttpResponse('<a href="{0}/analysis/{1}/summary/" target="_blank"> Link to latest existing Cukoo Report</a>'.format(cfg.cuckoo.cuckoo_web, str(task_id)))
        except Exception as err:
            log.error("Error: {}".format(err))
            return HttpResponse('<span class="alert alert-danger">Error Connecting To Cuckoo</span>'.format())

        # If it doesn't exist, submit it.

        # Get the file data from viper
        file_data = open(__sessions__.current.file.path, 'rb').read()
        file_name = __sessions__.current.file.name

        if file_data:
            # Submit file data to cuckoo
            uri = '{0}{1}'.format(cfg.cuckoo.cuckoo_host, '/tasks/create/file')
            options = {'file': (file_name, file_data)}
            cuckoo_response = requests.post(uri, files=options)
            if cuckoo_response.status_code == 200:
                cuckoo_id = dict(cuckoo_response.json())['task_id']
                return HttpResponse('<a href="{0}/analysis/pending/" target="_blank"> Link To Cuckoo (pending tasks)</a>'.format(cfg.cuckoo.cuckoo_web, str(cuckoo_id)))
            else:
                log.error("Cuckoo Response Code: {}".format(cuckoo_response.status_code))

        return HttpResponse('<span class="alert alert-danger">Unable to Submit File</span>')
Example #43
0
    def get(self, request, *args, **kwargs):
        template_name = "viperweb/file.html"

        # default to "default" project if none given
        project = kwargs.get('project', 'default')
        db = open_db(project)

        sha256 = kwargs.get('sha256')
        if not sha256:
            log.error("no sha256 hashed provided")
            raise Http404("no sha256 hashed provided")

        path = get_sample_path(sha256)
        if not path:
            raise Http404("could not retrieve file for sha256 hash: {}".format(sha256))

        # Get additional details for file
        malware = db.find(key='sha256', value=sha256)
        try:
            malware_obj = malware[0]
        except IndexError:
            raise Http404("could not find file for sha256 hash: {}".format(sha256))

        note_list = []
        notes = malware_obj.note
        if notes:
            for note in notes:
                note_list.append({'title': note.title,
                                  'body': note.body,
                                  'id': note.id})

        module_history = []
        analysis_list = malware_obj.analysis
        if analysis_list:
            for item in analysis_list:
                module_history.append({'id': item.id,
                                       'cmd_line': item.cmd_line})

        tag_list = db.list_tags_for_malware(sha256)
        children = db.list_children(malware_obj.id)
        parent = db.get_parent(malware_obj.id)

        return render(request, template_name, {'malware': malware_obj,
                                               'note_list': note_list,
                                               'tag_list': tag_list,
                                               'children': children,
                                               'parent': parent,
                                               'module_history': module_history,
                                               'project': project,
                                               'projects': get_project_list()})
Example #44
0
    def get(self, request, *args, **kwargs):
        project = kwargs.get("project", "default")
        if project not in get_project_list():
            raise Http404("unknown project: {}".format(project))

        sha256 = kwargs.get("sha256")
        if not sha256:
            log.error("no sha256 hashed provided")
            raise Http404("no sha256 hashed provided")

        # Open a session
        try:
            path = get_sample_path(sha256)
            __sessions__.new(path)
        except Exception as err:
            log.error("Error: {}".format(err))
            return HttpResponse('<span class="alert alert-danger">Invalid Submission</span>'.format())

        try:
            task_list_url = '{0}/tasks/list'.format(cfg.cuckoo.cuckoo_host)
            task_list_response = requests.get(task_list_url)
            if task_list_response.status_code == 200:
                task_list = task_list_response.json()
                task_list_filtered = [x for x in task_list["tasks"] if x["sample"]["sha256"] == sha256]
                if task_list_filtered:
                    task_list_filtered_sorted = sorted(task_list_filtered, key=itemgetter("added_on"), reverse=True)
                    task_id = task_list_filtered_sorted[0]["id"]
                    return HttpResponse('<a href="{0}/analysis/{1}/summary/" target="_blank"> Link to latest existing Cukoo Report</a>'.format(cfg.cuckoo.cuckoo_web, str(task_id)))
        except Exception as err:
            log.error("Error: {}".format(err))
            return HttpResponse('<span class="alert alert-danger">Error Connecting To Cuckoo</span>'.format())

        # If it doesn't exist, submit it.

        # Get the file data from viper
        file_data = open(__sessions__.current.file.path, 'rb').read()
        file_name = __sessions__.current.file.name

        if file_data:
            # Submit file data to cuckoo
            uri = '{0}{1}'.format(cfg.cuckoo.cuckoo_host, '/tasks/create/file')
            options = {'file': (file_name, file_data)}
            cuckoo_response = requests.post(uri, files=options)
            if cuckoo_response.status_code == 200:
                cuckoo_id = dict(cuckoo_response.json())['task_id']
                return HttpResponse('<a href="{0}/analysis/pending/" target="_blank"> Link To Cuckoo (pending tasks)</a>'.format(cfg.cuckoo.cuckoo_web, str(cuckoo_id)))
            else:
                log.error("Cuckoo Response Code: {}".format(cuckoo_response.status_code))

        return HttpResponse('<span class="alert alert-danger">Unable to Submit File</span>')
Example #45
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))
Example #46
0
def cuckoo_submit():
    # Get Query Strings
    project = request.query.project
    file_hash = request.query.hash
    if project in project_list():
        __project__.open(project)
    else:
        __project__.open("../")
        project = "Main"
    # Open the Database
    db = Database()
    # Open a session
    try:
        path = get_sample_path(file_hash)
        __sessions__.new(path)
    except:
        return '<span class="alert alert-danger">Invalid Submission</span>'

    try:
        # Return URI For Existing Entry
        check_uri = "{0}/files/view/sha256/{1}".format(cuckoo_api, file_hash)
        check_file = requests.get(check_uri)
        if check_file.status_code == 200:
            check_result = dict(check_file.json())
            cuckoo_id = check_result["sample"]["id"]
            return '<a href="{0}/submit/status/{1}" target="_blank"> Link To Cukoo Report</a>'.format(
                cuckoo_web, str(cuckoo_id)
            )
    except Exception as e:
        return '<span class="alert alert-danger">Error Connecting To Cuckoo</span>'

    # If it doesn't exist, submit it.

    # Get the file data from viper
    file_data = open(__sessions__.current.file.path, "rb").read()
    file_name = __sessions__.current.file.name

    if file_data:
        # Submit file data to cuckoo
        uri = "{0}{1}".format(cuckoo_api, "/tasks/create/file")
        options = {"file": (file_name, file_data)}
        cuckoo_response = requests.post(uri, files=options)
        if cuckoo_response.status_code == 200:
            cuckoo_id = dict(cuckoo_response.json())["task_id"]
            return '<a href="{0}/submit/status/{1}" target="_blank"> Link To Cukoo Report</a>'.format(
                cuckoo_web, str(cuckoo_id)
            )
    else:
        return '<span class="alert alert-danger">Unable to Submit File</span>'
Example #47
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)
Example #48
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()
Example #49
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()
Example #50
0
    def download(self, request, *args, ** kwargs):
        """Download a Malware instance as a raw or compressed file"""
        # kwargs provided by URLs/Routers: project_name, sha256
        # malware_sha256 = self.kwargs.get("sha256", None)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # get instance
        instance = self.get_object()
        dl_file = open(get_sample_path(instance.sha256), 'rb')

        # TODO(frennkie) encoding?!?! CLRF, LF ?! XXX
        response = HttpResponse(DjangoFile(dl_file), content_type=instance.mime)
        response['Content-Disposition'] = 'attachment; filename={}'.format(instance.name)
        return response
Example #51
0
def cuckoo_submit():
    # Get Query Strings
    project = request.query.project
    file_hash = request.query.hash
    if project in project_list():
        __project__.open(project)
    else:
        __project__.open('../')
        project = 'Main'
    # Open the Database
    db = Database()
    # Open a session
    try:
        path = get_sample_path(file_hash)
        __sessions__.new(path)
    except:
        return '<span class="alert alert-danger">Invalid Submission</span>'

    try:
        # Return URI For Existing Entry
        check_uri = '{0}/files/view/sha256/{1}'.format(cuckoo_api, file_hash)
        check_file = requests.get(check_uri)
        if check_file.status_code == 200:
            check_result = dict(check_file.json())
            cuckoo_id = check_result['sample']['id']
            return '<a href="{0}/analysis/{1}" target="_blank"> Link To Cukoo Report</a>'.format(
                cuckoo_web, str(cuckoo_id))
    except Exception as e:
        return '<span class="alert alert-danger">Error Connecting To Cuckoo</span>'

    # If it doesn't exist, submit it.

    # Get the file data from viper
    file_data = open(__sessions__.current.file.path, 'rb').read()
    file_name = __sessions__.current.file.name

    if file_data:
        # Submit file data to cuckoo
        uri = '{0}{1}'.format(cuckoo_api, '/tasks/create/file')
        options = {'file': (file_name, file_data)}
        cuckoo_response = requests.post(uri, files=options)
        if cuckoo_response.status_code == 200:
            cuckoo_id = dict(cuckoo_response.json())['task_id']
            return '<a href="{0}/analysis/{1}" target="_blank"> Link To Cukoo Report</a>'.format(
                cuckoo_web, str(cuckoo_id))
    else:
        return '<span class="alert alert-danger">Unable to Submit File</span>'
Example #52
0
    def run(self, *args):
        try:
            args = self.parser.parse_args(args)
        except SystemExit:
            return

        # This command requires a session to be opened.
        if not __sessions__.is_set():
            self.log('error', "No open session. This command expects a file to be open.")
            self.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:
            self.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")
Example #53
0
    def ScanFile(self, sample):

        if isinstance(sample, Malware):
            sample_path = get_sample_path(sample.sha256)
        else:
            sample_path = sample.path
        if not os.path.exists(sample_path):
            self.log(
                'error',
                'The file does not exists at path {0}'.format(sample_path))
            return

        try:
            if self.daemon.ping():
                with open(sample_path, 'rb') as fd:
                    results = self.daemon.scan_stream(fd.read())
            else:
                self.log('error', "Unable to connect to the daemon")
        except Exception as ex:
            msg = 'Unable to scan file {0} with antivirus daemon, {1}'.format(
                sample.sha256, ex)
            self.log('error', msg)
            return

        found = None
        name = None

        if results:
            for item in results:
                found = results[item][0]
                name = results[item][1]

        if found == 'ERROR':
            self.log(
                'error',
                "Check permissions of the binary folder, {0}".format(name))
        else:
            if name is not None:
                if self.args.tag:
                    self.db.add_tags(sample.sha256, name)
            else:
                name = 'Threat not found!'

            self.log(
                'info',
                "{0} identify {1} as : {2}".format(self.socket, sample.sha256,
                                                   name))
Example #54
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.')
Example #55
0
    def download(self, request, *args, **kwargs):
        """Download a Malware instance as a raw or compressed file"""
        # kwargs provided by URLs/Routers: project_name, sha256
        # malware_sha256 = self.kwargs.get("sha256", None)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # get instance
        instance = self.get_object()
        dl_file = open(get_sample_path(instance.sha256), 'rb')

        # TODO(frennkie) encoding?!?! CLRF, LF ?! XXX
        response = HttpResponse(DjangoFile(dl_file),
                                content_type=instance.mime)
        response['Content-Disposition'] = 'attachment; filename={}'.format(
            instance.name)
        return response
Example #56
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__:
                    print_info("Running command \"{0}\"".format(split_command))

                    module = __modules__[root]['obj']()
                    module.set_commandline(args)
                    module.run()

                    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))
Example #57
0
    def _process_uploaded(db, uploaded_file_path, file_name, tag_list=None, note_title=None, note_body=None):
        """_process_uploaded add one uploaded file to database and to storage then remove uploaded file"""

        log.debug("adding: {} as {}".format(uploaded_file_path, file_name))

        malware = File(uploaded_file_path)
        malware.name = file_name

        if get_sample_path(malware.sha256):
            error = {"error": {"code": "DuplicateFileHash",
                               "message": "File hash exists already: {} (sha256: {})".format(malware.name, malware.sha256)}}
            log.error("adding failed: {}".format(error))
            raise ValidationError(detail=error)  # TODO(frennkie) raise more specific error?! so that we can catch it..?!
        # Try to store file object into database
        if db.add(obj=malware, tags=tag_list):
            # If succeeds, store also in the local repository.
            # If something fails in the database (for example unicode strings)
            # we don't want to have the binary lying in the repository with no
            # associated database record.
            malware_stored_path = store_sample(malware)

            # run autoruns on the stored sample
            if cfg.get('autorun').enabled:
                autorun_module(malware.sha256)

            log.debug("added file \"{0}\" to {1}".format(malware.name, malware_stored_path))

            if note_body and note_title:
                db.add_note(malware.sha256, note_title, note_body)
                log.debug("added note: \"{0}\"".format(note_title))

        else:
            error = {"error": {"code": "DatabaseAddFailed",
                               "message": "Adding File to Database failed: {} (sha256: {})".format(malware.name, malware.sha256)}}
            log.error("adding failed: {}".format(error))
            raise ValidationError(detail=error)

        # clean up
        try:
            os.remove(uploaded_file_path)
        except OSError as err:
            log.error("failed to delete temporary file: {}".format(err))

        return malware
Example #58
0
    def cmd_delete(self, *args):
        parser = argparse.ArgumentParser(prog='delete', description="Delete a file")
        parser.add_argument('-a', '--all', action='store_true', help="Delete ALL files in this project")

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

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

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

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

            self.log('info', "Deleted a total of {} files.".format(len(samples)))
        else:
            if __sessions__.is_set():
                rows = self.db.find('sha256', __sessions__.current.file.sha256)
                if rows:
                    malware_id = rows[0].id
                    if self.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.")