On Tuesday August 2nd, 2022, I created a playground consisting of 23 systems. Ten Window 10 machines, ten Windows 11 machines, one Velociraptor Server and one Server 2019 Windows machine, compromised with a persistent remote access trojan that communicated to an attacker machine hosted outside of the US.
I created a few questions that I felt would be interesting and posted them as a quasi CTF/Practice with instructions on Github.
I then made the Velociraptor server publicly accessible, tweeted about it, and stated that it would be available for three days.
Interestingly enough and much to my surprise, many people took me up on the opportunity, requesting access to the server. Everyone that requested access got a chance to play around with the telemetry collected by the Velociraptor Server. The playground remained up for the promised three days and on Friday we did a walk through of many of the steps outlined in the instructions of the CTF.
Below is the walk through of the CTF/Practice questions, with a screenshot of the data. Prior to taking down the playground I used a custom created offline Velociraptor collector so that I could create a triage image of the compromised server. By the time that you read this, the infrastructure will no longer be up. Nevertheless you can follow along and find the evil by analyzing the triage image using your favorite tools of choice.
Download the triage image from here...
Watch the walk through here...
The compromised client is a Server2019 Windows Machine. This server is in the AWS cloud, it is currently compromised with an active backdoor that has an
ESTABLISHED connection to an attacker machine, which is also in the AWS cloud. The backdoor was created by us using the
sliver C2 framework. All machines are owned and controlled by us. This is a practice playground. Although you are going to be hunting for malware, this is considered a SAFE playground and you will not (should not) get infected.
Hunting for Evil
Objective: Your goal is to find how the system was compromised.
All of the artifacts that you need to get your answers have already been collected and you can read the collected data to find the answers. For example.
Look for Running Processes
Objective: Use the artifacts ability to check for unsigned binaries to find untrusted running processes.
Windows.System.Pslist Post process your artifact collection with the below notebook
SELECT Pid,Name,Exe, Hash.MD5 AS md5hash, Authenticode.Trusted AS signer FROM source(artifact="Windows.System.Pslist") WHERE signer =~ "untrusted"
And you get...
As you can see there is one process that is untrusted that looks very suspicious. This is just the first artifact that you looked at. We recommend that you do more.
Look for Network Connections
Objective: Use the artifacts ability to check for established connection to see if the process has networking capabilities.
Windows.System.Netstat Post process your artifact collection with the below notebook
SELECT Timestamp,Pid,Name,Status,`Laddr.IP`,`Laddr.Port`, geoip(ip=`Raddr.IP`,db='/velo/velo/public/GeoLite2-City.mmdb').country.names.en AS Country,`Raddr.IP`,`Raddr.Port`,Fqdn FROM source(artifact="Windows.Network.Netstat") WHERE Status =~ "ESTAB" AND NOT Country =~ "United States"
And you get...
Did the attacker RDP to the system
Objective: Use the artifact to examine RDP connections to the server. Look for 4624 LogonType 10
SELECT EventTime,EventID,LogonType,UserName,SourceIP, geoip(ip=SourceIP,db='/velo/velo/public/GeoLite2-City.mmdb').country.names.en AS Country,Description FROM source(artifact="Windows.EventLogs.RDPAuth") WHERE EventID = 4624 AND LogonType = 10
How did the attacker get initial access to the server
Objective: Use the artifact to examine logon attempts to the server. You will realize that this was a successful brute force attack with over 400 failed attempts and successful logons from the same IP
SELECT EventTime,EventID,UserName,SourceIP, geoip(ip=SourceIP,db='/velo/velo/public/GeoLite2-City.mmdb').country.names.en AS Country, count() AS Count FROM source(artifact="Windows.EventLogs.RDPAuth") WHERE EventID = 4624 OR EventID = 4625 GROUP BY EventID,SourceIP
When was the malware executed by the attacker
Objective: Use a custom created artifact to get the execution time of the malware. The artifact named
Custom.Windows.EventLogs.SysmonProcessCreationID1 queries the Sysmon Event logs installed on the machine for process creation ID 1
SELECT * FROM source(artifact="Custom.Windows.EventLogs.SysmonProcessCreationID1") WHERE image =~ "dllhost"
Does the malware have persistence
Objective: Do analysis to determine persistence. Use a custom artifact to execute autoruns on the system.
SELECT count() AS Count, Time, Signer, Entry,Category,Profile,Description,`Image Path` AS ImagePath,`Launch String` AS LaunchString, Enabled,MD5 FROM source(artifact="Custom.Windows.Sysinternals.Autoruns") WHERE Enabled AND NOT Signer OR Signer =~ "Not verified" GROUP BY ImagePath,LaunchString
There were a few more artifacts that were collected at the time of the practice scenario, but the ones above are the ones that contain the notebooks with most value. We are definitely planning on running another one of these in the future.
If you though that this was interesting and you want to take part in the next one, please follow me on Twitter for updates on dates. @carlos_cajigas