TheAbsnt

SteamHide Malware Analysis - I

· THEABSNT

What’s this blog

This post explores an interesting malware SteamHide which abuses Steam servers to host malware within steam profile images to serve payloads for malware downloaders. Threat Actors can update already infected machines just by adding new images to steam profile.

Also, this malware was an assignment for us to analysis from the course Windows Malware Analysis for Hedgehogs, huge shoutout to Karsten Hahn for this brilliant course.


So, let’s start with initial triage the most important step when analyzing a new sample

Initial triage for ‘Hide binary inside image.exe’

File identification

metadata_fileIdentification The DIE output shows it’s a PE 32bit .NET Executable, which can be assured with the presence of CLR runtime header in data directory of this sample. We can use dnSpy to further analyse the functionality of this sample.

Strings to attach

metadata_strings_output

Taking a look at strings output reveals eye catching strings like

  • user agents and urls indicates possible internet commnuication
  • a gibberish but interesting looking string
  • an executable file name steam.exe
  • and many cryptography related strings and functions, where TripleDES stands out indicating possible algorithm used here

The way it behaves

Starts with ‘Form_Load()’

mw_mw_fn_Form1_Load

  1. initializing a variable String text having a string containing an html image tag including a regex URL in src attribute
  2. moving on we see a WebClient.DownloadString method which downloads the mentioned URL’s source code as String to store in variable String text2
  3. Regex.Match(String input, String pattern) method used to search for a pattern(text) in specified input string(the source code in text2), on success it will extract and store the matched string inString value using Groups[1].Value which reveals an image url
  4. next WebClient.DownloadData(String) method used to download the image resource from URL stored in value and save as a byte array in variable byte[] array, then convert it to a image class object using Image.fromStream(Stream) method (after converting the byte array array to a memory stream), in the very next line,Image.GetPropertyItem(Int32) is used which returns the PropertyItem Class for specified ID value 34675(0x8773), a quick look at MSDN page PropertyItem.Id Property shows that ID 0x8773 refers to PropertyTagICCProfile property tag ie. ICC profile embedded in the image.

TIP#1: You can view ICC profile of an image using exif data parser like exiftool and use command exiftool.exe -icc_profile -d -w icc [yourImage] to extract to a separate .icc file

  1. We see a call to DecryptBytes() with arguments passed are ICC profile data from value2, password string {PjlD\bzxS#;8@\x.3JT&<4^MsTqE0, an integer value 192 for iterations, mw_fn_DecryptByteswhich calls another method CryptBytes() with all the above three arguments plus the process set to decryption via enum CryptProc.DECRYPT, we’ll resume onto the cryptography stuff in a bit, moving on, File.WriteAllBytes(String, Byte[]) method used which will create a new executable file steam.exe, write the specified byte array array2(storing the decrypted second stage binary data), In the end it will execute steam.exe by starting a new process using Process.Startmethod

‘Form1_CryptBytes()’: old fashioned Cryptography Stuff

As we saw earlier, there was a call to CryptBytes() method, let’s take a look mw_fn_CryptBytes

  • Creates a PasswordDeriveBytes object to derive key from password string, key salt to use, hash algorithm set to SHA256, number of iterations to perform
  • TripleDES.Create method used to perform TripleDES algorithm, then key and IV properties are set using PasswordDeriveBytes.GetBytes()
  • now the stream transformation (ICryptoTransform cryptoTransform) to perform is set using ?:(ternary) operator based on whatevercryptProc is set, which gives either encryptor(TriplesDES.CreateEncryptor()) or decryptor(TripleDES.CreateDecryptor())
  • creates aCryptoStream instance cryptoStream with a target data stream(MemoryStream memoryStream), transformation to use cryptoTransform, and the mode of stream set to write access CryptoStreamMode.Write, then writes to memoryStream the transformed bytes from plain
  • in the end either encrypted or decrypted byte array(memoryStream.ToArray()) is returned

Decryption recipe

Here’s the cyberchef decryption recipe to decrypt the ICC profile

NOTE: As of writing this post, when i ran the sample, the steam profile image source code does not return the intended image url, which is why the steam.exe turn out to be invalid executable. So, I’m gonna move on with image provided with assignment beforehand just for such cases, check the hash below.


IOCs : how to tell if a system is compromised

Hide binary inside image.exe 148914b6c64c51130a42159e4100e6eb670852901418d88c1c0383bf0cd1e339
blink.jpg : downloaded image provided with assignment c0b7af1dd476effd0697ffac71c1124d3f086d88945c57cc45096d712e6386cb
FinalMalware.exe(steam.exe) : decrypted from ICC profile b41868a6a32a7e1167f4e76e2f3cf565b6c0875924f9d809d889eae9cb56a6ae
connection made to the steam profile image link hxxps://steamcommunity[dot]com/id/advance40/images

This concludes the first part of analyzing SteamHide in the very next post we will go through the second stage and explore the functionalities.

See you there :)