Commit 43f6a95c32ab20471bd909210e973538f659e27f
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, ' \ |