Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Explode Module: EXPLODE_VBA #63

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions laikaboss/modules/explode_vba.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copyright 2017 Kemp Langhorne
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from laikaboss.si_module import SI_MODULE
from laikaboss.objectmodel import ModuleObject, ExternalVars, QuitScanException, \
GlobalScanTimeoutError, GlobalModuleTimeoutError
from laikaboss.util import log_module
from oletools import olevba

class EXPLODE_VBA(SI_MODULE):
'''
Version: 0.50

Input: Any supported format listed at https://bitbucket.org/decalage/oletools/wiki/olevba

Output: Extracted and decompressed VBA objects (macro and forms). Module also adds basic metadata about the object when possible.

Purpose: Uses olevba from oletools to extract embedded VBA macro and forms in various types of documents.

Note 1: olevba has many other features beyond just macro extraction. This module does only extraction.
Note 2: Test olevba.py (from decalage) against a known sample to verify you have decalage tools installed correctly

Example JSON output:

"EXPLODE_VBA": {
"Parsed_Macros_Metadata": [
{
"VBA_project": [
"('', 'PROJECT', 'VBA/dir')"
],
"OLE_stream": "VBA/Z1",
"Type": "OLE",
"VBA_filename": "Z1.bas"
}
],
"VBA_Forms_Found_Streams": [
"sTVOL/o"
]

Example of exploded file naming:
e_vba_a2a729ef454c64cd44377c2703f4222e_sTVOL.frm -> This is a macro
e_vba_a2a729ef454c64cd44377c2703f4222e_A0.bas -> This is a macro
e_vba_a2a729ef454c64cd44377c2703f4222e_combined_forms.txt -> This is a form


'''

def __init__(self,):
self.module_name = "EXPLODE_VBA"

def _run(self, scanObject, result, depth, args):
moduleResult = []
try:
vbaparser = olevba.VBA_Parser(scanObject.objectHash, data=scanObject.buffer) #load ole into olevba
if vbaparser.detect_vba_macros(): #VBA Macro Found
# Loop to parse VBA Macro
for (filename, stream_path, vba_filename, vba_code) in vbaparser.extract_macros(): # macro extraction
macrofilesdict = {}
macrofilesdict.update({'Type': vbaparser.type, 'VBA_project': vbaparser.vba_projects, 'OLE_stream': stream_path, 'VBA_filename': vba_filename})
scanObject.addMetadata(self.module_name, "Parsed_Macros_Metadata", macrofilesdict)
explodevbafilename = 'e_vba_%s_%s' % (scanObject.objectHash, vba_filename) # Exploded file name contains source hash
moduleResult.append(ModuleObject(buffer=vba_code, externalVars=ExternalVars(filename=explodevbafilename)))
# Loop to parse VBA Forms
combinedstring = ""
formfilesdlist = set()
for (filename, stream_path, form_string) in vbaparser.extract_form_strings():
formfilesdlist.add(stream_path) #set because stream_path could be the same over and over again
combinedstring += " %s" % form_string #combining all found forms text into a single variable
if combinedstring: #form text found
scanObject.addMetadata(self.module_name, "VBA_Forms_Found_Streams", formfilesdlist)
explodeformsfilename = 'e_vba_%s_combined_forms.txt' % (scanObject.objectHash)
moduleResult.append(ModuleObject(buffer=combinedstring, externalVars=ExternalVars(filename=explodeformsfilename)))
vbaparser.close()

except olevba.OlevbaBaseException as e: # exceptions from olevba import will raise
olevbaerror = 'e_vba:err:%s' % e
#scanObject.addFlag(olevbaerror)
log_module("MSG", self.module_name, 0, scanObject, result, olevbaerror)
except (QuitScanException, GlobalScanTimeoutError, GlobalModuleTimeoutError):
raise
return moduleResult