def __init__(self, compression='snappy'): if Config().PLATFORM == 'win': self.__binary = 'winpmem-2.1.post4.exe' self.__dumpfunc = self.__dump_win elif Config().PLATFORM == 'linux': self.__binary = 'linpmem-2.1.post4' self.__dumpfunc = self.__dump_linux elif Config().PLATFORM == 'osx': self.__binary = 'osxpmem-2.1.post4.zip' self.__dumpfunc = self.__dump_osx else: raise NotImplementedError() self.compression = compression
def dump(self): if callable(self.__dumpfunc): # Ensure the BINCACHE_DIR exists os.makedirs(Config().BINCACHE_DIR, exist_ok=True) return self.__dumpfunc(DataClient().get('http_blob', self.__binary)) raise NotImplementedError()
def __recursion_callback(self, item: Path): posix_path = item.as_posix() path = posix_path[3:] if Config( ).PLATFORM == 'win32' and posix_path[1] == ':' else posix_path for excl in self.config.get('EXCLUDE_DIRS'): if path.startswith(excl): return False return True
def __init__(self, platform=None): super(MonitorApp, self).__init__() self.report = [] self.config = DEFAULT_CONFIGS.get(platform, dict()) if Config().PLATFORM == 'unix': from epclib.event.linevt import LinuxEventMonitor self.monitor = LinuxEventMonitor() elif Config().PLATFORM == 'android': from epclib.event.androidevt import AndroidEventMonitor self.monitor = AndroidEventMonitor() elif Config().PLATFORM == 'win32': from epclib.event.winevt import WinEventMonitor self.monitor = WinEventMonitor() else: raise NotImplementedError() for event in Event: self.monitor.add_callback(event, partial(self.event_cb, event))
def __dump_win(self, data): with tempfile.NamedTemporaryFile(dir=Config().BINCACHE_DIR, suffix='.exe') as tmp: tmp.write(data) tmp.flush() with Popen([ tmp.name, '--acquire-memory', '--compression', self.compression, '--output', '-' ], stdout=PIPE, stderr=PIPE) as proc: # TODO: store/send the data pass
class App(object): """Base class for apps""" _runmode = 'thread' if Config().PLATFORM == 'android' else 'standalone' def __init__(self): self._thread = None self.__is_running = False self.logger = None @property def is_running(self): if self._runmode == "thread": return self._thread.isAlive() else: return self.__is_running def __run_t(self, *args, **kwargs) -> Optional[ThreadWithReturnValue]: if not kwargs: kwargs = {} target = getattr(self, '_run', None) if target and callable(target): self._thread = ThreadWithReturnValue(target=target, args=args, kwargs=kwargs) self._thread.start() return self._thread return None def run(self, args=(), kwargs=None): """Run the app""" if not kwargs: kwargs = {} if self._runmode == 'standalone': target = getattr(self, '_run', None) if target and callable(target): self.__is_running = True ret_code = target(*args, **kwargs) args[0].value = ret_code return ret_code elif self._runmode == 'thread': return self.__run_t(*args, **kwargs) return None def stop(self): """Stop the app""" stopfunc = getattr(self, '_stop', None) if stopfunc and callable(stopfunc): stopfunc() self.__is_running = False
def __get_winservice(self): """Retrieve windows service information""" if Config().PLATFORM != 'win32': raise NotImplementedError( "Cannot get Windows service information on a non-win32 system") data = [] for srv in psutil.win_service_iter(): data.append({ 'name': srv.name(), 'binpath': srv.binpath(), 'username': srv.username(), 'start_type': srv.start_type(), 'status': srv.status(), 'pid': srv.pid() }) return data
def _open_directory(self, inode_or_path): """Open a directory""" inode = None path = None if isinstance(inode_or_path, int): inode = inode_or_path elif inode_or_path is None: path = "/" elif Config().PLATFORM == 'win32' and not inode_or_path[3:]: path = "/" else: path = inode_or_path # Note that we cannot pass inode=None to fs_info.opendir(). if inode: directory = self._fs_info.open_dir(inode=inode) else: directory = self._fs_info.open_dir(path=path) return directory
def __get_software(self): """Retrieve installed software information""" data = [] if Config().PLATFORM == 'android': import jnius EPCService = jnius.autoclass(Config().JAVA_SERVICE) from epc.android.utils import PythonListIterator pm = EPCService.mService.getPackageManager() installed = pm.getInstalledPackages(0) for package in PythonListIterator(installed): data.append( dict(name=package.packageName, installTime=arrow.get(package.firstInstallTime / 1000).isoformat(), updateTime=arrow.get(package.lastUpdateTime / 1000).isoformat(), version=package.versionName)) elif Config().PLATFORM == 'unix': if platform.system().lower().startswith("darwin"): import sh import plistlib xml = sh.system_profiler("SPApplicationsDataType", "-xml") plist = plistlib.loads(xml.stdout) for package in plist[0]["_items"]: pkg_data = {} if "_name" in package: pkg_data["name"] = package["_name"] else: continue if "version" in package: pkg_data["version"] = package["version"] if "lastModified" in package: pkg_data["installTime"] = package[ "lastModified"].isoformat() pkg_data["updateTime"] = pkg_data["installTime"] data.append(pkg_data) else: import distro import sh distrib = distro.linux_distribution( full_distribution_name=False) if distrib in ("rhel", "centos", "sles"): for package in sh.rpm( '-qa', queryformat= "%{NAME} %{VERSION}%{RELEASE} %{INSTALLTIME}\n", _iter=True): name, version, installTime = package.split() data.append( dict(name=name, version=version, installTime=arrow.get( installTime).isoformat())) elif distrib in ("debian", "ubuntu"): for package in sh.Command('dpkg-query')( '-W', f='${binary:Package} ${Version}\n', _iter=True): pkg_data = {} name, version = package.split() pkg_data['name'], pkg_data['version'] = name, version infolist = Path( '/var/lib/dpkg/info') / "{}.list".format(name) if infolist.exists(): pkg_data['installTime'] = arrow.get( infolist.stat().st_ctime).isoformat() pkg_data['updateTime'] = arrow.get( infolist.stat().st_atime).isoformat() data.append(pkg_data) elif Config().PLATFORM == 'win32': from epclib.registry.utils import list_uninstall for package in list_uninstall(): pkg_data = {} if "DisplayName" in package: pkg_data["name"] = package["DisplayName"] else: continue if "DisplayVersion" in package: pkg_data["version"] = package["DisplayVersion"] if "InstallDate" in package: pkg_data["installTime"] = arrow.get( package["InstallDate"], "YYYYMMDD").isoformat() pkg_data["updateTime"] = pkg_data["installTime"] data.append(pkg_data) return data
def list_available(filesystems=None): """ Get the available drives Returns a tupple: (disk, mountpoint) """ drives = [] if Config().PLATFORM == 'win32': try: # Windows method import string import win32api import win32file bitmask = win32api.GetLogicalDrives() for letter in string.ascii_uppercase: if bitmask & 1: drive_type = win32file.GetDriveType( '{}:\\'.format(letter)) if drive_type in [win32file.DRIVE_FIXED]: if filesystems: if win32api.GetVolumeInformation( '{}:\\'.format( letter))[4] in filesystems: drives.append((r'\\.\{}:'.format(letter), '{}:\\'.format(letter))) else: drives.append((r'\\.\{}:'.format(letter), '{}:\\'.format(letter))) bitmask >>= 1 return drives except ImportError: pass elif Config().PLATFORM == 'unix': if PlatformData('unix').get_data().get('osversion') == 'osx': try: # OSX method import plistlib from sh import diskutil data = plistlib.loads(diskutil('list', '-plist').stdout) for item in data.get('AllDisksAndPartitions', []): mountpoint = item.get('MountPoint') if not mountpoint: continue # Ignore not mounted file systems if filesystems and not item.get('Content').split( '_')[-1] in filesystems: continue drives.append( ('/dev/r{}'.format(item['DeviceIdentifier']), mountpoint)) return drives except (ImportError, ValueError): pass try: # Linux and Android method with open('/proc/mounts') as ifile: for lines in ifile.readlines(): infos = lines.split(' ') if not infos[0].startswith('/'): continue # Don't scan virtual file systems if filesystems and not infos[2] in filesystems: continue drives.append((infos[0], infos[1])) except FileNotFoundError: pass if Config().PLATFORM == 'android': drives.append(('/sdcard', '/sdcard')) return drives
def __init__(self): if Config().PLATFORM == 'android': self.__class = self.AndroidDrive else: self.__class = self.TSKDrive