def test_hSchRpcEnumTasks(self): dce, rpctransport = self.connect(self.stringBindingAtSvc, tsch.MSRPC_UUID_TSCHS) dce2, rpctransport = self.connect(self.stringBindingAtSvc, atsvc.MSRPC_UUID_ATSVC) atInfo = AT_INFO() atInfo['JobTime'] = NULL atInfo['DaysOfMonth'] = 0 atInfo['DaysOfWeek'] = 0 atInfo['Flags'] = 0 atInfo['Command'] = '%%COMSPEC%% /C dir > %%SYSTEMROOT%%\\Temp\\BTO\x00' try: resp = atsvc.hNetrJobAdd(dce2, NULL, atInfo) resp.dump() except Exception as e: if e.get_error_code() != ERROR_NOT_SUPPORTED: raise else: # OpNum not supported, aborting test return jobId = resp['pJobId'] resp = tsch.hSchRpcEnumTasks(dce, '\\') resp.dump() resp = atsvc.hNetrJobDel(dce2, NULL, jobId, jobId) resp.dump()
def test_hSchRpcEnumTasks(self): dce, rpctransport = self.connect(self.stringBindingAtSvc, tsch.MSRPC_UUID_TSCHS) dce2, rpctransport = self.connect(self.stringBindingAtSvc, atsvc.MSRPC_UUID_ATSVC) atInfo = AT_INFO() atInfo['JobTime'] = NULL atInfo['DaysOfMonth'] = 0 atInfo['DaysOfWeek'] = 0 atInfo['Flags'] = 0 atInfo[ 'Command'] = '%%COMSPEC%% /C dir > %%SYSTEMROOT%%\\Temp\\BTO\x00' try: resp = atsvc.hNetrJobAdd(dce2, NULL, atInfo) resp.dump() except Exception as e: if e.get_error_code() != ERROR_NOT_SUPPORTED: raise else: # OpNum not supported, aborting test return jobId = resp['pJobId'] resp = tsch.hSchRpcEnumTasks(dce, '\\') resp.dump() resp = atsvc.hNetrJobDel(dce2, NULL, jobId, jobId) resp.dump()
def rpc_get_schtasks(self): """ Query the scheduled tasks via RPC. Requires admin privileges. These credentials can be dumped with mimikatz via vault::cred """ # Blacklisted folders (Default ones) blacklist = [u'Microsoft\x00'] # Start with the root folder folders = ['\\'] tasks = [] schtaskusers = [] binding = r'ncacn_np:%s[\PIPE\atsvc]' % self.addr try: dce = self.dce_rpc_connect(binding, tsch.MSRPC_UUID_TSCHS, True) if dce is None: return schtaskusers # Get root folder resp = tsch.hSchRpcEnumFolders(dce, '\\') for item in resp['pNames']: data = item['Data'] if data not in blacklist: folders.append('\\' + data) # Enumerate the folders we found # subfolders not supported yet for folder in folders: try: resp = tsch.hSchRpcEnumTasks(dce, folder) for item in resp['pNames']: data = item['Data'] if folder != '\\': # Make sure to strip the null byte tasks.append(folder[:-1] + '\\' + data) else: tasks.append(folder + data) except DCERPCException as e: logging.debug('Error enumerating task folder %s: %s', folder, e) for task in tasks: try: resp = tsch.hSchRpcRetrieveTask(dce, task) # This returns a tuple (sid, logontype) or None userinfo = ADUtils.parse_task_xml(resp['pXml']) if userinfo: if userinfo[1] == u'Password': # Convert to byte string because our cache format is in bytes schtaskusers.append(str(userinfo[0])) logging.info( 'Found scheduled task %s on %s with stored credentials for SID %s', task, self.hostname, userinfo[0]) except DCERPCException as e: logging.debug('Error querying task %s: %s', task, e) except DCERPCException as e: logging.debug('Exception enumerating scheduled tasks: %s', e) dce.disconnect() return schtaskusers
def test_hSchRpcEnumTasks(self): dce, rpctransport = self.connect(self.stringBindingAtSvc, tsch.MSRPC_UUID_TSCHS) dce2, rpctransport = self.connect(self.stringBindingAtSvc, atsvc.MSRPC_UUID_ATSVC) atInfo = AT_INFO() atInfo['JobTime'] = NULL atInfo['DaysOfMonth'] = 0 atInfo['DaysOfWeek'] = 0 atInfo['Flags'] = 0 atInfo['Command'] = '%%COMSPEC%% /C dir > %%SYSTEMROOT%%\\Temp\\BTO\x00' resp = atsvc.hNetrJobAdd(dce2, NULL, atInfo) resp.dump() jobId = resp['pJobId'] resp = tsch.hSchRpcEnumTasks(dce, '\\') resp.dump() resp = atsvc.hNetrJobDel(dce2, NULL, jobId, jobId) resp.dump()
def test_hSchRpcEnumTasks(self): dce, rpctransport = self.connect(self.stringBindingAtSvc, tsch.MSRPC_UUID_TSCHS) dce2, rpctransport = self.connect(self.stringBindingAtSvc, atsvc.MSRPC_UUID_ATSVC) atInfo = AT_INFO() atInfo['JobTime'] = NULL atInfo['DaysOfMonth'] = 0 atInfo['DaysOfWeek'] = 0 atInfo['Flags'] = 0 atInfo[ 'Command'] = '%%COMSPEC%% /C dir > %%SYSTEMROOT%%\\Temp\\BTO\x00' resp = atsvc.hNetrJobAdd(dce2, NULL, atInfo) resp.dump() jobId = resp['pJobId'] resp = tsch.hSchRpcEnumTasks(dce, '\\') resp.dump() resp = atsvc.hNetrJobDel(dce2, NULL, jobId, jobId) resp.dump()