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,6 +155,7 @@ https://github.com/unixfreak0037/officeparser
155 # - added suspicious strings for PowerShell.exe options 155 # - added suspicious strings for PowerShell.exe options
156 # 2015-10-09 v0.42 PL: - VBA_Parser: split each format into a separate method 156 # 2015-10-09 v0.42 PL: - VBA_Parser: split each format into a separate method
157 # 2015-10-10 PL: - added support for text files with VBA source code 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 __version__ = '0.42' 160 __version__ = '0.42'
160 161
@@ -632,7 +633,7 @@ vba_expr_str <<= infixNotation(vba_expr_str_item, @@ -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 def sum_ints_list(tokens): 638 def sum_ints_list(tokens):
638 """ 639 """
@@ -644,11 +645,47 @@ def sum_ints_list(tokens): @@ -644,11 +645,47 @@ def sum_ints_list(tokens):
644 return sum(integers) 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 vba_expr_int_item = (vba_asc | vba_val | integer) 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 vba_expr_int <<= infixNotation(vba_expr_int_item, 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 ("+", 2, opAssoc.LEFT, sum_ints_list), 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,7 +2307,7 @@ class VBA_Parser_CLI(VBA_Parser):
2270 print '' 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 Process a file in triage mode, showing only summary results on one line. 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,7 +2321,7 @@ class VBA_Parser_CLI(VBA_Parser):
2284 if sys.stdout.isatty(): 2321 if sys.stdout.isatty():
2285 print 'Analysis...\r', 2322 print 'Analysis...\r',
2286 sys.stdout.flush() 2323 sys.stdout.flush()
2287 - self.analyze_macros() 2324 + self.analyze_macros(show_decoded_strings=show_decoded_strings)
2288 flags = TYPE2TAG[self.type] 2325 flags = TYPE2TAG[self.type]
2289 macros = autoexec = suspicious = iocs = hexstrings = base64obf = dridex = vba_obf = '-' 2326 macros = autoexec = suspicious = iocs = hexstrings = base64obf = dridex = vba_obf = '-'
2290 if self.contains_macros: macros = 'M' 2327 if self.contains_macros: macros = 'M'
@@ -2363,8 +2400,6 @@ def main(): @@ -2363,8 +2400,6 @@ def main():
2363 help='display only analysis results, not the macro source code') 2400 help='display only analysis results, not the macro source code')
2364 parser.add_option("-c", '--code', action="store_true", dest="vba_code_only", default=False, 2401 parser.add_option("-c", '--code', action="store_true", dest="vba_code_only", default=False,
2365 help='display only VBA source code, do not analyze it') 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 parser.add_option("--decode", action="store_true", dest="show_decoded_strings", 2403 parser.add_option("--decode", action="store_true", dest="show_decoded_strings",
2369 help='display all the obfuscated strings with their decoded content (Hex, Base64, StrReverse, Dridex, VBA).') 2404 help='display all the obfuscated strings with their decoded content (Hex, Base64, StrReverse, Dridex, VBA).')
2370 parser.add_option("--attr", action="store_false", dest="hide_attributes", default=True, 2405 parser.add_option("--attr", action="store_false", dest="hide_attributes", default=True,
@@ -2375,6 +2410,8 @@ def main(): @@ -2375,6 +2410,8 @@ def main():
2375 # Disabled options: 2410 # Disabled options:
2376 # parser.add_option("--each", action="store_false", dest="global_analysis", default=True, 2411 # parser.add_option("--each", action="store_false", dest="global_analysis", default=True,
2377 # help='analyze each VBA module separately') 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 # TODO: --novba to disable VBA expressions parsing 2416 # TODO: --novba to disable VBA expressions parsing
2380 2417
@@ -2394,14 +2431,14 @@ def main(): @@ -2394,14 +2431,14 @@ def main():
2394 # For now, all logging is disabled: 2431 # For now, all logging is disabled:
2395 logging.disable(logging.CRITICAL) 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 # Old display with number of items detected: 2443 # Old display with number of items detected:
2407 # print '%-8s %-7s %-7s %-7s %-7s %-7s' % ('Type', 'Macros', 'AutoEx', 'Susp.', 'IOCs', 'HexStr') 2444 # print '%-8s %-7s %-7s %-7s %-7s %-7s' % ('Type', 'Macros', 'AutoEx', 'Susp.', 'IOCs', 'HexStr')
@@ -2436,7 +2473,7 @@ def main(): @@ -2436,7 +2473,7 @@ def main():
2436 print '\nFiles in %s:' % container 2473 print '\nFiles in %s:' % container
2437 previous_container = container 2474 previous_container = container
2438 # summarized output for triage: 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 count += 1 2477 count += 1
2441 if not options.detailed_mode or options.triage_mode: 2478 if not options.detailed_mode or options.triage_mode:
2442 print '\n(Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, TXT=Text, M=Macros, ' \ 2479 print '\n(Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, TXT=Text, M=Macros, ' \