SteamHide Malware Analysis - I
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
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
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()’
- initializing a variable
String text
having a string containing an html image tag including a regex URL insrc
attribute - moving on we see a
WebClient.DownloadString
method which downloads the mentioned URL’s source code as String to store in variableString text2
Regex.Match(String input, String pattern)
method used to search for a pattern(text
) in specified input string(the source code intext2
), on success it will extract and store the matched string inString value
usingGroups[1].Value
which reveals an image url- next
WebClient.DownloadData(String)
method used to download the image resource from URL stored invalue
and save as a byte array in variablebyte[] array
, then convert it to a image class object usingImage.fromStream(Stream)
method (after converting the byte arrayarray
to a memory stream), in the very next line,Image.GetPropertyItem(Int32)
is used which returns the PropertyItem Class for specified ID value34675(0x8773)
, a quick look at MSDN page PropertyItem.Id Property shows that ID0x8773
refers toPropertyTagICCProfile
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
- We see a call to
DecryptBytes()
with arguments passed are ICC profile data fromvalue2
, password string{PjlD\bzxS#;8@\x.3JT&<4^MsTqE0
, an integer value192
for iterations,which calls another method
CryptBytes()
with all the above three arguments plus the process set to decryption via enumCryptProc.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 filesteam.exe
, write the specified byte arrayarray2
(storing the decrypted second stage binary data), In the end it will executesteam.exe
by starting a new process usingProcess.Start
method
‘Form1_CryptBytes()’: old fashioned Cryptography Stuff
As we saw earlier, there was a call to CryptBytes()
method, let’s take a look
- Creates a
PasswordDeriveBytes
object to derive key from password string, key salt to use, hash algorithm set toSHA256
, number of iterations to perform TripleDES.Create
method used to performTripleDES
algorithm, then key and IV properties are set usingPasswordDeriveBytes.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 a
CryptoStream
instancecryptoStream
with a target data stream(MemoryStream memoryStream
), transformation to usecryptoTransform
, and the mode of stream set to write accessCryptoStreamMode.Write
, then writes tomemoryStream
the transformed bytes fromplain
- 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 :)