Valak uses a multi-stage, script-based malware that hijacks email replies and embeds malicious URLs or attachments to infect devices with fileless scripts.
By Jason Reaves and Joshua Platt
Executive Summary
- Valak uses multi-stage, script-based malware utilized in campaigns reminiscent of Gozi ConfCrew.
- The overlapping campaign structure has led to some sandbox reports misidentifying Valak as Gozi.
- Emails are harvested and used in ‘Reply Chain Attacks’ to further spread the malware with a purpose-built plugin, ‘exchgrabber’.
- A newly-discovered plugin called ‘clientgrabber’ is also utilized for stealing email credentials from the registry.
See the full report for more technicals details on Varak.
Background
Gozi has been around in various forms for over a decade now. Certain variants are operated by more sophisticated actors, typically choosing to operate the trojan privately with partners or as a more functional rented service model. One variant in particular, which used the key 10291029JSJUYNHG, is noticeable due to their unique ‘Reply’ chain or thread hijack spamming. At times this key has been confused with dreambot but is in fact operated separately. The two primary functions of the service are loading and spamming.
While this Gozi service has operated continuously for several years, in mid-October 2019, Valak began to appear in testing mode. The new JavaScript-based system also involved compromised servers with link-based email campaigns, which was a departure from the typical password protected attachment approach.
Research Insight
Delivery – ConfCrew Delivery System
A recent Valak delivery chain utilized document files that contact PHP delivery proxies in order to pull down and execute the initial DLL payload. This system was commonly utilized by the Gozi crew for campaigns previously and is actually frequently labeled as Gozi traffic due to the similar URL structure.
For example:
5184b70eef0d99c77e3e56f7e7b67727e515364e
downloads:
80af349e1d41195576eeb7badc26d9b7873bdfbc
via the following URL:
hxxp://a8xui1akl9gjqucfa[.]com/vv55v37kts7et/idq9p9t142vyk.php?l=frraw2.cab
This is the Valak DLL loader when unpacked; however, looking at IOC and sandbox reports it is easy to see that this switch up of malware is already causing confusion and is being labeled Gozi in some reports.
Delivery – Compromised Websites
Another delivery avenue for retrieving the malicious document, which will then contact compromised websites to retrieve the initial DLL loader for detonation, involves links in emails[5]. These links have similar random looking PHP names on compromised websites that will return a document instead of a DLL. The campaign server can be utilized for both the documents and the DLLs and you can find campaigns performing both.
Compromised PHP Script
The request structure for recent Valak deliveries is listed below.
/_3ZyKva_O9zPO1K_k.php?x=MDAwMCCz9oR8W_gfwzPN6OQPNnku8FfF-ORh5orr1PzC0Avh3LkS4cvcHcQm38Efx3sZMnArLlPqOq5dmdcTOCewa7719Cc84VKgzrxYXx_1dF6N2TuRZ_A_wW8lpm2QOdV0_o-ebn1WCpHJl7o1CJKc3KfF8T-nLUAzS-P_dBt2BVUaVi2OQs-a35JD6DWiJux2-xL2eyIwGBlte-n8hD-egM3iqfh8Zw~~
This seemingly random looking data has some striking resemblance to base64, but we will need the PHP in order to be able to cleanly decode it.
The script takes the URL parameters and ultimately decrypts the contact URL out with an embedded key. First, the base64 encoded data can be cleaned up and initially decoded such as the following:
>>> a = 'MDAwMCCz9oR8W_gfwzPN6OQPNnku8FfF-ORh5orr1PzC0Avh3LkS4cvcHcQm38Efx3sZMnArLlPqOq5dmdcTOCewa7719Cc84VKgzrxYXx_1dF6N2TuRZ_A_wW8lpm2QOdV0_o-ebn1WCpHJl7o1CJKc3KfF8T-nLUAzS-P_dBt2BVUaVi2OQs-a35JD6DWiJux2-xL2eyIwGBlte-n8hD-egM3iqfh8Zw~~' >>> a = a.replace('-', '+') >>> a = a.replace('_', '/') >>> a = a.replace('~', '=') >>> a 'MDAwMCCz9oR8W/gfwzPN6OQPNnku8FfF+ORh5orr1PzC0Avh3LkS4cvcHcQm38Efx3sZMnArLlPqOq5dmdcTOCewa7719Cc84VKgzrxYXx/1dF6N2TuRZ/A/wW8lpm2QOdV0/o+ebn1WCpHJl7o1CJKc3KfF8T+nLUAzS+P/dBt2BVUaVi2OQs+a35JD6DWiJux2+xL2eyIwGBlte+n8hD+egM3iqfh8Zw==' >>> b = base64.b64decode(a) >>> a 'MDAwMCCz9oR8W/gfwzPN6OQPNnku8FfF+ORh5orr1PzC0Avh3LkS4cvcHcQm38Efx3sZMnArLlPqOq5dmdcTOCewa7719Cc84VKgzrxYXx/1dF6N2TuRZ/A/wW8lpm2QOdV0/o+ebn1WCpHJl7o1CJKc3KfF8T+nLUAzS+P/dBt2BVUaVi2OQs+a35JD6DWiJux2+xL2eyIwGBlte+n8hD+egM3iqfh8Zw==' >>> b '0000 xb3xf6x84|[xf8x1fxc33xcdxe8xe4x0f6y.xf0Wxc5xf8xe4axe6x8axebxd4xfcxc2xd0x0bxe1xdcxb9x12xe1xcbxdcx1dxc4&xdfxc1x1fxc7{x192p+.Sxea:xae]x99xd7x138'xb0kxbexf5xf4'<xe1Rxa0xcexbcX_x1fxf5t^x8dxd9;x91gxf0?xc1o%xa6mx909xd5txfex8fx9en}Vnx91xc9x97xba5x08x92x9cxdcxa7xc5xf1?xa7-@3Kxe3xfftx1bvx05Ux1aV-x8eBxcfx9axdfx92Cxe85xa2&xecvxfbx12xf6{"0x18x19m{xe9xfcx84?x9ex80xcdxe2xa9xf8|g'
The segment variable from the PHP script is then 0 and the compression flag for this instance is a space; if it were compressed it would be ‘z’.
The rest of the URL is decoded using an onboard key; however, the key data is very large and the segment value we decoded earlier is actually an index multiplier into this giant key.
Knowing this and armed with the key we can now decode out the contact URL.
>>> test = bytearray(b[5:]) >>> key = bytearray(base64.b64decode('24LwDGHXMPQL49nWNhhLHsh5/czLDIfjh/mfqrVoirnLP4Wur3bpUraseuoZeEBdR0c9gUmBMPCkcBdT2QXHhoBGSJJ9yaDYPScxhRwusoppwzi0d4geUudZ43WyCoCywTEoHWHIhs74A2Hlrq2SjogSikk0bAqOkTZYJGljbRJMuBOm45ikJ41nwROeT4xqlShaenQvByGiie1bqfWM0vCaRBmIkM9aEhfrEgfsj2TVSkpT+UWiEt/CfDj0xV+1YCjpJw+E3qwO9X0FOtZ4PpetY5cnif5QWN0Evg7k1nBh+choS2ydJyhsDlmhhASlCI4xkj8A6zjrJkrNVguMr6CanLlIwJZycHqcm7TntyKChEKrsJE4VyNMUAfpMSWnEk61QBapDw7t67h/lg9mwLsmm/UMmhNGkLR+55HHk92XoD0BNTOtnfpnZ0eI77z5aRiZTixoz8FVteOtc3vP2MHZ2rjffbhAqf3ayVcwjQpS/5KnK0FWkjruI34LXSFgeRZvCXrH5ZNBzamTpVDnhKR0L98Ksztvpk77jGGx5vhoZ0MYDExkM4F6fhlBNHR9ZCCpelT8kR2g5v0RK9iMkc3GtMyQwKgL37XfcTQciSYjaH6D2jFsC7/ODK0IeIJIujcHaXx0ddLFJMibvnRqAEfYTbRAQRwjSrHfBQkk14GyehISjqKwJF8XOoRs/Jt6OllExDUI35xe6moFR3L6zZAzot7CtNIOeTvJ+bROHxWxUZheRQW3+Q/9jGryWHA6q+x/f+kz+ZqrsF6Wnax9hk91SI1bMOwE3lYvIjxQCVYOo2moVyE4Dy6iIHZBrSVNNBcmJ9NQEFDGCPPqhI/JMxE92UddkfzPyC+nlkKcnGguIUaJMZ3gceZnmksH/XN2XUnW1VEh8TC2tfsvThIMbB0Mxh5zX9CiTpwIrDN/4Xo2xE9apnRCJ+uLBW+cGoRM8X69xuoY/EgfLPGP7JBwIMYD56PjyyrNjZSI4Mh4/zokOP0h5OmQEXFTU9wBeWhJMgZWkCyA5jyw2lmI')) >>> for i in range(len(test)): ... test[i] ^= key[i] ... >>> test bytearray(b'http://78.129.208.84/mail-checker-desk-time-bar-links/misc/tinystats/index.php?SRR_DHIqwA4sLg~~=__UKkYOYB6iw2q5Ky--dt_AmnBCRl6wDa6QiyG6deRc5r9wxcSxJl6jZKuid7uA0Yb8~')
After performing the decryption, we have the real download URL. The campaign files retrieved with this PHP script, such as Office documents and the DLL loaders, are not stored in the PHP files directly but are the result of pre-generated campaign URLs passed to the proxy script in order to retrieve them upon execution.
To summarize the process, the proxy script utilizes an embedded key to decrypt the URL and retrieve the contents.
The similar-looking encoded string passed to the index.php
file as a parameter is likely an encoded message containing campaign specific data. If we continue to look at the functionality of this PHP file, we can surmise it is used to track statistics along with the delivery of the campaign files.
Serving up campaign files from the backend:
Stats Panel
Upon further analysis, a stats panel was uncovered confirming our hypothesis. Each campaign is carefully tracked. In the image below, the hits are displayed for each file along with the operator and filename. This is typical for a load service, which would require statistics in order to charge customers accurately.
The panel also displays tracking for each of the links from their campaigns, offering possible insight into the number of success executions per campaign.
Valak
Other researchers have already written extensively on Valak[6], so we decided to focus on the aspects that we feel show more of a connection between the Gozi ConfCrew and Valak. These primarily revolve around the use of new plugins. When Valak was in testing in 2019, a number of different plugins were seen[3]. However, two new ones of particular interest relate specifically to the harvesting of email credential data. One of these, the exchange grabber, was also mentioned previously[6].
The harvesting of email credentials falls in line with a previous tactic used by the Gozi crew, where they would harvest emails from accounts and then use the email chains in their spam campaigns[4][8] for a ‘Reply Chain Attack’. This attack revolves around hijacking existing, legitimate emails that are then ‘replied to’ and spammed out. This technique is a way to catch users off-guard as they are normally trained to spot fake emails but will let their guard down when they see that the email is a reply, particularly if it appears to be part of a conversation between known or trusted recipients. Reply Chain Attacks also mean the actors do not have to invest in creating legitimate-looking email templates because they are able to leverage genuine email correspondence chains.
Exchange Data Plugin – EXCHGRABBER
If you are going to leverage reply chain attacks for your spamming campaigns, then you obviously need some email data. It’s interesting to see that when campaigns shifted more towards Valak and away from Gozi, the addition of a plugin surrounding the theft of exchange data showed up.
The plugin names itself in its config section as an ‘exchgrabber’ or exchange grabber. The name suits the functionality in the .NET compiled plugin as it will enumerate credentials from the Credential Manager looking for one associated with Office. Then, using the data from autodiscover.xml, it will build the harvested data into a report.
After retrieving the data it will exfiltrate it to the C2:
Email Credential Plugin – CLIENTGRABBER
The recent shift of focus to email theft and enterprise targeting is interesting. While conducting this research, we also discovered a new plugin called ‘clientgrabber’, which is primarily utilized for stealing email credentials from the registry.
The registry locations are recursively searched for the ‘keys’.
Once found, it will check that the value is using the newer method of encryption and contains the actual encrypted password data, which can be decrypted[7].
Indicators of Compromise
Endpoint
%temp%[a-f0-9]{12}.bin
Scheduled task 'PerfWatson_[a-f0-9]+'
ADS executable and script files:
HKCUSoftwareApplicationContainerAppsw64ShimV4
HKCUSoftwareApplicationContainerAppsw64SetupServiceKey
Network
Base64 encoded PE files transferred over the wire
Samples
435ec42fefc05eba0a8005256c815979877d430a
693e681e7be554e50e4ff9bf7cbfe5aeab3fe91f
e22b404e1fec743f0795cdea8a95337660878860
dba1337a0a8293b721642b8b45a86352bcdfd04f
4d33425d7031284cf5ee323dc616d9f84987dc0d
17b74a4c3f43c21504b355b1ffc333280ef4cd74
7f58d22d9e95f65170acadd05e324ec2d8ef13f6
9be234bf2268f4e055ea59cf7bef76781a36c35c
19f481063ca956688824e3cc022b8eedb6dd0bea
4ae3ed6c1ab2fe41daf6f650a54dae63684d2064
30fd553dedfadc81522adf37e11dfc4039d4ea31
References
1: https://twitter.com/vk_intel/status/1207917643291910144
2: https://en.wikipedia.org/wiki/ROT13
3: http://prsecurity.org/2019-valak-c2.html
4: https://www.zdnet.com/article/this-phishing-trick-steals-your-email-and-then-fools-your-friends-into-downloading-malware/
5: https://app.any.run/tasks/8e5b6f19-c3e5-4c87-87ac-8c8e012cbb5f/
6: https://www-cybereason-com.cdn.ampproject.org/c/s/www.cybereason.com/blog/valak-more-than-meets-the-eye
7: https://securityxploded.com/outlookpasswordsecrets.php
8: https://www.webroot.com/blog/2019/04/03/hijacked-email-reply-chains/
Read the Full Report
See the research report for more technicals details on Varak.