Last Updated: 2015-10-19 07:25:46 UTC
by Didier Stevens (Version: 1)
Last time I helped out someone with ransomware over at the Bleeping Computer forums, I was able to recover the ransomed JPEG files.
A first look at the file with the file command did not help me:
Neither did a look at the header with a hex editor tell me much more.
But when I analyzed the file with one of my tools to calculate byte statistics (byte-stats.py), I noticed something:
The file has a high byte entropy: 7.815519, that's almost the maximum (8.0). So the file appears to be a set of random bytes, e.g. an encrypted file.
But my program not only calculates the entropy for the whole file (along with other properties), but it also splits the file in buckets (10KB size by default) and calculates the entropy (and other properties) for each bucket. The second entropy value produced by the analysis (5.156678) is the lowest entropy calculated for the buckets (85 in total for this file). And an entropy of 5 is much lower than the entropy of encrypted or compressed data. So somewhere in this file there is data that doesn't look very random.
A picture is worth a thousand words is the saying. bytes-stats.py can also output the entropy for each bucket (option -l), which enabled me to produce this graph:
Somewhere around position 0x5000, data doesn't look random. I took a look with my hex editor, and quickly recognized JPEG structures. What was missing were the first headers of a JPEG file. So I patched a file together with the header of a JPEG file followed by the data recovered from the ransomed file. And to my surprise, I had recovered the image.
I had no luck when I analyzed a ransomed .doc file from the same victim:
The entropy of this file looks uniformly high.
I often look at the entropy when I analyze files. Many of my analysis tools include entropy calculations. For example, pecheck.py provides the entropy of each section of a PE file, allowing me to quickly identify packed sections.