Hunting The XOR Keys For Hashed Imports - Emotet Example (Patreon)
Content
With HashDB we have a new powerful tool to deal with malware that is using API hashing. If you missed our tutorial on API hashing and how HashDB can be used to resolve hashed imports you can view it on YouTube. In addition to hashing API names some malware families will XOR the API hashes with a XOR key that changes with each new build of the malware. This is an attempt to further obscure the APIs and frustrate tools like HashDB. Luckily HashDB supports XOR keys for API hashes, but the job of locating the XOR key is still a manual task that must be performed by the analyst.
Locating XOR Key(s)
Locating an XOR key for an API hash algorithm is a straight forward three-step process.
- Locate the API resolving function where the API hash is passed as an argument.
- Follow the API hash (there may be multiple nested function calls) until it is compared against the hashes generated by the hashing algorithm.
- Somewhere between where the API hash is passed to the function and when it is compared there will be an XOR with a hard coded value. This is the XOR key.
Emotet Example
To illustrate this process we will step through an example using a recent Emotet sample. The sample is available for download on Malshare.
931cf2ec23e034d8677c61e6be19ca79591a49c8a664d256f465a2d1e8331bd1
Emotet is unique in that there are two separate XOR keys, one for the module (DLL) name and one for the API name. In this example we will first locate the module XOR key, then the API XOR key.
First we locate the API resolving function which is easy to spot since it takes two DWORD values as arguments. Function sub_10003F8A.
Nerd Note: It is obviously not always that case that a function accepting two DWORD values is an API resolve function but this function is called over 100 times in the binary always with different DWORD values. Checking the xrefs to a potential API hash resolving function and noting how many times it is called in the binary and checking the arguments is a quick way to confirm the function is a likely candidate.
We follow the module hash passed as the last argument to the API resolve function as it is passed as the last argument to a second function, sub_10010028.
Finally we locate where the module hash is compared to another value and we notice that the XOR key is inline with the comparison. We have found the module hash XOR key: 0x1276F6BD.
Next, we return to the API resolving function sub_10003F8A, and notice that the API hash is passed as the first argument.
We follow the API hash passed as the first argument to the API resolve function as it is passed as the third argument to a second function sub_1000CD9B.
Finally we locate where the API hash is compared to another value and we notice that the XOR key is in-line with the comparison. We have found the API hash XOR key: 0x1E08174E.
Now that we have both the API hash XOR key and the module hash XOR key we can begin resolving the hashes with HashDB! Remember it is easier to set one key and resolve all of one type of hash, then change the key and move on to the next type of hash, rather than alternate between the two of them. Happy hashing!