Core Dumps

In the last post I had discussed about the Heartbleed defect in the OpenSSL. The vulnerability opens up a method by which in a hacker can over a TLS connection with a server retrieve sensitive information like the private key.The server can be made to emit its memory contents over the wire without it being aware of it. There were successful attempts in finding the full server key by using this vulnerability. It is clear that if an application can  hold sensitive information in memory, it should be taking steps to prevent it from being visible.

One way in which a snapshot of memory of an application can be obtained is by causing the application to crash and have the core dump of the process. The crash can be a due to a genuine bug or the application could have received intentionally created signals that causes process crash. So if your application potentially posses sensitive information in memory, you may want to prevent that data being written do disk on a program crash. An attacker can use debugging tools like gdb to analyze the core dump and can use the information.

So, how do we prevent the dumps on process crash? Consider the program with a very nasty bug as shown below. Assume this to be sophisticated program which handles sensitive information like passwords.When this program is run, for obvious reasons it is going to crash and dump core.
#include<stdio.h>

int main()
{
    char password[] = "secret";

    int *tmp = NULL;
    *tmp = 100; //Cause Crash

    return 0;
}
Running the core dump through gdb, we see, as shown below that we are able to see the contents of the char array which in our case holds some password which by definition should be not be known to to all. Dumping core also has another effect. In case of large programs, core dump can be huge and can take up a sizable disk space which can hamper system in other ways. So the best option is to disable dumping of core on process crash.
4
On Linux systems, we can use the ulimit option to prevent the core dump as follows:
 ulimit -c 0 // This essentially says that the core file size is zero bytes.
But an attacker may be able to manipulate the program’s run time environment such that the above can be overridden.
#include<stdio.h>
#include<sys/resource.h>

void spc_limit_core(void)
{
    struct rlimit rlim;

    rlim.rlim_cur = rlim.rlim_max = 0;
    setrlimit(RLIMIT_CORE,&rlim);
}

int main()
{
    spc_limit_core(); // Limit the size of the core.

    char *password = "secret";

    int *tmp = NULL;
    *tmp = 100; //Cause Crash

    return 0;
}
By setting the RLIMIT_CORE to 0, we prevent the process from from leaving a memory snapshot onto the disk. We will have to have the call  spc_limit_core() at very beginning of the program before anything else can come into memory.One disadvantage with preventing core dump is that it makes debugging process crash difficult. No forensic clues are left behind for us to analyze the cause for the crash.  This can be overcome by allowing core dumps only when run in a controlled manner. A debug version of the application can be separately built. This build shall have the compilation option to enable or disable the call to spc_limit_core(). This can be done by enclosing the call within a preprocessor directive as shown below:
#ifndef DEBUG
    spc_limit_core();
#endif

Leave a comment