IPFuscation — using IP addresses to obfuscate your sus payloads
It’s no news that most anti-malware programs will immediately detect your payload if it’s stored as-is in your malware. To overcome this static detection, one strategy is to obfuscate your payload.
In 2022, SentinelOne published their findings about how the Hive ransomware used an obfuscation technique, which they named “IPFuscation” — using array of IP addresses to obfuscate arbitrary data.
What’s the logic?
The logic is simple. An IP address is just bytes. The dots (in IPv4) or the colons (in IPv6) are just for our ease of understanding. To a machine, it’s actually represented as an array of bytes.
In an IPv4 address, there’s 4 octets, each is a byte. In an IPv6 address, there’s 16 octets.
If you take arbitrary data, group up the bytes in sets of 4, then each set could be represented as an IPv4 address. And the same for sets of 6 for IPv6 addresses.
For example, the IPv4 address “252.72.131.228” is actually just the array of bytes “\xfc\x48\x83\xe4”. So instead of storing the latter, you’d store the former, which would appear benign.
My attempt
SentinelOne’s blog post mentions the use of “RtlIpv4StringToAddressA” NT function to convert an IPv4 string to the equivalent byte array. This is necessary to deobfuscate the payload, and get back the original buffer from the array of IPv4 addresses.
And this makes it easy to detect such obfuscation attempts — just search for the function name. This forms an IOC for such obfuscators.
I wanted to evade this, so I went ahead and wrote a custom implementation for this. The logic is simple — for each IPv4 address, process each octet (octets here would be separated by “.”s) by converting the string representation to decimal, and then to byte representation.
Take the earlier example — “252.72.131.228”. The flow would be as follows:
- Iterate through the whole string until a “.” or a “\00” is encountered.
- Each section is now an octet. Convert to decimal by first getting the integer equivalent for each character digit (just convert from ASCII to integer by subtracting ASCII for “0”), then by summing the digits each with their proper powers of 10. So, “252” would yield 2, 5 and 2, which would take you to (2 * 100) + (5 * 10) + (2 * 1), which is 252.
Here’s my implementation of the IPFuscator in C
All functions are written custom. I wanted to try my hands at practising my pointers because I like to bring suffering to my life.
This POC first obfuscates the payload and gives you the array of IPv4 addresses you’d need to use for the deobfuscator.
Then it uses the deobfuscator to get back the original buffer from this array.