Commit 49b8af644038bf4ceaa3a7c51f057f5f111c0346

Authored by Philippe Lagadec
1 parent 4b4775d3

olevba: added new option --reveal

Showing 1 changed file with 32 additions and 4 deletions
oletools/olevba.py
@@ -151,8 +151,9 @@ https://github.com/unixfreak0037/officeparser @@ -151,8 +151,9 @@ https://github.com/unixfreak0037/officeparser
151 # 2015-09-15 PL: - remove duplicate IOCs from results 151 # 2015-09-15 PL: - remove duplicate IOCs from results
152 # 2015-09-16 PL: - join long VBA lines ending with underscore before scan 152 # 2015-09-16 PL: - join long VBA lines ending with underscore before scan
153 # - disabled unused option --each 153 # - disabled unused option --each
  154 +# 2015-09-22 v0.41 PL: - added new option --reveal
154 155
155 -__version__ = '0.40' 156 +__version__ = '0.41'
156 157
157 #------------------------------------------------------------------------------ 158 #------------------------------------------------------------------------------
158 # TODO: 159 # TODO:
@@ -2095,9 +2096,30 @@ class VBA_Parser_CLI(VBA_Parser): @@ -2095,9 +2096,30 @@ class VBA_Parser_CLI(VBA_Parser):
2095 print 'No suspicious keyword or IOC found.' 2096 print 'No suspicious keyword or IOC found.'
2096 2097
2097 2098
  2099 + def reveal(self):
  2100 + print 'MACRO SOURCE CODE WITH DEOBFUSCATED VBA STRINGS (EXPERIMENTAL):\n'
  2101 + # we only want printable strings:
  2102 + analysis = self.analyze_macros(show_decoded_strings=False)
  2103 + # to avoid replacing short strings contained into longer strings, we sort the analysis results
  2104 + # based on the length of the encoded string, in reverse order:
  2105 + analysis = sorted(analysis, key=lambda type_decoded_encoded: len(type_decoded_encoded[2]), reverse=True)
  2106 + # normally now self.vba_code_all_modules contains source code from all modules
  2107 + deobf_code = self.vba_code_all_modules
  2108 + for kw_type, decoded, encoded in analysis:
  2109 + if kw_type == 'VBA string':
  2110 + #print '%3d occurences: %r => %r' % (deobf_code.count(encoded), encoded, decoded)
  2111 + # need to add double quotes around the decoded strings
  2112 + # after escaping double-quotes as double-double-quotes for VBA:
  2113 + decoded = decoded.replace('"', '""')
  2114 + deobf_code = deobf_code.replace(encoded, '"%s"' % decoded)
  2115 + print ''
  2116 + print deobf_code
  2117 + #TODO: repasser l'analyse plusieurs fois si des chaines hex ou base64 sont revelees
  2118 +
  2119 +
2098 def process_file(self, show_decoded_strings=False, 2120 def process_file(self, show_decoded_strings=False,
2099 display_code=True, global_analysis=True, hide_attributes=True, 2121 display_code=True, global_analysis=True, hide_attributes=True,
2100 - vba_code_only=False): 2122 + vba_code_only=False, show_deobfuscated_code=False):
2101 """ 2123 """
2102 Process a single file 2124 Process a single file
2103 2125
@@ -2150,6 +2172,8 @@ class VBA_Parser_CLI(VBA_Parser): @@ -2150,6 +2172,8 @@ class VBA_Parser_CLI(VBA_Parser):
2150 if global_analysis and not vba_code_only: 2172 if global_analysis and not vba_code_only:
2151 # analyse the code from all modules at once: 2173 # analyse the code from all modules at once:
2152 self.print_analysis(show_decoded_strings) 2174 self.print_analysis(show_decoded_strings)
  2175 + if show_deobfuscated_code:
  2176 + self.reveal()
2153 else: 2177 else:
2154 print 'No VBA macros found.' 2178 print 'No VBA macros found.'
2155 except: #TypeError: 2179 except: #TypeError:
@@ -2260,6 +2284,8 @@ def main(): @@ -2260,6 +2284,8 @@ def main():
2260 help='display all the obfuscated strings with their decoded content (Hex, Base64, StrReverse, Dridex, VBA).') 2284 help='display all the obfuscated strings with their decoded content (Hex, Base64, StrReverse, Dridex, VBA).')
2261 parser.add_option("--attr", action="store_false", dest="hide_attributes", default=True, 2285 parser.add_option("--attr", action="store_false", dest="hide_attributes", default=True,
2262 help='display the attribute lines at the beginning of VBA source code') 2286 help='display the attribute lines at the beginning of VBA source code')
  2287 + parser.add_option("--reveal", action="store_true", dest="show_deobfuscated_code",
  2288 + help='display the macro source code after replacing all the obfuscated strings by their decoded content.')
2263 2289
2264 # Disabled options: 2290 # Disabled options:
2265 # parser.add_option("--each", action="store_false", dest="global_analysis", default=True, 2291 # parser.add_option("--each", action="store_false", dest="global_analysis", default=True,
@@ -2316,7 +2342,8 @@ def main(): @@ -2316,7 +2342,8 @@ def main():
2316 # fully detailed output 2342 # fully detailed output
2317 vba_parser.process_file(show_decoded_strings=options.show_decoded_strings, 2343 vba_parser.process_file(show_decoded_strings=options.show_decoded_strings,
2318 display_code=options.display_code, global_analysis=True, #options.global_analysis, 2344 display_code=options.display_code, global_analysis=True, #options.global_analysis,
2319 - hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only) 2345 + hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only,
  2346 + show_deobfuscated_code=options.show_deobfuscated_code)
2320 else: 2347 else:
2321 # print container name when it changes: 2348 # print container name when it changes:
2322 if container != previous_container: 2349 if container != previous_container:
@@ -2335,7 +2362,8 @@ def main(): @@ -2335,7 +2362,8 @@ def main():
2335 # if options -t and -d were not specified and it's a single file, print details: 2362 # if options -t and -d were not specified and it's a single file, print details:
2336 vba_parser.process_file(show_decoded_strings=options.show_decoded_strings, 2363 vba_parser.process_file(show_decoded_strings=options.show_decoded_strings,
2337 display_code=options.display_code, global_analysis=True, #options.global_analysis, 2364 display_code=options.display_code, global_analysis=True, #options.global_analysis,
2338 - hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only) 2365 + hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only,
  2366 + show_deobfuscated_code=options.show_deobfuscated_code)
2339 2367
2340 2368
2341 if __name__ == '__main__': 2369 if __name__ == '__main__':