test_crypto.py
3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""Check decryption of files from olevba works."""
import sys
import unittest
import os
from os.path import join as pjoin
from subprocess import check_output, CalledProcessError
import json
from collections import OrderedDict
from tests.test_utils import DATA_BASE_DIR, SOURCE_BASE_DIR
from oletools import crypto
@unittest.skipIf(not crypto.check_msoffcrypto(),
'Module msoffcrypto not installed for python{}.{}'
.format(sys.version_info.major, sys.version_info.minor))
class OlevbaCryptoWriteProtectTest(unittest.TestCase):
"""
Test documents that are 'write-protected' through encryption.
Excel has a way to 'write-protect' documents by encrypting them with a
hard-coded standard password. When looking at the file-structure you see
an OLE-file with streams `EncryptedPackage`, `StrongEncryptionSpace`, and
`EncryptionInfo`. Contained in the first is the actual file. When opening
such a file in excel, it is decrypted without the user noticing.
Olevba should detect such encryption, try to decrypt with the standard
password and look for VBA code in the decrypted file.
All these tests are skipped if the module `msoffcrypto-tools` is not
installed.
"""
def test_autostart(self):
"""Check that autostart macro is found in xls[mb] sample file."""
# create a PYTHONPATH environment var to prefer our olevba
env = os.environ
try:
env['PYTHONPATH'] = SOURCE_BASE_DIR + os.pathsep + \
os.environ['PYTHONPATH']
except KeyError:
env['PYTHONPATH'] = SOURCE_BASE_DIR
for suffix in 'xlsm', 'xlsb':
example_file = pjoin(
DATA_BASE_DIR, 'encrypted',
'autostart-encrypt-standardpassword.' + suffix)
try:
output = check_output([sys.executable, '-m', 'olevba', '-j',
example_file],
universal_newlines=True, env=env)
except CalledProcessError as err:
print(err.output)
raise
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'])
if __name__ == '__main__':
unittest.main()