コード例 #1
0
    def do_test_md5(self, args, test_fun=None, only_run_every=1):
        """ helper for test_md5 and test_md5_args """
        data_dir = join(DATA_BASE_DIR, 'oleobj')

        # name of sample, extension of embedded file, md5 hash of embedded file
        for sample_index, (sample_name, embedded_name, expect_hash) \
                in enumerate(SAMPLES):
            if sample_index % only_run_every != 0:
                continue
            args_with_path = args + [join(data_dir, sample_name), ]
            if test_fun is None:
                output, ret_val = call_and_capture('oleobj', args_with_path,
                                                   accept_nonzero_exit=True)
            else:
                ret_val = test_fun(args_with_path)
                output = '[output: see above]'
            self.assertEqual(ret_val, oleobj.RETURN_DID_DUMP,
                             msg='Wrong return value {} for {}. Output:\n{}'
                                 .format(ret_val, sample_name, output))
            expect_name = join(self.temp_dir,
                               sample_name + '_' + embedded_name)
            if not isfile(expect_name):
                self.did_fail = True
                self.fail('{0} not created from {1}. Output:\n{2}'
                          .format(expect_name, sample_name, output))
                continue
            md5_hash = calc_md5(expect_name)
            if md5_hash != expect_hash:
                self.did_fail = True
                self.fail('Wrong md5 {0} of {1} from {2}. Output:\n{3}'
                          .format(md5_hash, expect_name, sample_name, output))
                continue
コード例 #2
0
ファイル: test_basic.py プロジェクト: decalage2/oletools
    def test_rtf_behaviour(self):
        """Test behaviour of olevba when presented with an rtf file."""
        input_file = join(DATA_BASE_DIR, 'msodde', 'RTF-Spec-1.7.rtf')
        output, ret_code = call_and_capture('olevba',
                                            args=(input_file, ),
                                            accept_nonzero_exit=True)

        # check that return code is olevba.RETURN_OPEN_ERROR
        self.assertEqual(ret_code, 5)

        # check output:
        self.assertIn('FileOpenError', output)
        self.assertIn('is RTF', output)
        self.assertIn('rtfobj', output)
        # TODO: I disabled this test because we do not log "not encrypted" as warning anymore
        # to avoid other issues.
        # If we really want to test this, then the test should be run with log level INFO:
        # self.assertIn('not encrypted', output)

        # check warnings
        for line in output.splitlines():
            if line.startswith('WARNING ') and 'encrypted' in line:
                continue  # encryption warnings are ok
            elif 'warn' in line.lower():
                raise self.fail('Found "warn" in output line: "{}"'.format(
                    line.rstrip()))
コード例 #3
0
ファイル: test_crypto.py プロジェクト: zerospam/oletools
 def test_autostart(self):
     """Check that autostart macro is found in xls[mb] sample file."""
     for suffix in 'xlsm', 'xlsb':
         example_file = pjoin(
             DATA_BASE_DIR, 'encrypted',
             'autostart-encrypt-standardpassword.' + suffix)
         output, _ = call_and_capture('olevba',
                                      args=('-j', example_file),
                                      exclude_stderr=True)
         data = json.loads(output, object_pairs_hook=OrderedDict)
         # debug: json.dump(data, sys.stdout, indent=4)
         self.assertEqual(len(data), 4)
         self.assertIn('script_name', data[0])
         self.assertIn('version', data[0])
         self.assertEqual(data[0]['type'], 'MetaInformation')
         self.assertIn('return_code', data[-1])
         self.assertEqual(data[-1]['type'], 'MetaInformation')
         self.assertEqual(data[1]['container'], None)
         self.assertEqual(data[1]['file'], example_file)
         self.assertEqual(data[1]['analysis'], None)
         self.assertEqual(data[1]['macros'], [])
         self.assertEqual(data[1]['type'], 'OLE')
         self.assertEqual(data[2]['container'], example_file)
         self.assertNotEqual(data[2]['file'], example_file)
         self.assertEqual(data[2]['type'], "OpenXML")
         analysis = data[2]['analysis']
         self.assertEqual(analysis[0]['type'], 'AutoExec')
         self.assertEqual(analysis[0]['keyword'], 'Auto_Open')
         macros = data[2]['macros']
         self.assertEqual(macros[0]['vba_filename'], 'Modul1.bas')
         self.assertIn('Sub Auto_Open()', macros[0]['code'])
コード例 #4
0
ファイル: test_crypto.py プロジェクト: zerospam/oletools
 def test_standard_password(self):
     """Check dde-link is found in xls[mb] sample files."""
     for suffix in 'xls', 'xlsx', 'xlsm', 'xlsb':
         example_file = pjoin(DATA_BASE_DIR, 'encrypted',
                              'dde-test-encrypt-standardpassword.' + suffix)
         output, _ = call_and_capture('msodde', [
             example_file,
         ])
         self.assertIn('\nDDE Links:\ncmd /c calc.exe\n',
                       output,
                       msg='Unexpected output {!r} for {}'.format(
                           output, suffix))
コード例 #5
0
ファイル: test_basic.py プロジェクト: zerospam/oletools
 def test_crypt_output(self):
     """Check for helpful error message when failing to decrypt."""
     for suffix in 'doc', 'docm', 'docx', 'ppt', 'pptm', 'pptx', 'xls', \
             'xlsb', 'xlsm', 'xlsx':
         example_file = join(BASE_DIR, 'encrypted', 'encrypted.' + suffix)
         output, ret_code = call_and_capture('msodde', [
             example_file,
         ],
                                             accept_nonzero_exit=True)
         self.assertEqual(ret_code, 1)
         self.assertIn('passwords could not decrypt office file',
                       output,
                       msg='Unexpected output: {}'.format(output.strip()))
コード例 #6
0
 def test_no_output(self):
     """ test that oleobj does not find data where it should not """
     args = ['-d', self.temp_dir]
     for sample_name in ('sample_with_lnk_to_calc.doc',
                         'embedded-simple-2007.xml',
                         'embedded-simple-2007-as2003.xml'):
         full_name = join(DATA_BASE_DIR, 'oleobj', sample_name)
         output, ret_val = call_and_capture('oleobj', args + [full_name, ],
                                            accept_nonzero_exit=True)
         if glob(self.temp_dir + 'ole-object-*'):
             self.fail('found embedded data in {0}. Output:\n{1}'
                       .format(sample_name, output))
         self.assertEqual(ret_val, oleobj.RETURN_NO_DUMP,
                          msg='Wrong return value {} for {}. Output:\n{}'
                              .format(ret_val, sample_name, output))
コード例 #7
0
    def test_external_links(self):
        """
        loop through sample files asserting that external links are found
        """

        for dirpath, _, filenames in os.walk(BASE_DIR):
            for filename in filenames:
                file_path = path.join(dirpath, filename)

                output, ret_val = call_and_capture('oleobj', [
                    file_path,
                ],
                                                   accept_nonzero_exit=True)
                self.assertEqual(
                    ret_val,
                    oleobj.RETURN_DID_DUMP,
                    msg='Wrong return value {} for {}. Output:\n{}'.format(
                        ret_val, filename, output))
コード例 #8
0
ファイル: test_basic.py プロジェクト: decalage2/oletools
    def test_crypt_return(self):
        """
        Test that encrypted files give a certain return code.

        Currently, only the encryption applied by Office 2010 (CryptoApi RC4
        Encryption) is tested.
        """
        CRYPT_DIR = join(DATA_BASE_DIR, 'encrypted')
        CRYPT_RETURN_CODE = 9
        ADD_ARGS = [], [
            '-d',
        ], [
            '-a',
        ], [
            '-j',
        ], [
            '-t',
        ]  # only 1st file
        EXCEPTIONS = [
            'autostart-encrypt-standardpassword.xls',  # These ...
            'autostart-encrypt-standardpassword.xlsm',  # files ...
            'autostart-encrypt-standardpassword.xlsb',  # are ...
            'dde-test-encrypt-standardpassword.xls',  # automati...
            'dde-test-encrypt-standardpassword.xlsx',  # ...cally...
            'dde-test-encrypt-standardpassword.xlsm',  # decrypted.
            'dde-test-encrypt-standardpassword.xlsb'
        ]
        for filename in os.listdir(CRYPT_DIR):
            if filename in EXCEPTIONS:
                continue
            full_name = join(CRYPT_DIR, filename)
            for args in ADD_ARGS:
                _, ret_code = call_and_capture('olevba',
                                               args=[
                                                   full_name,
                                               ] + args,
                                               accept_nonzero_exit=True)
                self.assertEqual(ret_code, CRYPT_RETURN_CODE,
                                 msg='Wrong return code {} for args {}'\
                                     .format(ret_code, args + [filename, ]))

                # test only first file with all arg combinations, others just
                # without arg (test takes too long otherwise
                ADD_ARGS = ([], )
コード例 #9
0
ファイル: test_basic.py プロジェクト: decalage2/oletools
    def test_xlm(self):
        """Test that xlm macros are found."""
        XLM_DIR = join(DATA_BASE_DIR, 'excel4-macros')
        ADD_ARGS = ['-j']

        for filename in os.listdir(XLM_DIR):
            full_name = join(XLM_DIR, filename)
            suffix = splitext(filename)[1]
            out_str, ret_code = call_and_capture('olevba',
                                                 args=[
                                                     full_name,
                                                 ] + ADD_ARGS,
                                                 accept_nonzero_exit=True)
            output = json.loads(out_str)
            self.assertEqual(len(output), 3)
            self.assertEqual(output[0]['type'], 'MetaInformation')
            self.assertEqual(output[0]['script_name'], 'olevba')
            self.assertEqual(output[-1]['type'], 'MetaInformation')
            self.assertEqual(output[-1]['n_processed'], 1)
            self.assertEqual(output[-1]['return_code'], 0)
            result = output[1]
            self.assertTrue(result['json_conversion_successful'])
            if suffix in ('.xlsb', '.xltm', '.xlsm'):
                # TODO: cannot extract xlm macros for these types yet
                self.assertEqual(result['macros'], [])
            else:
                code = result['macros'][0]['code']
                if suffix == '.slk':
                    self.assertIn('Excel 4 macros extracted', code)
                else:
                    self.assertIn('Excel 4.0 macro sheet', code)
                self.assertIn('Auto_Open', code)
                if 'excel5' not in filename:  # TODO: is not found in excel5
                    self.assertIn('ALERT(', code)
                self.assertIn('HALT()', code)

                self.assertIn(len(result['analysis']), (2, 3))
                types = [entry['type'] for entry in result['analysis']]
                keywords = [entry['keyword'] for entry in result['analysis']]
                self.assertIn('Auto_Open', keywords)
                self.assertIn('XLM macro', keywords)
                self.assertIn('AutoExec', types)
                self.assertIn('Suspicious', types)
コード例 #10
0
ファイル: test_basic.py プロジェクト: decalage2/oletools
    def do_test_behaviour(self, filename):
        """Helper for test_{text,empty}_behaviour."""
        input_file = join(DATA_BASE_DIR, 'basic', filename)
        output, _ = call_and_capture('olevba', args=(input_file, ))

        # check output
        self.assertTrue(re.search(r'^Type:\s+Text\s*$', output, re.MULTILINE),
                        msg='"Type: Text" not found in output:\n' + output)
        self.assertTrue(re.search(r'^No suspicious .+ found.$', output,
                                  re.MULTILINE),
                        msg='"No suspicous...found" not found in output:\n' + \
                            output)
        self.assertNotIn('error', output.lower())

        # check warnings
        for line in output.splitlines():
            if line.startswith('WARNING ') and 'encrypted' in line:
                continue  # encryption warnings are ok
            elif 'warn' in line.lower():
                raise self.fail('Found "warn" in output line: "{}"'.format(
                    line.rstrip()))
コード例 #11
0
    def test_autostart(self):
        """Check that autostart macro is found in xls[mb] sample file."""
        for suffix in 'xlsm', 'xlsb':
            example_file = pjoin(
                DATA_BASE_DIR, 'encrypted',
                'autostart-encrypt-standardpassword.' + suffix)
            output, _ = call_and_capture('olevba',
                                         args=('-j', example_file),
                                         exclude_stderr=True)
            data = json.loads(output, object_pairs_hook=OrderedDict)
            # debug: json.dump(data, sys.stdout, indent=4)
            self.assertIn(len(data), (3, 4))

            # first 2 parts: general info about script and file
            self.assertIn('script_name', data[0])
            self.assertIn('version', data[0])
            self.assertEqual(data[0]['type'], 'MetaInformation')
            self.assertEqual(data[1]['container'], None)
            self.assertEqual(data[1]['file'], example_file)
            self.assertEqual(data[1]['analysis'], None)
            self.assertEqual(data[1]['macros'], [])
            self.assertEqual(data[1]['type'], 'OLE')
            self.assertTrue(data[1]['json_conversion_successful'])

            # possible VBA stomping warning
            if len(data) == 4:
                self.assertEqual(data[2]['type'], 'msg')
                self.assertIn('VBA stomping', data[2]['msg'])

            # last part is the actual result
            self.assertEqual(data[-1]['container'], example_file)
            self.assertNotEqual(data[-1]['file'], example_file)
            self.assertEqual(data[-1]['type'], "OpenXML")
            analysis = data[-1]['analysis']
            self.assertEqual(analysis[0]['type'], 'AutoExec')
            self.assertEqual(analysis[0]['keyword'], 'Auto_Open')
            macros = data[-1]['macros']
            self.assertEqual(macros[0]['vba_filename'], 'Modul1.bas')
            self.assertIn('Sub Auto_Open()', macros[0]['code'])
            self.assertTrue(data[-1]['json_conversion_successful'])
コード例 #12
0
    def test_rtf_behaviour(self):
        """Test behaviour of olevba when presented with an rtf file."""
        input_file = join(DATA_BASE_DIR, 'msodde', 'RTF-Spec-1.7.rtf')
        output, ret_code = call_and_capture('olevba',
                                            args=(input_file, ),
                                            accept_nonzero_exit=True)

        # check that return code is olevba.RETURN_OPEN_ERROR
        self.assertEqual(ret_code, 5)

        # check output:
        self.assertIn('FileOpenError', output)
        self.assertIn('is RTF', output)
        self.assertIn('rtfobj.py', output)
        self.assertIn('not encrypted', output)

        # check warnings
        for line in output.splitlines():
            if line.startswith('WARNING ') and 'encrypted' in line:
                continue  # encryption warnings are ok
            elif 'warn' in line.lower():
                raise self.fail('Found "warn" in output line: "{}"'.format(
                    line.rstrip()))