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 | 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, ' \ | ... | ... |