Exemple #1
0
    def symtask(cls, jobitem, symserver, symdest, symlocal):
        '''
        perform symbol search for symbols of jobfile. If there are no symbols or symbols found
        are already in db, discard results. Else, return found symbols
        '''
        symlogger = logging.getLogger("BAM.Pools.SymWkr")
        jobfile = jobitem[0]
        hashes = (jobfile[1], jobfile[2])

        result = None
        logmsg = "[SYMMGR].. Getting SYM for (" + str(jobfile) + ")"
        symlogger.log(logging.DEBUG, logmsg)
        servers = ""

        if symlocal:
            servers = " \""+ symdest + "\""
        else:
            servers = "u \"srv*" + symdest + "*" + symserver +"\""

        args = (".\\tools\\x64\\symchk.exe /v \"" + str(jobfile) + "\" /s" + servers + " /od")

        try:
            with subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) \
                    as psymchk:
                # communicate used as symchk's output is for one file and
                # is not "large or unlimited"
                pstdout, pstderr = psymchk.communicate()
                stdoutsplit = str(pstdout.decode("ascii")).split("\r\n")
                stderrsplit = str(pstderr.decode("ascii")).split("\r\n")

                logmsg = "[SYMMGR] Attempt to obtain symbols for " + str(jobfile) + " complete"
                symlogger.log(logging.DEBUG, logmsg)

                infolist = {}
                try:
                    unpefile = pefile.PE(jobfile)
                except pefile.PEFormatError as peerror:
                    logmsg = "[WSUS_DB] Caught: PE error " + str(peerror) + ". File: " + jobfile
                    symlogger.log(logging.ERROR, logmsg)
                    return result

                infolist['signature'] = getpesigwoage(unpefile)
                infolist['arch'] = getpearch(unpefile)

                unpefile.close()

                stderrsplit.append(symserver)
                result = ((str(jobfile), stderrsplit, stdoutsplit), hashes[0], hashes[1], infolist)
        except subprocess.CalledProcessError as error:
            logmsg = "[SYMMGR] {-} symchk failed with error: " + str(error) + ". File: " + jobfile
            symlogger.log(logging.ERROR, logmsg)
            result = None
        except FileNotFoundError as error:
            logmsg = ("[SYMMGR] {-} symchk.exe not found")
            symlogger.log(logging.ERROR, logmsg)
            result = None

        logmsg = "[SYMMGR] completed symtask for " + str(jobfile)
        symlogger.log(logging.DEBUG, logmsg)
        return result
Exemple #2
0
    def cleantask(cls, jobfile, updateid):
        '''
        task to clean up folder before submitting jobs for symbol search
        if item is removed in cleaning, None is returned, else return item
        '''
        clnlogger = logging.getLogger("BAM.Pools.ClnWkr")
        
        results = None

        logmsg = "[CLNMGR] Starting on " + str(jobfile)
        clnlogger.log(logging.DEBUG, logmsg)

        if ispe(jobfile):
            # check db to see if job already exists:
            hashes = getfilehashes(jobfile)

            if hashes is None:
                return hashes

            if wsuse_db.dbentryexistwithsymbols(globs.DBCONN.cursor(),     \
                                globs.PATCHEDFILESDBNAME, hashes[0], hashes[1]):
                # if PE is already in db with symbols obtained,
                # do not retask job to symbol manager, return None instead
                return results
            else:
                pass
                logmsg = "[CLNMGR] continuing forward with " + str(jobfile)
                clnlogger.log(logging.DEBUG, logmsg)

            # getting to this point means item is not in db, may need to come up
            # with case where db needs to update item though
            infolist = {
                    'OriginalFilename': '', 'FileDescription': '', 'ProductName': '',
                    'Comments': '', 'CompanyName': '', 'FileVersion': '',
                    'ProductVersion': '', 'IsDebug': '', 'IsPatched': '',
                    'IsPreReleased': '', 'IsPrivateBuild': '', 'IsSpecialBuild': '',
                    'Language': '', 'PrivateBuild': '', 'SpecialBuild': ''
                    }

            try:
                unpefile = pefile.PE(jobfile, fast_load=True)
            except pefile.PEFormatError as peerror:
                logmsg = "[WSUS_DB] skipping " + str(jobfile) + " due to exception: " + peerror.value
                clnlogger.log(logging.ERROR, logmsg)
                return results

            infolist['fileext'], infolist['stype'] = pebinarytype(unpefile)
            infolist['arch'] = getpearch(unpefile)
            infolist['age'] = getpeage(unpefile)
            infolist['strippedpe'] = ispedbgstripped(unpefile)
            infolist['builtwithdbginfo'] = ispebuiltwithdebug(unpefile)            

            direntires=[ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_DEBUG'],    \
                pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE'] ]
            unpefile.parse_data_directories(directories=direntires)
            infolist['pdbfilename'] = getpepdbfilename(unpefile)
            infolist['signature'] = getpesigwoage(unpefile)

            # a PE only have 1 VERSIONINFO, but multiple language strings
            # More information on different properites can be found at
            # https://msdn.microsoft.com/en-us/library/windows/desktop/aa381058
            # https://msdn.microsoft.com/en-us/library/windows/desktop/aa381049
            if getattr(unpefile, "VS_VERSIONINFO", None) is not None and \
                getattr(unpefile, "FileInfo", None) is not None:
                    for fileinfoentries in unpefile.FileInfo:
                        for fileinfoentry in fileinfoentries:
                            if getattr(fileinfoentry, "StringTable", None) is not None:
                                for strtable in fileinfoentry.StringTable:
                                    # Currently only handling unicode en-us
                                    if strtable.LangID[:4] == b'0409' or \
                                            (strtable.LangID[:4] == b'0000' and
                                            (strtable.LangID[4:] == b'04b0' or
                                            strtable.LangID[4:] == b'04B0')):
                                        infolist["Language"] \
                                            = strtable.LangID.decode("utf-8")
                                        for field, value in strtable.entries.items():
                                            dfield = field.decode('utf-8')
                                            dvalue = value.decode('utf-8')
                                            if dfield == "OriginalFilename":
                                                infolist["OriginalFilename"] \
                                                    = dvalue
                                            if dfield == "FileDescription":
                                                infolist["FileDescription"] \
                                                    = dvalue
                                            if dfield == "ProductName":
                                                infolist["ProductName"] \
                                                    = dvalue
                                            if dfield == "Comments":
                                                infolist["Comments"] \
                                                    = dvalue
                                            if dfield == "CompanyName":
                                                infolist["CompanyName"] \
                                                    = dvalue
                                            if dfield == "FileVersion":
                                                infolist["FileVersion"] \
                                                    = dvalue
                                            if dfield == "ProductVersion":
                                                infolist["ProductVersion"] \
                                                    = dvalue
                                            if dfield == "IsDebug":
                                                infolist["IsDebug"] \
                                                    = dvalue
                                            if dfield == "IsPatched":
                                                infolist["IsPatched"] \
                                                    = dvalue
                                            if dfield == "IsPreReleased":
                                                infolist["IsPreReleased"] \
                                                    = dvalue
                                            if dfield == "IsPrivateBuild":
                                                infolist["IsPrivateBuild"] \
                                                    = dvalue
                                            if dfield == "IsSpecialBuild":
                                                infolist["IsSpecialBuild"] \
                                                    = dvalue
                                            if dfield == "PrivateBuild":
                                                infolist["PrivateBuild"] \
                                                    = dvalue
                                            if dfield == "SpecialBuild":
                                                infolist["SpecialBuild"] \
                                                    = dvalue
            # Get the OS this PE is designed towards.
            # Microsoft PE files distributed via Microsoft's Updates typically
            # use the ProductVersion file properties to indicate the OS a specific
            # PE file is built towards.
            # If this is a Microsoft binary, the Product version is typically
            # the OS version it was built towards, but other products this is not
            # necessarily true
            if infolist['ProductName'].find("Operating System") != -1:
                infolist['osver'] = "NT" + infolist['ProductVersion']
            else:
                infolist['osver'] = "UNKNOWN"

            unpefile.close()

            results = ((str(jobfile), updateid), hashes[0], hashes[1], infolist)
        else:
            # if jobfile is not a PE, then check if it's a cab. If not a cab, remove it.
            if not validatecab(str(jobfile)):
                logmsg = "[CLNMGR] cleantask: Removing " + str(jobfile)
                clnlogger.log(logging.DEBUG, logmsg)

                rmfile(jobfile)

                logmsg = "[CLNMGR] " + str(jobfile) + " removed, not PE or cab file"
                clnlogger.log(logging.DEBUG, logmsg)
            else:
                pass
                logmsg = "[CLNMGR] " + str(jobfile) + " is nested cab, skipping"
                clnlogger.log(logging.DEBUG, logmsg)
            return results

        logmsg = "[CLNMGR] completed one cleantask for " + str(jobfile)
        clnlogger.log(logging.DEBUG, logmsg)

        return results