Protecting data in memory

3

I have read a lot of articles on cryptography etc ... The encryption reported by the posts was a success in my program, however some data stay in memory being vulnerable to Assembly readers in real time. An example of this is Cheat Engine , which I use to check the security of my application in memory. See the example below for an example of the code I used:

//A string desprotegida
string strCriptografar = "stringParaCriptografar";

//Classe que uso para criptografar
Cript criptClasse = new Cript();
//Aqui criptografo o valor da string...
string textoCriptografado = cript.Criptografar(strCriptografar, "mykey");

By this I can encrypt the string value, but when I parse in the disassembly string with the text still in memory at the time of execution. Could you help me?

    
asked by anonymous 09.04.2016 / 14:18

2 answers

4

As already mentioned, a security issue is rarely simple . However, if you need to have data in memory without it being visible, do not use any temporary / fixed variable for storage before encryption.

On the face of it, this involves a somewhat more specific problem that is how memory management is done in .NET. So if you use a string variable, it will be stored until the GC decides it is no longer useful and you have no control over when it will be deallocated.

There are several articles on this, try this: link

Also, why do you need to start the string in a plain text variable? If you are going to use it, you could at least use it in a SecureString , see this link:

link

But, there also involves how much a SecureString is secure :)

The biggest problem is how you pick up the string and how your encryption works. But at some point it will go through the memory to be encrypted.

You could use unmanaged code to better control how long it stays in memory, but unmanaged code has other security issues, many of which are linked to memory management or program execution flow.

There is no silver bullet. Even a char, typed on the keyboard, has to go through a buffer, just try to ensure that the place where you put the plain text, exists in the shortest possible time and is never stored in a long-lasting scope.

See the difference in the code example of the SecureString link:

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security;

public class Example
{
    public static void Main()
    {
        // Instantiate the secure string.
        SecureString securePwd = new SecureString();
        ConsoleKeyInfo key;

        Console.Write("Enter password: ");
        do {
           key = Console.ReadKey(true);

           // Ignore any key out of range.
           if (((int) key.Key) >= 65 && ((int) key.Key <= 90)) {
              // Append the character to the password.
              securePwd.AppendChar(key.KeyChar);
              Console.Write("*");
           }   
        // Exit if Enter key is pressed.
        } while (key.Key != ConsoleKey.Enter);
        Console.WriteLine();

        try {
            Process.Start("Notepad.exe", "MyUser", securePwd, "MYDOMAIN");
        }
        catch (Win32Exception e) {
            Console.WriteLine(e.Message);
        }
        finally {
           securePwd.Dispose();
        }
    }
}

The main difference is that it does not save a plaintext string and then move on to encryption, it already adds char to the char to the encrypted string.

Another thing he does is that he overrides each char with each new character entered, so only SecureString contains the whole sequence in memory, but the current char remains in memory for as long as the scope and GC allow .

This particular case of analysis, at first glance, seems to only serve a char to char entry by the console, however, you should remember that it can be applied to the stream stream by any byte-by-byte, not forgetting hidden buffers in the implementation of most standard APIs.

In addition, if the machine is compromised, even this approach falls easily on a Keylogger. :

    
09.04.2016 / 18:35
5

The only help we can give is not to keep the password anywhere. There is no miracle.

If you need this entire protection, do not store any password. Let the user enter the password you need access to.

  

Ah, but still a running application can be intercepted and pick up the password at the time of typing.

Yes, and there is nothing that can be done. If the computer is compromised, if there is a possibility of this interception, it will occur. That's why a computer as a whole needs to be safe.

Security is extremely complicated. Usually when you need it, the best thing to do is hire a highly trained specialist. I do not even know if this fits right. Even if you hire one that is not misleading. It is very easy to make a mistake in security. Or do you think these known security breaches occur only by relaxation? Of course, there are cases that is relaxing, it is complete ignorance, but in many cases everything that was given was done and yet the security was mocked.

In this case it seems the encryption seems to be being applied even naively. Maybe because you think security will happen otherwise. Please read on this question . I have serious doubts that encryption was "a success". Do you have definite proofs of this?

A possible palliative solution

The .Net has a string that helps a bit what you want, but it has a limit and only helps if it is used right. The question has little context, I do not know if it would help this case. The description is clear that it only keeps the text for the time needed. This time is enough for an interception.

    
09.04.2016 / 15:30