def copyFromContainerWithLibs(self, filePath, outFolderPath): if ( not self.containerId ): self.logger.error("Trying to copy file from non-running container! self.containerId: %s", self.containerId) return False originalCmd = "sudo docker {} cp -L {}:{} {}" cmd = originalCmd.format(self.remote, self.containerId, filePath, outFolderPath) returncode, out, err = util.runCommand(cmd) tempFilePath = filePath if ( returncode != 0 ): self.logger.debug("Error copying from docker. Starting to check for file in environment paths. dockerId: %s, filePath: %s, outputFolderPath: %s Error message: %s", self.containerId, filePath, outFolderPath, err) cmd = "sudo docker exec -it {} echo $PATH" cmd = cmd.format(self.containerId) returncode, envPaths, err = util.runCommand(cmd) if ( returncode != 0 ): self.logger.debug("Error running echo PATH command on docker: %s, forfeiting file: %s", err, filePath) return False envPaths = envPaths.split(":") for envPath in envPaths: envPath = envPath.strip() filePath = envPath + "/" + tempFilePath cmd = originalCmd.format(self.remote, self.containerId, filePath, outFolderPath) returncode, out, err = util.runCommand(cmd) if ( returncode == 0 ): tempFilePath = filePath break if ( filePath != tempFilePath ): #Use it as an identifier of having been able to find file in one of the env. paths or not return False if ( tempFilePath.strip() != "" and util.isFolder(outFolderPath + "/" + util.getNameWithExtFromPath(tempFilePath)) ): folderPath = outFolderPath + "/" + util.getNameWithExtFromPath(tempFilePath) util.deleteFolder(folderPath, self.logger) return True return self.extractLibsFromBinary(filePath, outFolderPath)
def extractCronJobs(self, tempOutputFolder): if (not self.containerId): self.logger.error( "Trying to extract list of cron jobs from non-running container! self.containerId: %s", self.containerId) return None processList = [] cmd = "sudo docker {} exec -it {} echo $PATH" cmd = cmd.format(self.remote, self.containerId) returncode, envPaths, err = util.runCommand(cmd) if (returncode != 0): self.logger.error("Error running echo PATH command on docker: %s", err) return None cronFolderPath = "/etc/cron*" cmd = util.getCmdRetrieveAllShellScripts(cronFolderPath) cmd = "sudo docker {} exec -it {} " + cmd cmd = cmd.format(self.remote, self.containerId) self.logger.debug("Running command: %s", cmd) returncode, out, err = util.runCommand(cmd) splittedOut = out.splitlines() for scriptFilePath in splittedOut: scriptFilePath = scriptFilePath[:scriptFilePath.index(":")] self.logger.debug("Found script file: %s", scriptFilePath) self.copyFromContainer(scriptFilePath, tempOutputFolder) scriptFilePath = tempOutputFolder + "/" + util.getNameWithExtFromPath( scriptFilePath) processList.extend( self.extractProcessListFromShellScript(envPaths, scriptFilePath, tempOutputFolder)) return processList
def extractRunningServices(self, tempOutputFolder): if ( not self.containerId ): self.logger.error("Trying to extract list of running services on non-running container! self.containerId: %s", self.containerId) return None processList = [] cmd = "sudo docker {} exec -it {} echo $PATH" cmd = cmd.format(self.remote, self.containerId) returncode, envPaths, err = util.runCommand(cmd) if ( returncode != 0 ): self.logger.error("Error running echo PATH command on docker: %s", err) return None self.logger.info("Running service snapshot") cmd = "sudo docker {} exec -it {} ps auxww" cmd = cmd.format(self.remote, self.containerId) returncode, out, err = util.runCommand(cmd) if ( returncode != 0 ): self.logger.error("Error running service snapshot on docker: %s", err) return None outLines = out.splitlines() cmdIndex = 10 for line in outLines[1:]: splittedLine = line.split() if ( cmdIndex < len(splittedLine) ): if ( splittedLine[cmdIndex].strip().startswith("runsvdir") ): #TODO Handle runsvdir cmdComplete = splittedLine[cmdIndex:] cmdComplete = ' '.join(cmdComplete) serviceFolderPath = util.extractCommandArgument(cmdComplete, "-P") self.logger.debug("Handling runsvdir process special case, serviceFolder: %s", serviceFolderPath) if ( serviceFolderPath ): cmd = util.getCmdRetrieveAllShellScripts(serviceFolderPath) cmd = "sudo docker {} exec -it {} " + cmd cmd = cmd.format(self.remote, self.containerId) self.logger.debug("Running command: %s", cmd) returncode, out, err = util.runCommand(cmd) splittedOut = out.splitlines() for scriptFilePath in splittedOut: scriptFilePath = scriptFilePath[:scriptFilePath.index(":")] self.logger.debug("Found script file: %s", scriptFilePath) self.copyFromContainer(scriptFilePath, tempOutputFolder) scriptFilePath = tempOutputFolder + "/" + util.getNameWithExtFromPath(scriptFilePath) processList.extend(self.extractProcessListFromShellScript(envPaths, scriptFilePath, tempOutputFolder)) elif ( splittedLine[cmdIndex].strip().startswith("runsv") ): #TODO Handle runsv continue else: self.logger.warning("ps output header has Command at index: %d, but current line: %s doesn't have that index!", cmdIndex, line) return processList
def extractEntryPointDependencies(self, outFolderPath): if (not self.containerId): self.logger.error( "Trying to extract contents of entrypoint script on non-running container! self.containerId: %s", self.containerId) return None processList = [] self.logger.info("Extracting entrypoint dependencies.") cmd = "sudo docker {} inspect {}" cmd = cmd.format(self.remote, self.imageName) returncode, out, err = util.runCommand(cmd) if (returncode != 0): self.logger.error( "Error running entrypoint extraction on docker: %s", err) return None out = out.strip() out = out[1:-1] entrypointJson = json.loads(out) entrypointVal = None cmdVal = None envVal = None if (entrypointJson.get("ContainerConfig", None)): if (entrypointJson["ContainerConfig"].get("Entrypoint", None)): entrypointVal = entrypointJson["ContainerConfig"]["Entrypoint"] entrypointVal = entrypointVal[0].strip() if (entrypointJson["ContainerConfig"].get("Env", None)): for envItem in entrypointJson["ContainerConfig"]["Env"]: self.logger.debug("envItem: %s", envItem) splittedEnvItem = envItem.split("=") if (splittedEnvItem[0] == "PATH"): envVal = splittedEnvItem[1] if (not entrypointVal and entrypointJson.get("Config", None)): if (entrypointJson["Config"].get("Entrypoint", None)): entrypointVal = entrypointJson["Config"]["Entrypoint"] entrypointVal = entrypointVal[0].strip() if (entrypointJson["Config"].get("Cmd", None)): cmdVal = entrypointJson["Config"]["Cmd"] cmdVal = cmdVal[0].strip() if (not envVal and entrypointJson.get("Config", None)): if (entrypointJson["Config"].get("Env", None)): for envItem in entrypointJson["Config"]["Env"]: self.logger.debug("envItem: %s", envItem) splittedEnvItem = envItem.split("=") if (splittedEnvItem[0] == "PATH"): envVal = splittedEnvItem[1] if (entrypointVal): entrypointFile = "" if (entrypointVal.startswith("[")): entrypointVal = entrypointVal[1:] if (entrypointVal.endswith("]")): entrypointVal = entrypointVal[:-1] if ("\"" in entrypointVal): entrypointVal = entrypointVal.replace("\"", "") if (self.copyFromContainer(entrypointVal, outFolderPath)): entrypointFile = outFolderPath + "/" + util.getNameWithExtFromPath( entrypointVal) self.logger.debug("Setting entrypointFile: %s / %s", outFolderPath, util.getNameWithExtFromPath(entrypointVal)) self.logger.debug("Setting entrypointFile: %s", entrypointFile) elif (envVal): splittedEnvPaths = envVal.split(":") for envPath in splittedEnvPaths: if (self.copyFromContainer(envPath + "/" + entrypointVal, outFolderPath)): entrypointFile = outFolderPath + "/" + util.getNameWithExtFromPath( envPath + "/" + entrypointVal) self.logger.debug( "Setting entrypointFile: %s / %s", outFolderPath, util.getNameWithExtFromPath(envPath + "/" + entrypointVal)) self.logger.debug("Setting entrypointFile: %s", entrypointFile) break else: self.logger.error("Can't copy entrypoint file...") if (entrypointFile != ""): processList = self.extractProcessListFromShellScript( envVal, entrypointFile, outFolderPath) return processList