Introducing Delta Encoder

By Red Siege | April 15, 2024

By Corey Overstreet, Senior Security Consultant

Recently, our own Mike Saunders released a novel shellcode obfuscation technique with the tool Jigsaw. If you haven’t checked out the GitHub repository or his blog post, I highly recommend you check them out. To recap why we need these obfuscation techniques, we want to include our shellcode payloads within a loader that is sent into a target environment. This payload will need to remain undetected by antivirus and endpoint protection products while sitting on disk or during execution. These security products scan for signatures indicating a file contains malicious or obfuscated code using known techniques.  Additionally, endpoint protections will detect our loaders using known shellcode obfuscation techniques such as decryption with AES and XOR or decoding base64 encoded shellcode.  Some security products take it a step further and classify large blobs of highly random (or high entropy) data within a file as a potential sign of malicious obfuscated code. There are ways to reduce this entropy with tools such as Jargon, but we’re always trying to come up with new and novel ways to encode or obfuscate our shellcode to avoid those endpoint protection products during malicious file downloads and access.

Mike has some great material around shellcode obfuscation coming up soon (stay tuned for more info) and got the rest of our team thinking through new techniques to encode or obfuscate our payloads. That’s when the idea for Delta Encoder occurred to me: What if we could rebuild our shellcode in memory at run time?


How Does It Work?

Let’s say we have the following C byte array:

unsigned char shellcode[10] = { 0xfc, 0xe4, 0xd9, 0x45, 0x98, 0xa6, 0x77, 0x3c, 0x42, 0x10 };

Instead of storing this exact sequence of bytes in our loader, we could store the differences between shellcode[0] and shellcode[1] (0xfc and 0xe4 respectively). To get this value, we would take the second byte (shellcode[1]) and subtract the first byte (shellcode[0]) giving us a difference, or delta, of 0x18. We could store that in a different byte array and iterate through the rest of the values to get the differences.

What happens when we go over or under the maximum 1-byte values? In languages like C/C++, only the last byte is stored, effectively wrapping around to the value we want. As an example, let’s look at the difference between shellcode[3] and shellcode[2] (0x45 and 0xd9 respectively). As you can see below, the resulting value underflowed to 0xFFFFFFFFFFFFFF6C. However, if you’re using an unsigned char variable, which is 1 byte in C/C++, only the 0x6c will be stored, which gives us the exact value we need. For programming languages that do not support signed/unsigned variable values such as Python, you will need to implement logic to handle underflows when encoding the values and overflows when decoding during runtime.


I can hear you asking, “So what are we going to do with an array of deltas?”. In our loader code, we can now store the array of differences and another array with the first byte set to the real value of our shellcode as a seed for reconstituting our payload. We can add the first delta to the first byte of shellcode and store that as the second byte of our shellcode. As we iterate through the deltas and the newly stored shellcode, we effectively reconstruct our shellcode in memory at runtime and (hopefully) evade detections along the way.


Old Dog, New Tricks

While researching this technique to determine whether this was something that was already known and implemented, I found a Wikipedia article describing the exact method and idea for using deltas to store binary data. The technique of using delta encoding is used in a wide variety of applications such as application updates, Git, HTTP protocol, and most widely used in various forms of Diff.  I searched GitHub for examples of tools that specifically encoded shellcode using deltas as I described above but could not find any direct examples. However, that doesn’t mean this technique was not already known or in use; only that it wasn’t known to me at time of writing.


In Practice, How Did We Do?

While talking through this idea with Mike, he coded up a quick shellcode loader to execute a Metasploit Framework shellcode payload. We encoded the payload provided by Metasploit, placed it into the loader, and compiled into a Windows executable. As shown below, VirusTotal detected the loader with 2/72 security products. Not bad for a well-known encoding technique like deltas.


In Conclusion

It was fun thinking about new ways to get our shellcode into a loader and into memory while not being blocked from the start. If you know of any examples or tools using this encoding method, please let me know on Discord or on GitHub. I would like to give credit where credit is due and read through other implementations of this for more ideas on how to use this during operations.

About Corey Overstreet, Senior Security Consultant

Corey Overstreet

Senior Security Consultant

Corey has been engaged with Fortune 500 organizations across a variety of industries, including financial services, government services, and healthcare and is widely recognized for his in-depth OSINT talks and workshops. Additionally, he is a Black Hat trainer and has spoken at conferences such as Wild West Hackin’ Fest, Texas Cyber Summit, and CypherCon. He has over five years of systems administration and extensive VMWare administration experience. Corey was a member of the SECCDC Red Team and is one of the top Red Team Operators at Red Siege.


Connect on Twitter & LinkedIn

Adventures in Shellcode Obfuscation! Part 1: Overview

By Red Siege | June 17, 2024

by Mike Saunders, Principal Security Consultant This blog is the first in a series of articles on methods for obfuscating shellcode. I’ll be focusing on how to obfuscate shellcode to […]

Learn More
Adventures in Shellcode Obfuscation! Part 1: Overview

Essential Steps for Management to Maximize the Value of a Penetration Test Report

By Red Siege | June 3, 2024

by Tim Medin, CEO Penetration testing is a critical component of a well-rounded cybersecurity strategy. Penetration testing identifies vulnerabilities before malicious actors can exploit them. However, the true value of […]

Learn More
Essential Steps for Management to Maximize the Value of a Penetration Test Report

Fun With JWT X5u

By Red Siege | May 30, 2024

by Senior Security Consultant Douglas Berdeaux On a recent web application penetration test engagement, I came across a JSON Web Token (JWT) that contained an x5u header parameter. I almost […]

Learn More
Fun With JWT X5u

Find Out What’s Next

Stay in the loop with our upcoming events.