Commit 23169cd9e830567a3c4c5e06b79ebd5dd8a1264d
1 parent
c3aa06c8
olevba: improved display, shows container file
Showing
1 changed file
with
20 additions
and
9 deletions
oletools/olevba.py
| @@ -92,6 +92,7 @@ https://github.com/unixfreak0037/officeparser | @@ -92,6 +92,7 @@ https://github.com/unixfreak0037/officeparser | ||
| 92 | # - option -z to scan files in password-protected zips | 92 | # - option -z to scan files in password-protected zips |
| 93 | # 2015-01-02 v0.11 PL: - improved filter_vba to detect colons | 93 | # 2015-01-02 v0.11 PL: - improved filter_vba to detect colons |
| 94 | # 2015-01-03 v0.12 PL: - fixed detect_patterns to detect all patterns | 94 | # 2015-01-03 v0.12 PL: - fixed detect_patterns to detect all patterns |
| 95 | +# - process_file: improved display, shows container file | ||
| 95 | 96 | ||
| 96 | __version__ = '0.12' | 97 | __version__ = '0.12' |
| 97 | 98 | ||
| @@ -136,6 +137,7 @@ import math | @@ -136,6 +137,7 @@ import math | ||
| 136 | import zipfile | 137 | import zipfile |
| 137 | import re | 138 | import re |
| 138 | import optparse | 139 | import optparse |
| 140 | +import os.path | ||
| 139 | 141 | ||
| 140 | import thirdparty.olefile as olefile | 142 | import thirdparty.olefile as olefile |
| 141 | from thirdparty.prettytable import prettytable | 143 | from thirdparty.prettytable import prettytable |
| @@ -1025,27 +1027,34 @@ class VBA_Parser(object): | @@ -1025,27 +1027,34 @@ class VBA_Parser(object): | ||
| 1025 | self.ole_file.close() | 1027 | self.ole_file.close() |
| 1026 | 1028 | ||
| 1027 | 1029 | ||
| 1028 | -def process_file (filename, data): | 1030 | +def process_file (container, filename, data): |
| 1029 | """ | 1031 | """ |
| 1030 | Process a single file | 1032 | Process a single file |
| 1033 | + | ||
| 1034 | + :param container: str, path and filename of container if the file is within | ||
| 1035 | + a zip archive, None otherwise. | ||
| 1036 | + :param filename: str, path and filename of file on disk, or within the container. | ||
| 1037 | + :param data: bytes, content of the file if it is in a container, None if it is a file on disk. | ||
| 1031 | """ | 1038 | """ |
| 1032 | #TODO: replace print by writing to a provided output file (sys.stdout by default) | 1039 | #TODO: replace print by writing to a provided output file (sys.stdout by default) |
| 1033 | - print '' | 1040 | + if container: |
| 1041 | + display_filename = '%s in %s' % (filename, container) | ||
| 1042 | + else: | ||
| 1043 | + display_filename = filename | ||
| 1034 | print '='*79 | 1044 | print '='*79 |
| 1035 | - print 'File:', filename | 1045 | + print 'FILE:', display_filename |
| 1036 | try: | 1046 | try: |
| 1037 | #TODO: handle olefile errors, when an OLE file is malformed | 1047 | #TODO: handle olefile errors, when an OLE file is malformed |
| 1038 | vba = VBA_Parser(filename, data) | 1048 | vba = VBA_Parser(filename, data) |
| 1039 | print 'Type:', vba.type | 1049 | print 'Type:', vba.type |
| 1040 | if vba.detect_vba_macros(): | 1050 | if vba.detect_vba_macros(): |
| 1041 | - print 'Contains VBA Macros:' | 1051 | + #print 'Contains VBA Macros:' |
| 1042 | for (subfilename, stream_path, vba_filename, vba_code) in vba.extract_macros(): | 1052 | for (subfilename, stream_path, vba_filename, vba_code) in vba.extract_macros(): |
| 1043 | # hide attribute lines: | 1053 | # hide attribute lines: |
| 1044 | vba_code = filter_vba(vba_code) | 1054 | vba_code = filter_vba(vba_code) |
| 1045 | print '-'*79 | 1055 | print '-'*79 |
| 1046 | - print 'Filename :', subfilename | ||
| 1047 | - print 'OLE stream :', stream_path | ||
| 1048 | - print 'VBA filename:', vba_filename | 1056 | + print 'VBA MACRO %s ' % vba_filename |
| 1057 | + print 'in file: %s - OLE stream: %s' % (subfilename, stream_path) | ||
| 1049 | print '- '*39 | 1058 | print '- '*39 |
| 1050 | # detect empty macros: | 1059 | # detect empty macros: |
| 1051 | if vba_code.strip() == '': | 1060 | if vba_code.strip() == '': |
| @@ -1053,6 +1062,7 @@ def process_file (filename, data): | @@ -1053,6 +1062,7 @@ def process_file (filename, data): | ||
| 1053 | else: | 1062 | else: |
| 1054 | print vba_code | 1063 | print vba_code |
| 1055 | print '- '*39 | 1064 | print '- '*39 |
| 1065 | + print 'ANALYSIS:' | ||
| 1056 | autoexec_keywords = detect_autoexec(vba_code) | 1066 | autoexec_keywords = detect_autoexec(vba_code) |
| 1057 | if autoexec_keywords: | 1067 | if autoexec_keywords: |
| 1058 | print 'Auto-executable macro keywords found:' | 1068 | print 'Auto-executable macro keywords found:' |
| @@ -1099,6 +1109,7 @@ def process_file (filename, data): | @@ -1099,6 +1109,7 @@ def process_file (filename, data): | ||
| 1099 | except: #TypeError: | 1109 | except: #TypeError: |
| 1100 | #raise | 1110 | #raise |
| 1101 | print sys.exc_value | 1111 | print sys.exc_value |
| 1112 | + print '' | ||
| 1102 | 1113 | ||
| 1103 | 1114 | ||
| 1104 | #=== MAIN ===================================================================== | 1115 | #=== MAIN ===================================================================== |
| @@ -1130,10 +1141,10 @@ def main(): | @@ -1130,10 +1141,10 @@ def main(): | ||
| 1130 | 1141 | ||
| 1131 | logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING) #INFO) | 1142 | logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING) #INFO) |
| 1132 | 1143 | ||
| 1133 | - for filename, data in xglob.iter_files(args, recursive=options.recursive, | 1144 | + for container, filename, data in xglob.iter_files(args, recursive=options.recursive, |
| 1134 | zip_password=options.zip_password, zip_fname=options.zip_fname): | 1145 | zip_password=options.zip_password, zip_fname=options.zip_fname): |
| 1135 | #data = open(filespec, 'rb').read() | 1146 | #data = open(filespec, 'rb').read() |
| 1136 | - process_file(filename, data) | 1147 | + process_file(container, filename, data) |
| 1137 | 1148 | ||
| 1138 | if __name__ == '__main__': | 1149 | if __name__ == '__main__': |
| 1139 | main() | 1150 | main() |