Runtime encrypted strings | Part 1

Runtime Encrypted Strings

Today we will go through the basics of runtime encrypted strings, why do we need to encrypt our strings and learn how to create our own.

In this article you will understand and learn:

  • What is runtime encryption and decryption
  • Why do you need to encrypt your strings
  • See how anybody can see your sensitive data
  • Create your own custom encryption

What is runtime encryption and decryption

This refers to data encrypted and/or decrypted during the runtime of a program (software, application). The data can be of any type from memory blocks, network traffic, strings, etc.

One of the most common methods used for this purpose is obfuscation (basic). The other (advanced) mechanisms involve mutation/virtualization of compiled code.

Today we will focus on a mechanism using XOR obfuscation.

Why encrypt strings ?

The moment you run your software everything is visible in memory. This applies to your end users as well which means they can see everything.

One of the first things an attacker will do is look for strings inside your software. This will allow him to understand everything about your software with minimal effort.

If you are storing sensitive data (like passwords or licenses) it is crucial to not keep them in plain text. Keeping them in plain text will make the life of an attacker easy.

There is a number of ways people can use to analyze your software. The most known and common methods are static and runtime analysis.

Let’s have a look at a simple example using a console app:

Runtime Encrypted Strings - Sample non-encrypted 1
Sample non-encrypted 1

We compile this in Release mode (to avoid any debug information left inside). Let’s proceed and test the static and runtime analysis.

Static Analysis Test

In static analysis the software does not need to execute. With that said, let’s open the sample in Ghidra.

From the screenshot below you can see that the sample is compiled without any debug information:

Runtime Encrypted Strings - Sample non-encrypted 1-1
Sample non-encrypted 1-1

If we search for strings you can see that all our sensitive information is visible:

Runtime Encrypted Strings - Sample non-encrypted 1-2
Sample non-encrypted 1-2

Once you highlighted the string you can open the decompiler view and see all the relevant code:

Runtime Encrypted Strings - Sample non-encrypted 1-3
Sample non-encrypted 1-3

Pretty sad eh ? 🙁 Imagine you worked on your amazing software for months, and you are ready to sell it.

I think the rest is self-explanatory, but I’m sure you get the point.

What’s even sadder is the fact that this is so simple that even a 12-year old can do it. (and some actually do it)

Runtime Analysis Test

In runtime analysis the software needs to run (execute). This means we need to use a software to open the process and read it. (normally a debugger)

However, a debugger is not really needed for this purpose. We can simply download a free tool like Process Hacker and open the process:

Runtime Encrypted Strings - Sample non-encrypted 2
Sample non-encrypted 2

That was rather simple right ? And keep in mind that we haven’t even attached a debugger. A skilled and determined individual will use a debugger.

When you attach a debugger you see much more, but that discussion is for another day.

Creating Runtime Encrypted Strings

There are numerous ways you achieve this:

  • Using a third party software like VMProtect, Themida.
  • Compile time string encryption like xorstr.
  • Using custom methods

The first 2 options might not suit your needs. There are many ups and downs for each of them, which we will not discuss at this point.

One thing you need to understand is that popularity means risk. When you use stuff found randomly on Google, someone already knows about it.

Most people developed a tool against your tool. It’s just the way things are. They do it for a challenge, or to steal your work, but they do it.

With this in mind, you must go custom. You can create your own string encryption from basic to advanced level.

The Plan

  • Create an easy to use solution
  • Keep strings encrypted at all times
  • Decryption only when you need it
  • Place the strings in random location (optional – not covered)
  • Destroy the strings after using them (optional – not covered)

The Solution

Start by defining our strings one by one as an array:

Runtime Encrypted Strings - Step 1
Step 1

The array can hold an unlimited number of strings with a 256 length limit.

I know this is a daunting task, especially if your strings are long. This is just for demonstration and later on we will create a more practical solution.

The idea is to encrypt each character from the string. I will use a simple XOR encryption for this.

Below you can see an example of how this would work:

Runtime Encrypted Strings - Step 2
Step 2

The above has nothing complicated going on, it’s plain and simple yet quite powerful. You can use this inside a console application.

After you compile and run, the result is unreadable bytes to the human eye:

Runtime Encrypted Strings - Step 3
Step 3

There you have it, your own little software to create runtime encrypted strings. 🙂

The Result

I’s time to put our solution into practice. Let’s create another sample for this purpose and add our code:

Runtime Encrypted Strings - Step 4
Step 4

Notice 2 important things:

  • I’ve left some strings in plain text so you can see the difference
  • The decryption functions needs the length (more on this later)

We compile the above in Release mode and run it. The new Sample is working normally:

Runtime Encrypted Strings - Step 5
Step 5

If we open the new Sample software in IDA the strings we encrypted are not visible:

Runtime Encrypted Strings - Step 6
Step 6

I’ve mentioned that there are some string intentionally left plain in this sample. The reason why is, so we can follow them to see the code:

Runtime Encrypted Strings - Step 7
Step 7

I had to scroll down to reach the text in the above image. You can see how different the compiled code is.

We solved the static analysis problem, let’s move on to runtime.

Open it in Process Hacker:

Runtime Encrypted Strings - Step 8
Step 8

Voila! We solved the runtime analysis problem as well 🙂

More on encrypted strings

The above example is not very practical. Defining each string manually is a daunting task, as well as specifying the length of the string each time.

Ideally we would need the following:

  • Reading a text file for strings
  • Writing to a text file the resulted strings
  • Adding the Escape sequences to strings to avoid specifying the length each time.
  • Add more complex XOR or any other method (optional)
  • Place the strings on random locations (optional)

I have prepared a nice solution for you to play with. You can test everything written in this article and also have your own ready to use tool to make runtime encrypted strings.

It includes 4 projects:

  • RuntimeStringEcryptor which reads from a text file strings, encrypts them and then writes them to another text file.
  • Sample is the plain simple console used to demonstrate with IDA.
  • SampleEncryptedStrings is the simple console with encrypted strings to demonstrate with IDA.
  • SimpleRuntimeStringEncryption is the initial playground where you can test this method.

Notes:

  • If you don’t add escape sequence, the decryption will not know when to “stop”. The result being in gibberish/null data until it reaches the defined array size.
  • Make sure you change the XOR keys I have used in my example.
  • Avoid using the same words multiple times. They will generate the same bytes and it’s a risk of being detected.

Download

To download the ready to use solution, please consider supporting this blog 🙂

Sorry! This part of content is hidden behind this box because it requires a higher contribution level ($5) at Patreon. Why not take this chance to increase your contribution?

Liked it? Support me on Patreon with a coffee 😀

Leave a comment

Your email address will not be published. Required fields are marked *