Commit 43f6a95c32ab20471bd909210e973538f659e27f

Authored by Philippe Lagadec
1 parent 28aa9a84

olevba: fixed bug with --decode option

Showing 1 changed file with 51 additions and 14 deletions
oletools/olevba.py
... ... @@ -155,6 +155,7 @@ https://github.com/unixfreak0037/officeparser
155 155 # - added suspicious strings for PowerShell.exe options
156 156 # 2015-10-09 v0.42 PL: - VBA_Parser: split each format into a separate method
157 157 # 2015-10-10 PL: - added support for text files with VBA source code
  158 +# 2015-11-17 PL: - fixed bug with --decode option
158 159  
159 160 __version__ = '0.42'
160 161  
... ... @@ -632,7 +633,7 @@ vba_expr_str <<= infixNotation(vba_expr_str_item,
632 633 ])
633 634  
634 635  
635   -# ---STRING EXPRESSION -------------------------------------------------------
  636 +# --- INTEGER EXPRESSION -------------------------------------------------------
636 637  
637 638 def sum_ints_list(tokens):
638 639 """
... ... @@ -644,11 +645,47 @@ def sum_ints_list(tokens):
644 645 return sum(integers)
645 646  
646 647  
  648 +def subtract_ints_list(tokens):
  649 + """
  650 + parse action to subtract integers in a VBA expression with operator '-'
  651 + """
  652 + # extract argument from the tokens:
  653 + # expected to be a tuple containing a list of integers such as [a,'&',b,'&',c,...]
  654 + integers = tokens[0][::2]
  655 + return reduce(lambda x,y:x-y, integers)
  656 +
  657 +
  658 +def multiply_ints_list(tokens):
  659 + """
  660 + parse action to multiply integers in a VBA expression with operator '*'
  661 + """
  662 + # extract argument from the tokens:
  663 + # expected to be a tuple containing a list of integers such as [a,'&',b,'&',c,...]
  664 + integers = tokens[0][::2]
  665 + return reduce(lambda x,y:x*y, integers)
  666 +
  667 +
  668 +def divide_ints_list(tokens):
  669 + """
  670 + parse action to divide integers in a VBA expression with operator '/'
  671 + """
  672 + # extract argument from the tokens:
  673 + # expected to be a tuple containing a list of integers such as [a,'&',b,'&',c,...]
  674 + integers = tokens[0][::2]
  675 + return reduce(lambda x,y:x/y, integers)
  676 +
  677 +
647 678 vba_expr_int_item = (vba_asc | vba_val | integer)
648 679  
  680 +# operators associativity:
  681 +# https://en.wikipedia.org/wiki/Operator_associativity
  682 +
649 683 vba_expr_int <<= infixNotation(vba_expr_int_item,
650 684 [
  685 + ("*", 2, opAssoc.LEFT, multiply_ints_list),
  686 + ("/", 2, opAssoc.LEFT, divide_ints_list),
651 687 ("+", 2, opAssoc.LEFT, sum_ints_list),
  688 + ("-", 2, opAssoc.LEFT, subtract_ints_list),
652 689 ])
653 690  
654 691  
... ... @@ -2270,7 +2307,7 @@ class VBA_Parser_CLI(VBA_Parser):
2270 2307 print ''
2271 2308  
2272 2309  
2273   - def process_file_triage(self):
  2310 + def process_file_triage(self, show_decoded_strings=False):
2274 2311 """
2275 2312 Process a file in triage mode, showing only summary results on one line.
2276 2313 """
... ... @@ -2284,7 +2321,7 @@ class VBA_Parser_CLI(VBA_Parser):
2284 2321 if sys.stdout.isatty():
2285 2322 print 'Analysis...\r',
2286 2323 sys.stdout.flush()
2287   - self.analyze_macros()
  2324 + self.analyze_macros(show_decoded_strings=show_decoded_strings)
2288 2325 flags = TYPE2TAG[self.type]
2289 2326 macros = autoexec = suspicious = iocs = hexstrings = base64obf = dridex = vba_obf = '-'
2290 2327 if self.contains_macros: macros = 'M'
... ... @@ -2363,8 +2400,6 @@ def main():
2363 2400 help='display only analysis results, not the macro source code')
2364 2401 parser.add_option("-c", '--code', action="store_true", dest="vba_code_only", default=False,
2365 2402 help='display only VBA source code, do not analyze it')
2366   - parser.add_option("-i", "--input", dest='input', type='str', default=None,
2367   - help='input file containing VBA source code to be analyzed (no parsing)')
2368 2403 parser.add_option("--decode", action="store_true", dest="show_decoded_strings",
2369 2404 help='display all the obfuscated strings with their decoded content (Hex, Base64, StrReverse, Dridex, VBA).')
2370 2405 parser.add_option("--attr", action="store_false", dest="hide_attributes", default=True,
... ... @@ -2375,6 +2410,8 @@ def main():
2375 2410 # Disabled options:
2376 2411 # parser.add_option("--each", action="store_false", dest="global_analysis", default=True,
2377 2412 # help='analyze each VBA module separately')
  2413 + # parser.add_option("-i", "--input", dest='input', type='str', default=None,
  2414 + # help='input file containing VBA source code to be analyzed (no parsing)')
2378 2415  
2379 2416 # TODO: --novba to disable VBA expressions parsing
2380 2417  
... ... @@ -2394,14 +2431,14 @@ def main():
2394 2431 # For now, all logging is disabled:
2395 2432 logging.disable(logging.CRITICAL)
2396 2433  
2397   - if options.input:
2398   - #TODO: remove this option
2399   - raise NotImplementedError
2400   - # input file provided with VBA source code to be analyzed directly:
2401   - print 'Analysis of VBA source code from %s:' % options.input
2402   - vba_code = open(options.input).read()
2403   - print_analysis(vba_code, show_decoded_strings=options.show_decoded_strings)
2404   - sys.exit()
  2434 + # if options.input:
  2435 + # #TODO: remove this option
  2436 + # raise NotImplementedError
  2437 + # # input file provided with VBA source code to be analyzed directly:
  2438 + # print 'Analysis of VBA source code from %s:' % options.input
  2439 + # vba_code = open(options.input).read()
  2440 + # print_analysis(vba_code, show_decoded_strings=options.show_decoded_strings)
  2441 + # sys.exit()
2405 2442  
2406 2443 # Old display with number of items detected:
2407 2444 # print '%-8s %-7s %-7s %-7s %-7s %-7s' % ('Type', 'Macros', 'AutoEx', 'Susp.', 'IOCs', 'HexStr')
... ... @@ -2436,7 +2473,7 @@ def main():
2436 2473 print '\nFiles in %s:' % container
2437 2474 previous_container = container
2438 2475 # summarized output for triage:
2439   - vba_parser.process_file_triage()
  2476 + vba_parser.process_file_triage(show_decoded_strings=options.show_decoded_strings)
2440 2477 count += 1
2441 2478 if not options.detailed_mode or options.triage_mode:
2442 2479 print '\n(Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, TXT=Text, M=Macros, ' \
... ...