Пример #1
0
    def test_delete(self):
        # Add a sample
        sha256 = '03b0b693f76b22e54eea716997b98b9a105c82b031439f72663d7b0209bd1f7d'
        db.session.add(Sample(sha256, 'c99.php',
                              'db3121cd98c49ef6114cc60f2fea32a1', 'c33ba376c53f33bf11bd607206c43eed7c7e2430',
                              '3072:7x1qKo1wcNyg1dxiGbkYdMH4qDZLFh7C8We8Y9377:7x1qKdcNB1dxiGbkYdMH4qDZLFh7C8W0',
                              '5.68514757275382', ' 	2016-04-21 13:41:37.960251 UTC',
                              ' 	2016-04-21 13:41:37.960251 UTC', 0, 0, ' 	text/x-php'))
        db.session.commit()

        # Acces the page with no authentication
        rv = self.app.get('/admin/delete/{sha256}'.format(sha256=sha256)).data.decode('utf-8')
        self.assertIn('You should be redirected automatically to target URL: <a href="/login">/login</a>',
                      rv)
        # Log in
        self.login()

        # Access the page with no sha256
        rv = self.app.get('/admin/delete/').status_code
        self.assertEqual(rv, 404)

        # Access the page with wrong sha256
        rv = self.app.get('/admin/delete/WHATTHEFUCKYOUSUCKAHAHAHAHAHA').status_code
        self.assertEqual(rv, 404)

        # Delete the sample
        self.app.get('/admin/delete/{sha256}'.format(sha256=sha256))
        self.assertIsNone(Sample.get(sha256))
Пример #2
0
    def test_vote(self):
        # Vote for the file we just uploaded
        rv = self.app.get('/vote/{sha256}/clean'.format(
            sha256=global_sha256)).data.decode('utf-8')
        samp = Sample.get(global_sha256)
        self.assertEqual(rv, 'OK')
        self.assertEqual(samp.vote_clean, 1)
        self.assertEqual(samp.vote_malicious, 0)

        # Vote for the same file
        rv = self.app.get('/vote/{sha256}/clean'.format(
            sha256=global_sha256)).data.decode('utf-8')
        samp = Sample.get(global_sha256)
        self.assertEqual(rv, 'NOK')
        self.assertEqual(samp.vote_clean, 1)
        self.assertEqual(samp.vote_malicious, 0)

        # Upload a new file
        self.app.post('/upload',
                      data=dict(file=(StringIO(file_content), file_name),
                                filename=file_name,
                                type='PHP'))

        # Vote for this file
        rv = self.app.get('/vote/{sha256}/malicious'.format(
            sha256=file_sha256)).data.decode('utf-8')
        samp = Sample.get(file_sha256)
        self.assertEqual(rv, 'OK')
        self.assertEqual(samp.vote_clean, 0)
        self.assertEqual(samp.vote_malicious, 1)
Пример #3
0
    def test_index(self):
        """ Test admin index """
        # Add a sample in the database
        sample = Sample(
            sha256='6ffef45e178b189c9eb486457dc6ae71a2e62be5724adc598d25585a6c0c6c1a',
            sha1='6a6f0260611dcd60d502d308f74ff3c1ad590cfe',
            md5='149b8ae3ca1cf126af05bd8c58ebde90',
            ssdeep='3072:7Q6vU3oUXNiDarHituutTxmakBIRDzGoiTzj7c5hH5D8:7Q6vMXNQarHituutTxmakBcDzGoiTzjF',
            entropy='5.65471943656401',
            mime='text/x-php',
            first_analysis='2000-01-01 10:00:00.00000',
            last_analysis='2000-01-01 10:00:00.00000'
        )
        sample.analyzes.append(Analysis(
            type='PHP',
            soft='PMF',
            sample_sha256='6ffef45e178b189c9eb486457dc6ae71a2e62be5724adc598d25585a6c0c6c1a',
            analysis_time='0.004575014114379883'
        ))
        db.session.add(sample)
        db.session.commit()

        # Access without being logged in
        rv = self.app.get('/admin/').data.decode('utf-8')
        self.assertIn('You should be redirected automatically to target URL: <a href="/login">/login</a>',
                      rv)

        # Log in and access it
        self.login()
        rv = self.app.get('/admin/').data.decode('utf-8')
        dates = [datetime.date.today() - datetime.timedelta(days=x) for x in range(7)]
        dates = [date.isoformat() for date in reversed(dates)]
        self.assertIn("labels: " + str(dates) + ",", rv)
Пример #4
0
    def test_submit_tag(self):
        # Submit shitty tag
        rv = self.app.get('/tag/submit/{sha256}/SHITTY').data.decode('utf-8')
        self.assertEqual(rv, 'NOK')

        # Submit a correct tag with invalid sha256
        rv = self.app.get('/tag/submit/{sha256}/Tag').data.decode('utf-8')
        self.assertEqual(rv, 'NOK')

        # Add a tag to the db
        tag = Tag('Tag', 'info')
        db.session.add(tag)
        db.session.commit()

        # Submit a correct tag with valid sha256
        rv = self.app.get('/tag/submit/{sha256}/Tag'.format(
            sha256=global_sha256)).data.decode('utf-8')
        self.assertEqual(rv, 'OK')
        tags = [tag.name for tag in Sample.get(global_sha256).tags]
        self.assertIn('Tag', tags)

        # Submit the same tag with the same sha256
        rv = self.app.get('/tag/submit/{sha256}/Tag'.format(
            sha256=global_sha256)).data.decode('utf-8')
        self.assertEqual(rv, 'NOK')
Пример #5
0
    def test_edit(self):
        # Add a sample
        sha256 = '03b0b693f76b22e54eea716997b98b9a105c82b031439f72663d7b0209bd1f7d'
        db.session.add(Sample(sha256, 'c99.php',
                              'db3121cd98c49ef6114cc60f2fea32a1', 'c33ba376c53f33bf11bd607206c43eed7c7e2430',
                              '3072:7x1qKo1wcNyg1dxiGbkYdMH4qDZLFh7C8We8Y9377:7x1qKdcNB1dxiGbkYdMH4qDZLFh7C8W0',
                              '5.68514757275382', ' 	2016-04-21 13:41:37.960251 UTC',
                              ' 	2016-04-21 13:41:37.960251 UTC', 0, 0, ' 	text/x-php'))
        db.session.commit()
        # Access the page with no authentication
        rv = self.app.get('/admin/edit/{sha256}'.format(sha256=sha256)).data.decode('utf-8')
        self.assertIn('You should be redirected automatically to target URL: <a href="/login">/login</a>',
                      rv)

        # Log in
        self.login()

        # Access the page with no sha256
        rv = self.app.get('/admin/edit/').status_code
        self.assertEqual(rv, 404)

        # Access the page with wrong sha256
        rv = self.app.get('/admin/edit/WHATTHEFUCKYOUSUCKAHAHAHAHAHA').status_code
        self.assertEqual(rv, 404)

        # Access the page
        rv = self.app.get('/admin/edit/{sha256}'.format(sha256=sha256)).data.decode('utf-8')
        self.assertIn('<h2>Edit sample : {sha256}</h2>'.format(sha256=sha256), rv)

        # Edit the sample
        rv = self.app.post('/admin/edit/{sha256}'.format(sha256=sha256), data=dict(
            name='c999.php', mime='text/x-php', first_analysis='2016-04-22 09:07:49.421788',
            last_analysis='2016-04-22 09:07:49.421788', tags=''
        ), follow_redirects=True).data.decode('utf-8')
        self.assertIn('c999.php', rv)
Пример #6
0
def sample_exists(analysis_type, sha256):
    """ Returns OK if the file has already been analysed """
    sample = Sample.get(sha256)
    if sample:
        for analysis in sample.analyzes:
            if analysis.type == analysis_type:
                return "OK"
    return "NOK"
Пример #7
0
def sample_exists(analysis_type, sha256):
    """ Returns OK if the file has already been analysed """
    sample = Sample.get(sha256)
    if sample:
        for analysis in sample.analyzes:
            if analysis.type == analysis_type:
                return "OK"
    return "NOK"
Пример #8
0
def delete(sha256):
    """ Delete a sample from harddrive and database """
    sample = Sample.get(sha256)
    if not sample:
        abort(404)
    for tag in sample.tags:
        db.session.delete(tag)
    for analysis in sample.analyzes:
        db.session.delete(analysis)
    db.session.delete(sample)
    db.session.commit()
    try:
        os.remove(Sample.get_file_path(sha256))
    except OSError:
        flash('Could not delete the file from the file system.', 'danger')
    flash('The file %s has been deleted. Are you happy now ?' % sha256, 'success')
    return redirect(request.referrer)
Пример #9
0
    def test_search(self):
        rv = self.app.get('/search')
        self.assertEqual(200, rv.status_code)
        self.assertIn('<h1>Search</h1>', rv.data.decode('utf-8'))

        # Add a sample with his tag
        tag = Tag('wat', 'danger')
        db.session.add(tag)
        sample = Sample(
            name=['wut.php'],
            sha256='6ffef45e178b189c9eb486457dc6ae71a2e62be5724adc598d25585a6c0c6c1a',
            sha1='6a6f0260611dcd60d502d308f74ff3c1ad590cfe',
            md5='149b8ae3ca1cf126af05bd8c58ebde90',
            ssdeep='3072:7Q6vU3oUXNiDarHituutTxmakBIRDzGoiTzj7c5hH5D8:7Q6vMXNQarHituutTxmakBcDzGoiTzjF',
            entropy='5.65471943656401',
            mime='text/x-php',
            first_analysis='2000-01-01 10:00:00.00000',
            last_analysis='2000-01-01 10:00:00.00000'
        )
        sample.tags.append(tag)
        sample.analyzes.append(Analysis(
            type='PHP',
            soft='PMF',
            sample_sha256='6ffef45e178b189c9eb486457dc6ae71a2e62be5724adc598d25585a6c0c6c1a',
            analysis_time='0.004575014114379883'
        ))
        db.session.add(sample)
        db.session.commit()
        result_sha256 = '<a href="/analysis/any/6ffef45e178b189c9eb486457dc6ae71a2e62be5724adc598d25585a6c0c6c1a">6ffef45e178b189c9eb486457dc6ae71a2e62be5724adc598d25585a6c0c6c1a</a>'
        rv = self.app.get('/search')
        self.assertIn(result_sha256, rv.data.decode('utf-8'))

        # Custom search
        rv = search(self.app, '6ffe')
        self.assertIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, '6ffe123')
        self.assertNotIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'md5:126')
        self.assertIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'md5:wat')
        self.assertNotIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'name:php')
        self.assertIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'name:qweqwe')
        self.assertNotIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'fist_analysis:2000-01-01')
        self.assertIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'last_analysis:2000-01-03')
        self.assertNotIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'tags:wat')
        self.assertIn(result_sha256, rv.data.decode('utf-8'))
        rv = search(self.app, 'tags:watt')
        self.assertNotIn(result_sha256, rv.data.decode('utf-8'))
Пример #10
0
    def analyse(self):
        # New sample ? New analysis ?
        sample = Sample.get(self.sha256)
        if sample is None:
            # New sample, let's add it !
            sample = Sample(sha256=self.sha256, name=self.name)
            sample.compute_hashes()
        else:
            # Too recent do not analyse it
            if (sample.last_analysis < (sample.last_analysis + datetime.timedelta(days=3))
                    and len(sample.analyzes) == len(current_app.config.get('ENABLED_ANALYZERS'))):
                return True
            # Update last analysis date
            sample.last_analysis = datetime.date.today()
        self.do_analyzes(sample)
        db.session.add(sample)

        # Commit database
        try:
            db.session.commit()
        except DataError:
            flash('There was an error while analysing your file.', 'danger')
            return False

        # Allow the user to vote for his sample
        session['can_vote'] = self.sha256
        return True
Пример #11
0
 def add_name(sha256, name):
     """
     Add a name to the specified sample
     :param sha256: str
     :param name: str
     """
     if name is None:
         return
     sample = Sample.get(sha256=sha256)
     if name not in sample.name:  # Since name is an ARRAY (postgresql) we cannot use append()
         sample.name = sample.name + [name]
         db.session.add(sample)
         db.session.commit()
Пример #12
0
def submit_tag(sha256, tag, format):
    tags = Tag.get_all()
    tag_names = [t.name for t in tags]
    if tag is None or tag not in tag_names:
        return "NOK"
    sample = Sample.get(sha256)
    sample_tag_names = [t.name for t in sample.tags]
    if sample is None or tag in sample_tag_names:
        return "NOK"

    _tag = tags[tag_names.index(tag)]
    sample.tags.append(_tag)  # postgre doesn't like str as objects.
    db.session.commit()
    return str(_tag) if format else 'OK'
Пример #13
0
def submit_tag(sha256, tag, format):
    tags = Tag.get_all()
    tag_names = [t.name for t in tags]
    if tag is None or tag not in tag_names:
        return "NOK"
    sample = Sample.get(sha256)
    sample_tag_names = [t.name for t in sample.tags]
    if sample is None or tag in sample_tag_names:
        return "NOK"

    _tag = tags[tag_names.index(tag)]
    sample.tags.append(_tag)  # postgre doesn't like str as objects.
    db.session.commit()
    return str(_tag) if format else 'OK'
Пример #14
0
    def analyse(self):
        """ Analyse the file with PMF """
        start = time.time()
        rule_file = os.path.join(current_app.config.get('BASE_DIR'), self.path, self.type.lower() + '.yar')
        rules = yara.compile(rule_file)

        try:
            with open(Sample.get_file_path(self.filename), 'rb') as f:
                matches = rules.match(data=f.read())
        except OSError:
            flash('Error while reanalysing the file.', 'danger')
            return False

        self.analysis_time = time.time() - start
        self.result = ' '.join(map(str, matches))
        return True
Пример #15
0
    def analyse(self):
        """ Analyse the file with PMF """
        start = time.time()
        rule_file = os.path.join(current_app.config.get('BASE_DIR'), self.path,
                                 self.type.lower() + '.yar')
        rules = yara.compile(rule_file)

        try:
            with open(Sample.get_file_path(self.filename), 'rb') as f:
                matches = rules.match(data=f.read())
        except OSError:
            flash('Error while reanalysing the file.', 'danger')
            return False

        self.analysis_time = time.time() - start
        self.result = ' '.join(map(str, matches))
        return True
Пример #16
0
    def analyse(self):
        if not zipfile.is_zipfile(self.path):
            flash('The file you sent is not a valid zip file.', 'danger')
            return False

        archive = zipfile.ZipFile(self.path)
        size = 0
        for compressed_file in archive.infolist():
            size += compressed_file.file_size
            if size > MAX_SIZE:
                flash('The size of the archive\'s content is too big !', 'danger')
                return False
            elif compressed_file.filename.lower().endswith('.' + self.analysis.lower()):
                path = archive.extract(compressed_file, current_app.config.get('UPLOAD_FOLDER'))
                with open(path, 'rb') as f:
                    buf = f.read()
                sha256 = hashlib.sha256(buf).hexdigest()
                new_path = Sample.get_file_path(sha256)
                directory = os.path.dirname(new_path)
                try:
                    # Make sure the directory is writeable
                    if not os.access(directory, os.W_OK):
                        try:
                            os.mkdir(directory)
                        except OSError:
                            flash('There was an error while saving you archive.', 'danger')
                    shutil.move(path, new_path)
                except Exception as err:
                    flash('There was an error while extracting your archive', 'danger')
                    logging.error(err)
                    return False

                # Chmod the file to prevent it from being executed
                os.chmod(new_path, 0o400)

                Analyser(sha256=sha256, name=compressed_file.filename, analysis_type=self.analysis, analyse=True)

        return True
Пример #17
0
def edit(sha256):
    """ Edit a sample metadata """
    sample = Sample.get(sha256)
    if sample:
        all_tags = Tag.get_all()
        if request.method == 'POST':
            all_tags_id = [tag.id for tag in all_tags]
            tag_list = []
            for value in request.form:
                if value.startswith('tag_'):
                    id = int(value[4:])
                    if id in all_tags_id:
                        tag_list.append(Tag.get(id))
            sample.name = request.form.get('name', '').replace(' ', '').split(',')
            sample.mime = request.form.get('mime', '')
            sample.first_analysis = request.form.get('first_analysis', '')
            sample.last_analysis = request.form.get('last_analysis', '')
            sample.tags = tag_list
            db.session.add(sample)
            db.session.commit()
            return redirect(url_for('admin.samples'))

        return render_template('admin/edit.html', sample=sample, names=[tag.name for tag in sample.tags], tags=all_tags)
    abort(404)