Introducing Exphash: Identifying Malicious DLLs With Export Hashing
Export Hashing (”exphash”), inspired by Mandiant’s
imphash, is a SHA-256 hash of ordinal-ordered export names in PEs. Tracking DLLs which are used in search-order hijacking can sometimes be tricky. They may have a partial Export Address Table compromising of a dozen functions that exist in the legitimate equivalent, or simply the target function they wish to invoke. Greg Lesnewich published a partial version of a Export Hash using YARA, which took into account the whole table.
Due to the way that Export Hashes are calculated, we can use this to identify related malware samples. An Export Hash is a powerful way to to do this, as they are relatively unique in terms of the ordinal and exported function name within the Export Address Table (EAT). I have been using this technique for a while now in my personal malware analysis pipeline, with great results!
For example, given this EAT:
Case Study: Qakbot
Qakbot uses several different DLLs for their first stage loader, given these DLLs (from https://tria.ge) we can generate a Export Hash to cluster them.
In this example, all of these DLLs export two functions:
This then renders an Export Hash of
ccfad4c79516abc22bf8950d4e89521f2f7b24cfbbcb7ef22145041c04ffc115. Pivoting on this hash, from a malware store compromised of public repositories and sandboxes, then reveals more DLLs that have have the same exphash:
5fc45785cf895f05d6378525ce437f041adf0dd02b578facd523d378b8947ccf 1dc171b504c1d8a1272bdb1b98939bb430d87baef9b6b62af7b85730e14a83b1 48ea2cef873e462c5f6b2912268bbd2e8f267a77357626e12a17aeab4eb33b71 9aa954c537ff7b9e77a625fff2985031ea503818bdef318c5905b0cd206988a2 1dc171b504c1d8a1272bdb1b98939bb430d87baef9b6b62af7b85730e14a83b1
I ensured Export Hashes use SHA-256 across community projects, after researchers at G Data post research on possible hash collisions for Import Hashing.
I have submit a PR to the popular Python-based pefile library for Exphash use, which can be used immediately. Simply call
get_exphash() to return a SHA-256 of the exports.
A PR is currently in review to be merged into the main YARA branch, and will be accessible via
pe.exphash(). Thanks to my colleague Nathaniel Hartley for his input on this.
With anything an adversary has control over, there is obviously limitations. A threat actor could simply map the legitimate ordinal and function name pairs over from a legitimate DLL they are wishing to hijack.