Commit 63ec91ed77bbc903936b260fcd5352859b9af4e8
1 parent
6569631d
olevba: join long VBA lines ending with underscore before scan, disabled unused option --each
Showing
1 changed file
with
27 additions
and
7 deletions
oletools/olevba.py
| @@ -142,15 +142,17 @@ https://github.com/unixfreak0037/officeparser | @@ -142,15 +142,17 @@ https://github.com/unixfreak0037/officeparser | ||
| 142 | # 2015-06-19 PL: - added options -a, -c, --each, --attr | 142 | # 2015-06-19 PL: - added options -a, -c, --each, --attr |
| 143 | # 2015-06-21 v0.32 PL: - always display decoded strings which are printable | 143 | # 2015-06-21 v0.32 PL: - always display decoded strings which are printable |
| 144 | # - fix VBA_Scanner.scan to return raw strings, not repr() | 144 | # - fix VBA_Scanner.scan to return raw strings, not repr() |
| 145 | -# 2015-07-09 v0.33 PL: - removed usage of sys.stderr which causes issues | 145 | +# 2015-07-09 v0.40 PL: - removed usage of sys.stderr which causes issues |
| 146 | # 2015-07-12 PL: - added Hex function decoding to VBA Parser | 146 | # 2015-07-12 PL: - added Hex function decoding to VBA Parser |
| 147 | # 2015-07-13 PL: - added Base64 function decoding to VBA Parser | 147 | # 2015-07-13 PL: - added Base64 function decoding to VBA Parser |
| 148 | # 2015-09-06 PL: - improved VBA_Parser, refactored the main functions | 148 | # 2015-09-06 PL: - improved VBA_Parser, refactored the main functions |
| 149 | # 2015-09-13 PL: - moved main functions to a class VBA_Parser_CLI | 149 | # 2015-09-13 PL: - moved main functions to a class VBA_Parser_CLI |
| 150 | # - fixed issue when analysis was done twice | 150 | # - fixed issue when analysis was done twice |
| 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 | ||
| 153 | +# - disabled unused option --each | ||
| 152 | 154 | ||
| 153 | -__version__ = '0.33' | 155 | +__version__ = '0.40' |
| 154 | 156 | ||
| 155 | #------------------------------------------------------------------------------ | 157 | #------------------------------------------------------------------------------ |
| 156 | # TODO: | 158 | # TODO: |
| @@ -1256,6 +1258,21 @@ def _extract_vba(ole, vba_root, project_path, dir_path): | @@ -1256,6 +1258,21 @@ def _extract_vba(ole, vba_root, project_path, dir_path): | ||
| 1256 | return | 1258 | return |
| 1257 | 1259 | ||
| 1258 | 1260 | ||
| 1261 | +def vba_collapse_long_lines(vba_code): | ||
| 1262 | + """ | ||
| 1263 | + Parse a VBA module code to detect continuation line characters (underscore) and | ||
| 1264 | + collapse split lines. Continuation line characters are replaced by spaces. | ||
| 1265 | + | ||
| 1266 | + :param vba_code: str, VBA module code | ||
| 1267 | + :return: str, VBA module code with long lines collapsed | ||
| 1268 | + """ | ||
| 1269 | + # TODO: use a regex instead, to allow whitespaces after the underscore? | ||
| 1270 | + vba_code = vba_code.replace(' _\r\n', ' ') | ||
| 1271 | + vba_code = vba_code.replace(' _\r', ' ') | ||
| 1272 | + vba_code = vba_code.replace(' _\n', ' ') | ||
| 1273 | + return vba_code | ||
| 1274 | + | ||
| 1275 | + | ||
| 1259 | def filter_vba(vba_code): | 1276 | def filter_vba(vba_code): |
| 1260 | """ | 1277 | """ |
| 1261 | Filter VBA source code to remove the first lines starting with "Attribute VB_", | 1278 | Filter VBA source code to remove the first lines starting with "Attribute VB_", |
| @@ -1473,7 +1490,8 @@ class VBA_Scanner(object): | @@ -1473,7 +1490,8 @@ class VBA_Scanner(object): | ||
| 1473 | 1490 | ||
| 1474 | :param vba_code: str, VBA source code to be analyzed | 1491 | :param vba_code: str, VBA source code to be analyzed |
| 1475 | """ | 1492 | """ |
| 1476 | - self.code = vba_code | 1493 | + # join long lines ending with " _": |
| 1494 | + self.code = vba_collapse_long_lines(vba_code) | ||
| 1477 | self.code_hex = '' | 1495 | self.code_hex = '' |
| 1478 | self.code_hex_rev = '' | 1496 | self.code_hex_rev = '' |
| 1479 | self.code_rev_hex = '' | 1497 | self.code_rev_hex = '' |
| @@ -2241,8 +2259,10 @@ def main(): | @@ -2241,8 +2259,10 @@ def main(): | ||
| 2241 | help='display all the obfuscated strings with their decoded content (Hex, Base64, StrReverse, Dridex, VBA).') | 2259 | help='display all the obfuscated strings with their decoded content (Hex, Base64, StrReverse, Dridex, VBA).') |
| 2242 | parser.add_option("--attr", action="store_false", dest="hide_attributes", default=True, | 2260 | parser.add_option("--attr", action="store_false", dest="hide_attributes", default=True, |
| 2243 | help='display the attribute lines at the beginning of VBA source code') | 2261 | help='display the attribute lines at the beginning of VBA source code') |
| 2244 | - parser.add_option("--each", action="store_false", dest="global_analysis", default=True, | ||
| 2245 | - help='analyze each VBA module separately') | 2262 | + |
| 2263 | + # Disabled options: | ||
| 2264 | + # parser.add_option("--each", action="store_false", dest="global_analysis", default=True, | ||
| 2265 | + # help='analyze each VBA module separately') | ||
| 2246 | 2266 | ||
| 2247 | # TODO: --novba to disable VBA expressions parsing | 2267 | # TODO: --novba to disable VBA expressions parsing |
| 2248 | 2268 | ||
| @@ -2294,7 +2314,7 @@ def main(): | @@ -2294,7 +2314,7 @@ def main(): | ||
| 2294 | if options.detailed_mode and not options.triage_mode: | 2314 | if options.detailed_mode and not options.triage_mode: |
| 2295 | # fully detailed output | 2315 | # fully detailed output |
| 2296 | vba_parser.process_file(show_decoded_strings=options.show_decoded_strings, | 2316 | vba_parser.process_file(show_decoded_strings=options.show_decoded_strings, |
| 2297 | - display_code=options.display_code, global_analysis=options.global_analysis, | 2317 | + display_code=options.display_code, global_analysis=True, #options.global_analysis, |
| 2298 | hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only) | 2318 | hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only) |
| 2299 | else: | 2319 | else: |
| 2300 | # print container name when it changes: | 2320 | # print container name when it changes: |
| @@ -2313,7 +2333,7 @@ def main(): | @@ -2313,7 +2333,7 @@ def main(): | ||
| 2313 | if count == 1 and not options.triage_mode and not options.detailed_mode: | 2333 | if count == 1 and not options.triage_mode and not options.detailed_mode: |
| 2314 | # if options -t and -d were not specified and it's a single file, print details: | 2334 | # if options -t and -d were not specified and it's a single file, print details: |
| 2315 | vba_parser.process_file(show_decoded_strings=options.show_decoded_strings, | 2335 | vba_parser.process_file(show_decoded_strings=options.show_decoded_strings, |
| 2316 | - display_code=options.display_code, global_analysis=options.global_analysis, | 2336 | + display_code=options.display_code, global_analysis=True, #options.global_analysis, |
| 2317 | hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only) | 2337 | hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only) |
| 2318 | 2338 | ||
| 2319 | 2339 |