def main(argv):

    logLevel = "INFO"
    # initialize macro_pack session object
    mpSession = mp_session.MpSession(WORKING_DIR, VERSION, MP_TYPE)

    try:
        longOptions = [
            "embed=", "listen=", "generate=", "quiet", "input-file=", "encode",
            "obfuscate", "obfuscate-form", "obfuscate-names",
            "obfuscate-strings", "file=", "template=", "start-function=", "dde"
        ]
        shortOptions = "e:l:s:f:t:G:hqmo"
        # only for Pro release
        if MP_TYPE == "Pro":
            longOptions.extend([
                "vbom-encode", "persist", "keep-alive", "av-bypass", "trojan=",
                "stealth", "dcom="
            ])
            shortOptions += "T:"
        # Only enabled on windows
        if sys.platform == "win32":
            longOptions.extend(["run="])

        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.listenPort = int(arg)
        elif opt == "-f" or opt == "--input-file":
            mpSession.vbaInput = arg
        elif opt == "-e" or opt == "--embed":
            mpSession.embeddedFilePath = os.path.abspath(arg)
        elif opt == "-t" or opt == "--template":
            if arg is None or arg.startswith(
                    "-") or arg == "help" or arg == "HELP":
                help.printTemplatesUsage(BANNER, sys.argv[0])
                sys.exit(0)
            else:
                mpSession.template = arg
        elif opt == "-q" or opt == "--quiet":
            logLevel = "ERROR"
        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 in ("-G", "--generate"):
            mpSession.outputFilePath = os.path.abspath(arg)
        elif opt == "-h" or opt == "--help":
            help.printUsage(BANNER, sys.argv[0], mpSession)
            sys.exit(0)
        else:
            if MP_TYPE == "Pro":
                if opt == "--vbom-encode":
                    mpSession.vbomEncode = True
                elif opt == "--persist":
                    mpSession.persist = True
                elif opt == "--keep-alive":
                    mpSession.keepAlive = True
                elif opt == "--av-bypass":
                    mpSession.avBypass = True
                elif opt == "-T" or opt == "--trojan":
                    # Document generation enabled only on windows
                    if sys.platform == "win32":
                        mpSession.outputFilePath = os.path.abspath(arg)
                        mpSession.trojan = True
                elif opt == "--stealth":
                    mpSession.stealth = True
                elif opt == "--dcom":
                    mpSession.dcom = True
                    mpSession.dcomTarget = arg
                else:
                    help.printUsage(BANNER, sys.argv[0], mpSession)
                    sys.exit(0)
            else:
                help.printUsage(BANNER, sys.argv[0], mpSession)
                sys.exit(0)

    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.vbaInput 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()
    else:
        if not os.path.isfile(mpSession.vbaInput):
            logging.error("   [!] ERROR: Could not find %s!" %
                          mpSession.vbaInput)
            sys.exit(2)
        else:
            logging.info("   [-] Input file path: %s" % mpSession.vbaInput)

    if mpSession.trojan == False:
        # verify that output file does not already exist
        if mpSession.outputFilePath is not None:
            if os.path.isfile(mpSession.outputFilePath):
                logging.error("   [!] ERROR: Output file %s already exist!" %
                              mpSession.outputFilePath)
                sys.exit(2)
    else:
        # In trojan mod, file are tojane if they already exist and created if they dont.
        # except for vba output which is not concerned by trojan feature
        if mpSession.outputFilePath is not None and mpSession.outputFileType == MSTypes.VBA:
            if mpSession.outputFilePath is not None:
                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_DIR)
    if not os.path.exists(WORKING_DIR):
        os.makedirs(WORKING_DIR)

    try:

        # Create temporary work file.
        if mpSession.ddeMode or mpSession.template:
            inputFile = os.path.join(WORKING_DIR, "command.cmd")
        else:
            inputFile = os.path.join(WORKING_DIR,
                                     utils.randomAlpha(9)) + ".vba"
        if mpSession.stdinContent is not None:
            logging.info("   [-] Store std input in file...")
            f = open(inputFile, 'w')
            f.writelines(mpSession.stdinContent)
            f.close()
        else:
            # Create temporary work file
            if mpSession.vbaInput is not None:
                logging.info("   [-] Store input file...")
                shutil.copy2(mpSession.vbaInput, inputFile)
        if os.path.isfile(inputFile):
            logging.info("   [-] Temporary input file: %s" % inputFile)
        # Check output file format
        if mpSession.outputFilePath:
            logging.info("   [-] Target output format: %s" %
                         mpSession.outputFileType)

        # Generate template
        if mpSession.template:
            if MP_TYPE == "Pro":
                generator = TemplateGeneratorPro(mpSession)
                generator.run()
            else:
                generator = TemplateToVba(mpSession)
                generator.run()

        # MS Office generation/trojan is only enabled on windows
        if sys.platform == "win32":

            if mpSession.stealth == True:
                # Add a new empty module to keep VBA library if we hide other modules
                # See http://seclists.org/fulldisclosure/2017/Mar/90
                genericModule = mp_module.MpModule(mpSession)
                genericModule.addVBAModule("")

            if mpSession.trojan == False:
                if MSTypes.XL in mpSession.outputFileType:
                    generator = ExcelGenerator(mpSession)
                    generator.run()
                elif MSTypes.WD in mpSession.outputFileType:
                    generator = WordGenerator(mpSession)
                    generator.run()
                elif MSTypes.PPT in mpSession.outputFileType:
                    generator = PowerPointGenerator(mpSession)
                    generator.run()
                elif MSTypes.MPP == mpSession.outputFileType:
                    generator = MSProjectGenerator(mpSession)
                    generator.run()
                elif MSTypes.VSD in mpSession.outputFileType:
                    generator = VisioGenerator(mpSession)
                    generator.run()
                elif MSTypes.PUB == mpSession.outputFileType and MP_TYPE == "Pro":
                    generator = PublisherGenerator(mpSession)
                    generator.run()
            else:
                if MSTypes.XL in mpSession.outputFileType:
                    if os.path.isfile(mpSession.outputFilePath):
                        generator = ExcelTrojan(mpSession)
                        generator.run()
                    else:
                        generator = ExcelGenerator(mpSession)
                        generator.run()
                if MSTypes.WD in mpSession.outputFileType:
                    if os.path.isfile(mpSession.outputFilePath):
                        generator = WordTrojan(mpSession)
                        generator.run()
                    else:
                        generator = WordGenerator(mpSession)
                        generator.run()
                if MSTypes.PPT in mpSession.outputFileType:
                    if os.path.isfile(mpSession.outputFilePath):
                        generator = PptTrojan(mpSession)
                        generator.run()
                    else:
                        generator = PowerPointGenerator(mpSession)
                        generator.run()
                if MSTypes.VSD in mpSession.outputFileType:
                    if os.path.isfile(mpSession.outputFilePath):
                        generator = VisioTrojan(mpSession)
                        generator.run()
                    else:
                        generator = VisioGenerator(mpSession)
                        generator.run()

                if MSTypes.MPP in mpSession.outputFileType:
                    if os.path.isfile(mpSession.outputFilePath):
                        generator = MsProjectTrojan(mpSession)
                        generator.run()
                    else:
                        generator = MSProjectGenerator(mpSession)
                        generator.run()

            if mpSession.stealth == True:
                obfuscator = Stealth(mpSession)
                obfuscator.run()

            if mpSession.ddeMode:  # DDE Attack mode
                if MSTypes.WD in mpSession.outputFileType:
                    generator = WordDDE(mpSession)
                    generator.run()
                else:
                    logging.warn(
                        " [!] Word and Word97 are only format supported for DDE attacks."
                    )

            if mpSession.runTarget:  #run com attack
                generator = ComGenerator(mpSession)
                generator.run()

            if mpSession.dcom:  #run dcom attack
                generator = DcomGenerator(mpSession)
                generator.run()

        if mpSession.outputFileType == MSTypes.VBS:
            generator = VBSGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.HTA:
            generator = HTAGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.SCT:
            generator = SCTGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.VBA or mpSession.outputFilePath == None:
            generator = VBAGenerator(mpSession)
            generator.run()

        if mpSession.listen:
            listener = ListenServer(mpSession)
            listener.run()

    except Exception:
        logging.exception(" [!] Exception caught!")
        logging.error(
            " [!] Hints: Check if MS office is really closed and Antivirus did not catch the files"
        )
        if sys.platform == "win32":
            logging.error(
                " [!] Attempt to force close MS Office applications...")
            objExcel = win32com.client.Dispatch("Excel.Application")
            objExcel.Application.Quit()
            del objExcel
            objWord = win32com.client.Dispatch("Word.Application")
            objWord.Application.Quit()
            del objWord
            ppt = win32com.client.Dispatch("PowerPoint.Application")
            ppt.Quit()
            del ppt

    logging.info(" [+] Cleaning...")
    shutil.rmtree(WORKING_DIR)

    logging.info(" Done!\n")

    sys.exit(0)
Exemple #2
0
def expose_ls2(commands):
    if commands[0] == 'ls':
        commands.pop(0)

    for arg in commands:
        if arg in ['-a', '--all']:
            printcmd(
                arg, '''
  do not ignore entries starting with .
            ''')
        elif arg == '-A' or arg == '--almost-all':
            printcmd(arg, '''
  do not list implied . and ..
            ''')
        elif arg == '--author':
            printcmd(
                arg, '''
  with -l, print the author of each file
            ''')
        elif arg == '-b' or arg == '--escape':
            printcmd(
                arg, '''
            print C-style escapes for nongraphic characters
            ''')
        elif arg.startswith('--block-size='):
            printcmd(
                arg, '''
  scale   sizes   by   SIZE   before   printing    them.     E.g.,
  '--block-size=M'  prints sizes in units of 1,048,576 bytes.  See
  SIZE format below.
            ''')
        elif arg in ['-B', '--ignore-backups']:
            printcmd(
                arg, '''
  do not list implied entries ending with ~
            ''')
        elif arg == '-c':
            printcmd(
                arg, '''
  with -lt: sort by, and show, ctime (time of last modification of
  file  status  information)  with -l: show ctime and sort by name
  otherwise: sort by ctime, newest first
              ''')
        elif arg == '-C':
            printcmd(arg, '''
  list entries by columns
            ''')
        elif arg.startswith('--color'):
            printcmd(
                arg, '''
  colorize the output.   WHEN  defaults  to  'always'  or  can  be
  'never' or 'auto'.  More info below
              ''')
        elif arg in ['-d', '--directory']:
            printcmd(
                arg, '''
  list  directory entries instead of contents, and do not derefer-
  ence symbolic links
            ''')
        elif arg in ['-D', '--dired']:
            printcmd(
                arg, '''
  generate output designed for Emacs' dired mode
            ''')
        elif arg == '-f':
            printcmd(
                arg, '''
  do not sort, enable -aU, disable -ls --color
            ''')
        elif arg in ['-F', '--classify']:
            printcmd(
                arg, '''
  append indicator (one of */=>@|) to entries
            ''')
        elif arg == '--file-type':
            printcmd(arg, """
  likewise, except do not append '*'
            """)
        elif arg.startswith('--format'):
            printcmd(
                arg, '''
  across -x, commas -m, horizontal -x, long -l, single-column  -1,
  verbose -l, vertical -C
            ''')
        elif arg == '--full-time':
            printcmd(arg, '''
  like -l --time-style=full-iso
            ''')
        elif arg == '-g':
            printcmd(arg, '''
  like -l, but do not list owner
            ''')
        elif arg == '--group-directories-first':
            printcmd(
                arg, '''
  group directories before files.
  
  augment  with  a  --sort option, but any use of --sort=none (-U)
  disables grouping
            ''')
        elif arg in ['-G', '--no-group']:
            printcmd(
                arg, '''
  in a long listing, don't print group names
            ''')
        elif arg in ['-h', '--human-readable']:
            printcmd(
                arg, '''
  with -l, print sizes in human readable format (e.g., 1K 234M 2G)
            ''')
        elif arg == '--si':
            printcmd(
                arg, '''
  likewise (as -h), but use powers of 1000 not 1024
            ''')
        elif arg in ['-H', '--dereference-command-line']:
            printcmd(
                arg, '''
  follow symbolic links listed on the command line
            ''')
        elif arg == '--dereference-command-line-symlink-to-dir':
            printcmd(
                arg, '''
  follow each command line symbolic link that points to  a  direc-
  tory
            ''')
        elif arg.startswith('--hide='):
            printcmd(
                arg, '''
  do  not  list implied entries matching shell PATTERN (overridden
  by -a or -A)
            ''')
        elif arg.startswith('--indicator-style='):
            printcmd(
                arg, '''
  append indicator with style WORD to entry names: none (default),
  slash (-p), file-type (--file-type), classify (-F)
            ''')
        elif arg in ['-i', '--inode']:
            printcmd(
                arg, '''
  print the index number of each file
            ''')
        elif arg == '-I' or arg.startswith('--ignore='):
            printcmd(
                arg, '''
  do not list implied entries matching shell PATTERN
            ''')
        elif arg in ['-k', '--kibibytes']:
            printcmd(arg, '''
  use 1024-byte blocks
            ''')
        elif arg == '-l':
            printcmd(arg, '''
  use a long listing format
            ''')
        elif arg in ['-L', '--dereference']:
            printcmd(
                arg, '''
  when showing file information for a symbolic link, show informa-
  tion for the file the link references rather than for  the  link
  itself
            ''')
        elif arg == '-m':
            printcmd(
                arg, '''
  fill width with a comma separated list of entries
            ''')
        elif arg in ['-n', '--numeric-uid-gid']:
            printcmd(
                arg, '''
  like -l, but list numeric user and group IDs
            ''')
        elif arg in ['-N', '--literal']:
            printcmd(
                arg, '''
  print  raw entry names (don't treat e.g. control characters spe-
  cially)
            ''')
        elif arg == '-o':
            printcmd(
                arg, '''
  like -l, but do not list group information
            ''')
        elif arg == '-p' or arg.startswith('--indicator-style='):
            printcmd(arg, '''
  append / indicator to directories
            ''')
        elif arg in ['-q', '--hide-control-chars']:
            printcmd(
                arg, '''
  print ? instead of non graphic characters
            ''')
        elif arg == '--show-control-chars':
            printcmd(
                arg, '''
  show non graphic characters as-is  (default  unless  program  is
  'ls' and output is a terminal)
            ''')
        elif arg in ['-Q', '--quote-name']:
            printcmd(
                arg, '''
  enclose entry names in double quotes
            ''')
        elif arg.startswith('--quoting-style='):
            printcmd(
                arg, '''
  use  quoting style WORD for entry names: literal, locale, shell,
  shell-always, c, escape
            ''')
        elif arg in ['-r', '--reverse']:
            printcmd(arg, '''
  reverse order while sorting
            ''')
        elif arg in ['-R', '--recursive']:
            printcmd(arg, '''
  list subdirectories recursively
            ''')
        elif arg in ['-s', '--size']:
            printcmd(
                arg, '''
  print the allocated size of each file, in blocks
            ''')
        elif arg == '-S':
            printcmd(arg, '''
  sort by file size
            ''')
        elif arg.startswith('--sort='):
            printcmd(
                arg, '''
  sort by WORD instead of name: none -U, extension  -X,  size  -S,
  time -t, version -v
            ''')
        elif arg.startswith('--time='):
            printcmd(
                arg, '''
  with  -l,  show time as WORD instead of modification time: atime
  -u, access -u, use -u, ctime -c, or  status  -c;  use  specified
  time as sort key if --sort=time
            ''')
        elif arg.startswith('--time-style='):
            printcmd(
                arg, '''
  with  -l, show times using style STYLE: full-iso, long-iso, iso,
  locale, +FORMAT.  FORMAT is interpreted like 'date';  if  FORMAT
  is  FORMAT1<newline>FORMAT2, FORMAT1 applies to non-recent files
  and FORMAT2 to recent files; if STYLE is prefixed with 'posix-',
  STYLE takes effect only outside the POSIX locale
            ''')
        elif arg == '-t':
            printcmd(
                arg, '''
  sort by modification time, newest first
            ''')
        elif arg == '-T' or arg.startswith('--tabsize='):
            printcmd(
                arg, '''
  assume tab stops at each COLS instead of 8
            ''')
        elif arg == '-u':
            printcmd(
                arg, '''
  with  -lt:  sort  by, and show, access time with -l: show access
  time and sort by name otherwise: sort by access time
            ''')
        elif arg == '-U':
            printcmd(
                arg, '''
  do not sort; list entries in directory order
            ''')
        elif arg == '-v':
            printcmd(
                arg, '''
  natural sort of (version) numbers within text
            ''')
        elif arg == '-w' or arg.startswith('--width='):
            printcmd(
                arg, '''
  assume screen width instead of current value
            ''')
        elif arg == '-x':
            printcmd(
                arg, '''
  list entries by lines instead of by columns
            ''')
        elif arg == '-X':
            printcmd(
                arg, '''
  sort alphabetically by entry extension
            ''')
        elif arg in ['-Z', '--context']:
            printcmd(
                arg, '''
  print any SELinux security context of each file
            ''')
        elif arg == '-1':
            printcmd(arg, '''
  list one file per line
            ''')
        elif arg == '--help':
            printcmd(arg, '''
  display this help and exit
            ''')
        elif arg == '--version':
            printcmd(
                arg, '''
  output version information and exit
            ''')
        # 'ls' can have options like '-lAF', which means same as '-l -A -F'.
        # compressed options
        elif arg.startswith('-'):
            if len(arg) == 2:
                printcmd(arg, 'Unknown or too new or error')
            else:
                # Separate and add '-' for example,
                # '-df' becomes ['-d', '-f']
                expose_ls2(['-' + c for c in arg[1:]])
        else:
            allmessage = '{0}'

            if arg == '.':
                message = '''
  current directory
                '''
            elif arg == '..':
                message = '''
  parent directory
                '''
            elif arg == '*':
                message = '''
  every file and directory, in case of directory, list content
  of the directory (not recursive unless '-R')
                '''
            elif arg.startswith('*'):
                message = '''
  every file and directory ends with '{}', in case of directory, 
  list content of the directory (not recursive unless '-R')
                '''.format(arg[1:])
            elif arg.endswith('*'):
                message = '''
  every file and directory starts with '{}', in case of directory, 
  list content of the directory (not recursive unless '-R')
                '''.format(arg[1:])
            elif '*' in arg:
                globArgs = arg.split('*')
                globLen = len(globArgs)
                if globLen == 2:
                    message = '''
  every file and directory starts with '{}' and ends with '{}', 
  in case of directory, list content  of the directory (not 
  recursive unless '-R')
                    '''.format(globArgs[0], globArgs[1])
                else:
                    message = '''
  every files and directory satisfies the glob, in case of directory, 
  list content of the directory (not recursive unless '-R')
                    '''
            else:
                message = arg

            printcmd(arg, allmessage.format(message))
Exemple #3
0
def main(argv):

    logLevel = "INFO"
    # initialize macro_pack session object
    mpSession = mp_session.MpSession(WORKING_DIR, VERSION, MP_TYPE)

    try:
        longOptions = [
            "embed=", "listen=", "port=", "webdav-listen=", "generate=",
            "quiet", "input-file=", "encode", "obfuscate", "obfuscate-form",
            "obfuscate-names", "obfuscate-strings", "file=", "template=",
            "start-function=", "unicode-rtlo=", "dde", "print"
        ]
        shortOptions = "e:l:w:s:f:t:G:hqmop"
        # only for Pro release
        if MP_TYPE == "Pro":
            longOptions.extend([
                "vbom-encode", "persist", "keep-alive", "av-bypass", "trojan=",
                "stealth", "dcom=", "background"
            ])
            shortOptions += "T:b"
        # Only enabled on windows
        if sys.platform == "win32":
            longOptions.extend(["run="])

        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 = arg
        elif opt == "--port":
            mpSession.listenPort = int(arg)
            mpSession.WlistenPort = int(arg)
        elif opt == "-w" or opt == "--webdav-listen":
            mpSession.Wlisten = True
            mpSession.WRoot = arg
        elif opt == "-f" or opt == "--input-file":
            mpSession.vbaInput = arg
        elif opt == "-e" or opt == "--embed":
            mpSession.embeddedFilePath = os.path.abspath(arg)
        elif opt == "-t" or opt == "--template":
            if arg is None or arg.startswith(
                    "-") or arg == "help" or arg == "HELP":
                help.printTemplatesUsage(BANNER, sys.argv[0])
                sys.exit(0)
            else:
                mpSession.template = arg
        elif opt == "-q" or opt == "--quiet":
            logLevel = "ERROR"
        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 == "--unicode-rtlo":
            mpSession.unicodeRtlo = arg
        elif opt in ("-G", "--generate"):
            mpSession.outputFilePath = os.path.abspath(arg)
        elif opt == "-h" or opt == "--help":
            help.printUsage(BANNER, sys.argv[0], mpSession)
            sys.exit(0)
        else:
            if MP_TYPE == "Pro":
                if opt == "--vbom-encode":
                    mpSession.vbomEncode = True
                elif opt == "--persist":
                    mpSession.persist = True
                elif opt == "--keep-alive":
                    mpSession.keepAlive = True
                elif opt == "--av-bypass":
                    mpSession.avBypass = True
                elif opt == "-T" or opt == "--trojan":
                    # Document generation enabled only on windows
                    if sys.platform == "win32":
                        mpSession.outputFilePath = os.path.abspath(arg)
                        mpSession.trojan = True
                elif opt == "-b" or opt == "--background":
                    mpSession.background = True
                elif opt == "--stealth":
                    mpSession.stealth = True
                elif opt == "--dcom":
                    mpSession.dcom = True
                    mpSession.dcomTarget = arg
                else:
                    help.printUsage(BANNER, sys.argv[0], mpSession)
                    sys.exit(0)
            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 output file format
    if mpSession.outputFilePath:
        logging.info("   [-] Target output format: %s" %
                     mpSession.outputFileType)
    elif mpSession.listen == False and mpSession.Wlisten == False and mpSession.runTarget is None and mpSession.dcomTarget is None:
        logging.error("   [!] You need to provide an output file! (-G option)")
        sys.exit(2)

    # Edit outputfile name to spoof extension if unicodeRtlo option is enabled
    if mpSession.unicodeRtlo:
        logging.info("   [-] Inject %s false extension with unicode RTLO" %
                     mpSession.unicodeRtlo)
        # Separate document and extension
        (fileName, fileExtension) = os.path.splitext(mpSession.outputFilePath)
        # Append unicode RTLO to file name
        fileName += '\u202e'
        # Append extension to spoof in reverse order
        fileName += mpSession.unicodeRtlo[::-1]
        # Appent file extension
        fileName += fileExtension
        mpSession.outputFilePath = fileName
        logging.info("   [-] File name modified to: %s" %
                     mpSession.outputFilePath)

    # check input args
    if mpSession.vbaInput 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()
            sys.stdin = sys.__stdin__
    else:
        if not os.path.isfile(mpSession.vbaInput):
            logging.error("   [!] ERROR: Could not find %s!" %
                          mpSession.vbaInput)
            sys.exit(2)
        else:
            logging.info("   [-] Input file path: %s" % mpSession.vbaInput)

    if mpSession.trojan == 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)
    else:
        # In trojan mod, file are tojane if they already exist and created if they dont.
        # Thid concerns only non OFfice documents for now
        if mpSession.outputFileType not in MSTypes.MS_OFFICE_FORMATS:
            if os.path.isfile(mpSession.outputFilePath):
                logging.error(
                    "   [!] ERROR: Trojan mode not supported for %s format. \nOutput file %s already exist!"
                    % (mpSession.outputFileType, mpSession.outputFilePath))
                sys.exit(2)

    #Create temporary folder
    logging.info("   [-] Temporary working dir: %s" % WORKING_DIR)
    if not os.path.exists(WORKING_DIR):
        os.makedirs(WORKING_DIR)

    try:
        # Create temporary work file.
        if mpSession.ddeMode or mpSession.template or (
                mpSession.outputFileType not in MSTypes.VB_FORMATS):
            inputFile = os.path.join(WORKING_DIR, "command.cmd")
        else:
            inputFile = os.path.join(WORKING_DIR,
                                     utils.randomAlpha(9)) + ".vba"
        if mpSession.stdinContent is not None:
            logging.info("   [-] Store std input in file...")
            f = open(inputFile, 'w')
            f.writelines(mpSession.stdinContent)
            f.close()
        else:
            # Create temporary work file
            if mpSession.vbaInput is not None:
                logging.info("   [-] Store input file...")
                shutil.copy2(mpSession.vbaInput, inputFile)
        if os.path.isfile(inputFile):
            logging.info("   [-] Temporary input file: %s" % inputFile)

        # Generate template
        if mpSession.template:
            if MP_TYPE == "Pro":
                generator = TemplateGeneratorPro(mpSession)
                generator.run()
            else:
                generator = TemplateToVba(mpSession)
                generator.run()

        # MS Office generation/trojan is only enabled on windows
        if sys.platform == "win32" and mpSession.outputFileType in MSTypes.MS_OFFICE_FORMATS:
            handleOfficeFormats(mpSession)

        if mpSession.outputFileType == MSTypes.VBS:
            generator = VBSGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.HTA:
            generator = HTAGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.SCT:
            generator = SCTGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.WSF:
            generator = WSFGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.VBA:
            generator = VBAGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.SCF:
            generator = SCFGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.XSL:
            generator = XSLGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.URL:
            generator = UrlShortcutGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.GLK:
            generator = GlkGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.LNK:
            generator = LNKGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.SETTINGS_MS:
            generator = SettingsShortcutGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.LIBRARY_MS:
            generator = LibraryShortcutGenerator(mpSession)
            generator.run()

        if mpSession.outputFileType == MSTypes.INF:
            generator = InfGenerator(mpSession)
            generator.run()

        #run com attack
        if mpSession.runTarget:
            generator = ComGenerator(mpSession)
            generator.run()

        #run dcom attack
        if mpSession.dcom:
            generator = DcomGenerator(mpSession)
            generator.run()

        # Activate Web server
        if mpSession.listen:
            listener = ListenServer(mpSession)
            listener.run()

        if mpSession.Wlisten:
            Wlistener = WListenServer(mpSession)
            Wlistener.run()

    except Exception:
        logging.exception(" [!] Exception caught!")

    logging.info(" [+] Cleaning...")
    shutil.rmtree(WORKING_DIR)

    logging.info(" Done!\n")

    sys.exit(0)
Exemple #4
0
def main(argv):

    logLevel = "INFO"
    # initialize macro_pack session object
    mpSession = mp_session.MpSession(WORKING_DIR, VERSION, MP_TYPE)

    try:
        longOptions = [
            "quiet", "input-file=", "vba-output=", "mask-strings", "encode",
            "obfuscate", "obfuscate-form", "obfuscate-names",
            "obfuscate-strings", "file=", "template=", "start-function=", "dde"
        ]
        # only for Pro release
        if MP_TYPE == "Pro":
            longOptions.extend([
                "vbom-encode", "persist", "keep-alive", "av-bypass", "trojan",
                "stealth"
            ])

        # Only enabled on windows
        if sys.platform == "win32":
            longOptions.extend([
                "excel-output=", "word-output=", "excel97-output=",
                "word97-output=", "ppt-output="
            ])

        opts, args = getopt.getopt(argv, "s:f:t:v:x:X:w:W:P:hqmo",
                                   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 == "-f" or opt == "--input-file":
            mpSession.vbaInput = arg
        elif opt == "-t" or opt == "--template":
            if arg is None or arg.startswith(
                    "-") or arg == "help" or arg == "HELP":
                help.printTemplatesUsage(BANNER, sys.argv[0])
                sys.exit(0)
            else:
                mpSession.template = arg
        elif opt == "-q" or opt == "--quiet":
            logLevel = "ERROR"
        elif opt == "-v" or opt == "--vba-output":
            mpSession.vbaFilePath = os.path.abspath(arg)
            mpSession.fileOutput = True
        elif opt == "--dde":
            if sys.platform == "win32":
                mpSession.ddeMode = True
        elif opt in ("-X", "--excel-output"):
            # Only enabled on windows
            if sys.platform == "win32":
                mpSession.excelFilePath = os.path.abspath(arg)
                mpSession.fileOutput = True
        elif opt in ("-W", "--word-output"):
            # Only enabled on windows
            if sys.platform == "win32":
                mpSession.wordFilePath = os.path.abspath(arg)
                mpSession.fileOutput = True
        elif opt in ("-x", "--excel97-output"):
            # Only enabled on windows
            if sys.platform == "win32":
                mpSession.excel97FilePath = os.path.abspath(arg)
                mpSession.fileOutput = True
        elif opt in ("-w", "--word97-output"):
            # Only enabled on windows
            if sys.platform == "win32":
                mpSession.word97FilePath = os.path.abspath(arg)
                mpSession.fileOutput = True
        elif opt in ("-P", "--ppt-output"):
            # Only enabled on windows
            if sys.platform == "win32":
                mpSession.pptFilePath = os.path.abspath(arg)
                mpSession.fileOutput = True
        elif opt == "-h" or opt == "--help":
            help.printUsage(BANNER, sys.argv[0], mpSession)
            sys.exit(0)
        else:
            if MP_TYPE == "Pro":
                if opt == "--vbom-encode":
                    mpSession.vbomEncode = True
                elif opt == "--persist":
                    mpSession.persist = True
                elif opt == "--keep-alive":
                    mpSession.keepAlive = True
                elif opt == "--av-bypass":
                    mpSession.avBypass = True
                elif opt == "--trojan":
                    mpSession.trojan = True
                elif opt == "--stealth":
                    mpSession.stealth = True
                else:
                    help.printUsage(BANNER, sys.argv[0], mpSession)
                    sys.exit(0)
            else:
                help.printUsage(BANNER, sys.argv[0], mpSession)
                sys.exit(0)

    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.vbaInput 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()
        else:
            logging.error("   [!] ERROR: No input provided")
            sys.exit(2)
    else:
        if not os.path.isfile(mpSession.vbaInput):
            logging.error("   [!] ERROR: Could not find %s!" %
                          mpSession.vbaInput)
            sys.exit(2)

    if mpSession.trojan == False:
        # verify that output file does not already exist
        for outputPath in [
                mpSession.vbaFilePath, mpSession.excelFilePath,
                mpSession.wordFilePath, mpSession.excel97FilePath,
                mpSession.word97FilePath, mpSession.pptFilePath
        ]:
            if outputPath is not None:
                if os.path.isfile(outputPath):
                    logging.error(
                        "   [!] ERROR: Output file %s already exist!" %
                        outputPath)
                    sys.exit(2)
    else:
        # In trojan mod, file are tojane if they already exist and created if they dont.
        # except for vba output which is not concerned by trojan feature
        for outputPath in [mpSession.vbaFilePath]:
            if outputPath is not None:
                if os.path.isfile(outputPath):
                    logging.error(
                        "   [!] ERROR: Output file %s already exist!" %
                        outputPath)
                    sys.exit(2)

    logging.info("   [-] Input file path: %s" % mpSession.vbaInput)
    #Create temporary folder
    logging.info("   [-] Temporary working dir: %s" % WORKING_DIR)
    if not os.path.exists(WORKING_DIR):
        os.makedirs(WORKING_DIR)

    try:

        logging.info("   [-] Store input file...")
        # Create temporary work file.
        if mpSession.ddeMode:
            inputFile = os.path.join(WORKING_DIR, "command.cmd")
        else:
            inputFile = os.path.join(WORKING_DIR,
                                     utils.randomAlpha(9)) + ".vba"
        if mpSession.stdinContent is not None:
            f = open(inputFile, 'w')
            f.writelines(mpSession.stdinContent)
            f.close()
        else:
            # Create temporary work file
            shutil.copy2(mpSession.vbaInput, inputFile)
        logging.info("   [-] Temporary file: %s" % inputFile)

        if mpSession.ddeMode:  # DDE Attack mode
            if mpSession.wordFilePath or mpSession.word97FilePath:
                generator = WordDDE(mpSession)
                generator.run()
        else:  # VBA macro mode

            # Generate template
            if mpSession.template:
                generator = TemplateToVba(mpSession)
                generator.run()

            # Macro obfuscation
            if mpSession.obfuscateNames:
                obfuscator = ObfuscateNames(mpSession)
                obfuscator.run()
            # Mask strings
            if mpSession.obfuscateStrings:
                obfuscator = ObfuscateStrings(mpSession)
                obfuscator.run()
            # Macro obfuscation
            if mpSession.obfuscateForm:
                obfuscator = ObfuscateForm(mpSession)
                obfuscator.run()

            if MP_TYPE == "Pro":
                #macro split
                if mpSession.avBypass:
                    obfuscator = AvBypass(mpSession)
                    obfuscator.run()

                # MAcro encoding
                if mpSession.vbomEncode:
                    obfuscator = VbomEncoder(mpSession)
                    obfuscator.run()

                    # PErsistance management
                    if mpSession.persist:
                        obfuscator = Persistance(mpSession)
                        obfuscator.run()
                    # Macro obfuscation
                    if mpSession.obfuscateNames:
                        obfuscator = ObfuscateNames(mpSession)
                        obfuscator.run()
                    # Mask strings
                    if mpSession.obfuscateStrings:
                        obfuscator = ObfuscateStrings(mpSession)
                        obfuscator.run()
                    # Macro obfuscation
                    if mpSession.obfuscateForm:
                        obfuscator = ObfuscateForm(mpSession)
                        obfuscator.run()
                else:
                    # PErsistance management
                    if mpSession.persist:
                        obfuscator = Persistance(mpSession)
                        obfuscator.run()

            # MS Office generation/trojan is only enabled on windows
            if sys.platform == "win32":

                if mpSession.stealth == True:
                    # Add a new empty module to keep VBA library if we hide other modules
                    # See http://seclists.org/fulldisclosure/2017/Mar/90
                    genericModule = mp_module.MpModule(mpSession)
                    genericModule.addVBAModule("")

                if mpSession.trojan == False:
                    if mpSession.excelFilePath or mpSession.excel97FilePath:
                        generator = ExcelGenerator(mpSession)
                        generator.run()
                    if mpSession.wordFilePath or mpSession.word97FilePath:
                        generator = WordGenerator(mpSession)
                        generator.run()
                    if mpSession.pptFilePath:
                        generator = PowerPointGenerator(mpSession)
                        generator.run()
                else:
                    if mpSession.excelFilePath:
                        if os.path.isfile(mpSession.excelFilePath):
                            generator = ExcelTrojan(mpSession)
                            generator.run()
                        else:
                            generator = ExcelGenerator(mpSession)
                            generator.run()
                    if mpSession.excel97FilePath:
                        if os.path.isfile(mpSession.excel97FilePath):
                            generator = ExcelTrojan(mpSession)
                            generator.run()
                        else:
                            generator = ExcelGenerator(mpSession)
                            generator.run()
                    if mpSession.wordFilePath:
                        if os.path.isfile(mpSession.wordFilePath):
                            generator = WordTrojan(mpSession)
                            generator.run()
                        else:
                            generator = WordGenerator(mpSession)
                            generator.run()
                    if mpSession.word97FilePath:
                        if os.path.isfile(mpSession.word97FilePath):
                            generator = WordTrojan(mpSession)
                            generator.run()
                        else:
                            generator = WordGenerator(mpSession)
                            generator.run()
                    if mpSession.pptFilePath:
                        if os.path.isfile(mpSession.pptFilePath):
                            generator = PptTrojan(mpSession)
                            generator.run()
                        else:
                            generator = PowerPointGenerator(mpSession)
                            generator.run()

                if mpSession.stealth == True:
                    obfuscator = Stealth(mpSession)
                    obfuscator.run()

            if mpSession.vbaFilePath is not None or mpSession.fileOutput == False:
                generator = VBAGenerator(mpSession)
                generator.run()
    except Exception:
        logging.exception(" [!] Exception caught!")
        logging.error(
            " [!] Hints: Check if MS office is really closed and Antivirus did not catch the files"
        )
        if sys.platform == "win32":
            logging.error(
                " [!] Attempt to force close MS Office applications...")
            objExcel = win32com.client.Dispatch("Excel.Application")
            objExcel.Application.Quit()
            del objExcel
            objWord = win32com.client.Dispatch("Word.Application")
            objWord.Application.Quit()
            del objWord
            ppt = win32com.client.Dispatch("PowerPoint.Application")
            ppt.Quit()
            del ppt

    logging.info(" [+] Cleaning...")
    shutil.rmtree(WORKING_DIR)
    logging.info(" Done!\n")

    sys.exit(0)