Attack Discovery: A simple scenario with Meterpreter and Cerberus
While cleaning out my drive, I found a little gem of my past and thought I’d just paste it here. A while back, a friend was involved with a project and needed me to generate some artifacts for some kind of a basic compromise and a brief analysis from which he would generate some kind of test-like evaluation. I only had a few days which was mostly consumed with setting up a virtual network to do what I wanted. In the end, I had a fairly large pcap, some memory dumps, and some virtual disks for forensic evaluation. All I had to do was use this evidence to discover the actions taken by an attacker while pretending that I wasn’t also the attacker. It’s harder than it sounds, but given there wasn’t a ton of network traffic, the analysis could pretty easily be done using mostly rudimentary manual techniques even if I hadn’t setup the network and initiated the traffic myself.
When all was done, I had a pcap, a memory dump, and a disk image to analyze. There was a scenario that began with a pcap, and led to some basic memory and disk analysis but most of the details aren’t really relevant here. Basically, a student would be informed that the user at 192.168.10.12 had reported a slow connection and was asked to look at a pcap. It was expected that a memory dump and filesystem dump would be requested and would be provided.
So starting with the pcap, I fired up Wireshark to get a handle on what had been seen occurring on the network. I went to the “Statistics” tab to attempt to narrow down the results to the more interesting traffic and started noting items of interest. After looking through “Conversations”, Endpoints, and Resolved Addresses, I’d noted the following items for further investigation.
In wireshark, manually viewing Statistics -> Resolved Addresses, Conversations, Endpoints, HTTP -> Requests
Communications and Endpoints of interest:
192.168.10.12 talking to 22.214.171.124 over port 8080
126.96.36.199 and 188.8.131.52
Resolved addresses of interest:
HTTP requests of interest:
So far, no strings but IP addresses and DNS names to investigate are:
updates.flash.com.realf1ash.com points to 184.108.40.206; more information below
192.168.10.1 — nothing suspect
220.127.116.11:8080 — needs further investigation
18.104.22.168 — confirmed AVG traffic
192.168.10.12 — needs further investigation
172.16.10.1 — needs further investigation
22.214.171.124 — needs further investigation
Analysis for traffic between 126.96.36.199 and 192.168.10.12
188.8.131.52 is a Chinese registered address (CHINANET Guangdong
province network) and more information can be found here: https://www.robtex.com/ip/184.108.40.206.html
#64–890 (tcp.stream==1) shows a get request to a possibly random 4 character path which returns a binary that is 770048 bytes. The binary was extracted from the pcap by viewing conversation and saving as raw.
Current packet filter: ip.addr==220.127.116.11 && ip.addr==192.168.10.12 && !(tcp.stream==1)
Between stream1 and at the beginning of stream2, there was evidence of a beacon that consisted of a POST that returned a 0-length packet and from an unversioned Apache server which can be indicative of a meterpreter http beacon.
Stream2 (# 893–1089 begins with a POST and another possibly random path consisting of 4 characters, and underscore, and 16 more characters as seen below. The contents seemed to be unknown data but there was a string that is noted for further analysis.
Stream3 consisted of another beacon
Stream4 seems to be passing more data this time with many more strings to catalog for later analysis such as stdapi, railgun, core_channel .
Using Wireshark’s string search feature and searching for “stdapi” in the packet bytes, a number of interesting packets returned showing what appeared to be instructions issued such as getuid, and getsystem. One of interest contained the name of an executable, snorton.exe as shown below. Searching for this instruction (stdapi_fs_file) might show additional binary names.
The file appears to begin transfer in #2974. The binary of 8416 bytes (with packet information) was ripped for further analysis.
running tcpdump -nAr capture.pcap | grep -e “stdapi_fs_file” returns the following files were uploaded to an unknown directory.
> tcpdump -nAr capture.pcap | grep -e “stdapi_fs_file”
Other files were also discovered and due to the suffix of rbb vs wbb as in the previous, packets, it is likely that these are set to be retrieved from instead of written to the target disk as shown below. After some analysis, we learn that ‘rbb’ is for reading a file while ‘wbb’ is for writing.
The rest of this traffic between these two hosts is primarily comprised of various C2 instructions as mentioned previously.
A complete listing of all captured instructions of this type can be found using the command:
tcpdump -nAr livecapture.pcap |egrep -o -e ‘stdapi[^\.]*’ | sort -u
Traffic shows a number of registry keys accessed and created and grepping for common registry values such as SYSTEM or SAM shows the potential for persistence in the RUN key as well as possible user enumeration or hash dumping.
There was significant traffic between this host and 192.168.10.12 over port 80 though the traffic didn’t seem to match the HTTP protocol. The primary identifying characteristic of this traffic was the string “wBmpf3Pb7RJe” which a quick search indicated the Cerberus RAT. Because there were no other markers in the packet capture, the binary will have to be recovered for further analysis.
Based on the recovered string, a signature could be created to detect it. E.g:
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”Cerberus Beacon”; flow:from_server,established; content:”wBmpf3Pb7RJe”;classtype:trojan-activity; sid:1234567;)
Since various compilations of the RAT will likely have different strings, we would need to gather more information to create a more precise signature.
Basic process and network dump follows.
Wanted to replace this with a memory timeline but the file is too large so this will have to do.
volatility -f raw_memory_image.001 pstree
volatility -f raw_memory_image.001 connections
volatility -f raw_memory_image.001 connscan
volatility sockets -f memory.dd
The quick dump confirms what we’ve seen in the packet capture. We can also see that LabResult.pdf.exe is the parent of both winit.exe and w2_sock.exe.
Of the files captured over the wire, some either weren’t executed, weren’t running at the time of the memory dump or migrated into another process:
These binaries were found active in the memory dump:
winit.exe is in the process list, but has no sockets related
w2_sock.exe is currently running and is bound to TCP port 4612 on 0.0.0.0
There was no reference to these files using dlllist and driverscan. It’s possible that their corresponding executable was never called.
From network traffic, we gathered potential traffic from a Cerberus RAT. It’s very important that we are able to find the processes that is creating that traffic. We can see that iexplore.exe is communicating to the address reported in network traffic that was potentially associated with the RAT.
We can dump the memory space of the iexplore.exe process and search it for strings and either manually parse it, or grep for the couple of indicators we have so far gathered. If no results were returned, we might have to rely on filesystem forensics to recover the initial file and gain more strings to form a malware signature. The following commands provided some juicy detail. We can see potential locations on the filesystem, a handful of additional search terms for the rest of the memory capture, possible additional C2 nodes or alternate DNS callbacks and more.
vol.py -f raw_memory_image.001 vaddump -p 3672 — dump-dir dump.iexplore/
strings dump.iexplore/* |grep -C 5 18.104.22.168
Using this, we can create a YARA rule to see if any other processes are affected by the RAT.
The most simple rule we can likely make is the following:
rule cerberus : rat
$a = “cerberus” nocase
any of them
Using the above rule, we can scan the memory image for other processes that alert on that string which will indicate at least that part of the Cerberus code residing in that processes memory space.
volatility -f raw_memory_image.001 yarascan -y yararule |grep Pid | sort -u
Alternatively, since this is a simple string, one could just use the following:
volatility -f raw_memory_image.001 yarascan — yara-rules=”Cerberus” |grep Pid |sort -u
This show that there are at least 32 processes with Cerberus code in it’s address space.
I used the following commands to create a timeline of the filesystem activity on the infected machine.
log2timeline.py — partition 2 ./fs_timeline.csv ./disk_image.dd.001 — output L2tcsv
From there, I opened it up in Excel and began examining by searching for the files we saw transferred in the packet capture.
Many of the file suspected suspected to be part of the intrusion are shown in Prefetch as shown below.
LabResult.pdf.exe seems to have been executed around the same time as the Thunderbird mail client was being accessed as shown below. It appears to have originally been saved in the Thunderbird folder.
A little research shows the default folder for Thunderbird Mail Client is C:\Documents and Settings\$USER\Application Data\Thunderbird\Profiles\????????.default
We can find message content in the global-messages-db.sqlite. We can run strings on the file to get the gist, or we can use an sqlite parser to view the contents. Using a custom python script to parse the db, we can see that the file sent to Avery didn’t open as expected but that her computer was behaving oddly and she sent a couple of messages about it. Alternatively, one could use “sqlitebrowser”
/cases/db_scout.py -d global-messages-db.sqlite -t messagesText_content -c c0body
An attempt was made to stop the AVG security product. We can also see a number of the files we saw in traffic being created in the System32 directory shown below.
We can see a log of those files being executed as well as a couple of other interesting events surrounding them. we can see winit.exe, snorton.exe, w2_sock.exe and we also see iexplore.exe being executed as well. The screenshot from the infection doesn’t show Internet Explorer running, and from our network and memory scans, we saw it connecting to a Japanese IP address. We also see that the system firewall has possibly been modified.
We should be able to recover most of these files by simply mounting the image and ripping them out. We can then further process the binaries to create the signatures we need to discover these binaries and processes on other systems.
Continuing to search for our given file names, we can see a number of registry entries being created as well as the loading of the .vbs file we saw in traffic below.
The suspected RAT, flashupdate.exe.exe was added to the run key in a slightly more confusing manner. It appears to have been added in multiple ways possibly to bypass any quick removal attempts by a hasty investigator or administrator.
We’ve found enough evidence of filesystem activity that correlates to what we’ve seen in traffic analysis to be able to identify the obvious threats on the system and retrieve them for further evaluation.
Using the command “losetup -0 32256 /dev/loop0 disk_image.dd” to mount the image, we found that the vbs script that had been uploaded was not in the Temp . All other files were recovered successfully.
Using fls, we were also able to recover the LabResults.pdf.exe file from the filesystem.
Quick Static Analysis
For each binary that was recovered, we ran srch_strings and srch_strings -e l to recover the most amount of information possible. We then wrote a python script to dump the IAT as well.
python script (Medium breaks the indents)
pe = pefile.PE(binary)
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for imp in entry.imports:
print “\t”, hex(imp.address), imp.name
except Exception, e:
This is a very basic binary with few enough imports that strings show all that we need to know this is likely a keylogger due to the API calls to GetAsyncKeyState, GetForegroundWindow, WriteFile, etc.
Strings revealed some compiliation information and API calls, but listing the API calls alone shows that this executable uses pcap libraries which is indicative of a sniffer, and also has a reference to isDebuggerPresent which might indicate an attempted debugging defeat.
Strings show that this binary seems to be passing data over the network but it’s tough to tell more based on this.
The import table show a fair amount going on and confirms the networking strings we saw above with the call to WS2_32.dll.
Running strings, we can see what appears to be hosts (probably callbacks), the filename flashupdate.exe, the word infected (this is a default password for many malware zips), klog.dat which should be recovered for analysis, and the keyword Cerberus RAT which indicates that our suspicions are correct.
Knowing now that this is the Cerberus RAT, we expect to have more comprehensive functionality which is shown in part by its import table below. Because many RATs have the capability to receive additional plugins, it’s tough to gauge the full capabilities of this particular malware.