19

I need to evaluate the security of a cryptographic library. In particular I am targeting a part of the library where I believe the private key is exposed for a limited time in the RAM. Any ideas or pointers on how to go about checking the RAM for this key. I was thinking about dumping memory after some specific user interactions. But how do I start with this, any tools recommended? I am home in the security world, I know about memory layouts, usage, countermeasures against memory attacks etc. Just not in Android.

As for starter it is sufficient if the tools/techniques require custom kernel flashing or rooted devices. But in the end it should be applicable in real life situations where the target device is an out-of-the-box OEM device.

  • Are you expecting a software-only solution (e.g. malware) or for the attacker to have physical access to the device? – Dmitry Janushkevich Jul 2 '14 at 14:17
  • Both are within scope of my assessment. What are you thinking about? – 4oxer Jul 2 '14 at 14:34
  • The simplest way would be to gain kernel or root privs and simply read it off the FS. Otherwise, gain ptrace privs and rack the process memory for e.g. "BEGIN PRIVATE KEY" (depends on the key format). Then, there was this flush+reload attack, not sure whether it is applicable -- might be. I guess that's about it from the SW perspective. Note that the key will obviously be in memory since the library has to process it somehow, and this doesn't count as an issue. The issue would be not scrubbing memory after the processing is done. – Dmitry Janushkevich Jul 2 '14 at 14:53
  • Physical attacks would depend on whether the key was flushed from caches or not. If not, then sorry. If yes, then you could e.g. tap the traces and record the traffic, looking for access patterns specific to what the library does. Note this may be a bit convoluted due to caching and multitasking. Or, you could try halting the system and dumping the whole RAM chip. Both don't look very realistic to me, though, much easier to get the flash chip out and dump it, reading data from FS. – Dmitry Janushkevich Jul 2 '14 at 14:59
  • Since this looks like you first post, the very nature of this question make me wonder what you are really looking for... – KristoferA Jul 2 '14 at 15:08
11

I had the same need and after looking around I ended up writing my own program.

Usage:

memdump <pid>
memdump <pid> <ip-address> <port>

The former will output the entire process memory to stdout, and the latter to the TCP port of your choice (you'll likely use netcat on the other end).

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <arpa/inet.h>

void dump_memory_region(FILE* pMemFile, unsigned long start_address, long length, int serverSocket)
{
    unsigned long address;
    int pageLength = 4096;
    unsigned char page[pageLength];
    fseeko(pMemFile, start_address, SEEK_SET);

    for (address=start_address; address < start_address + length; address += pageLength)
    {
        fread(&page, 1, pageLength, pMemFile);
        if (serverSocket == -1)
        {
            // write to stdout
            fwrite(&page, 1, pageLength, stdout);
        }
        else
        {
            send(serverSocket, &page, pageLength, 0);
        }
    }
}

int main(int argc, char **argv) {

    if (argc == 2 || argc == 4)
    {
        int pid = atoi(argv[1]);
        long ptraceResult = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
        if (ptraceResult < 0)
        {
            printf("Unable to attach to the pid specified\n");
            return;
        }
        wait(NULL);

        char mapsFilename[1024];
        sprintf(mapsFilename, "/proc/%s/maps", argv[1]);
        FILE* pMapsFile = fopen(mapsFilename, "r");
        char memFilename[1024];
        sprintf(memFilename, "/proc/%s/mem", argv[1]);
        FILE* pMemFile = fopen(memFilename, "r");
        int serverSocket = -1;
        if (argc == 4)
        {   
            unsigned int port;
            int count = sscanf(argv[3], "%d", &port);
            if (count == 0)
            {
                printf("Invalid port specified\n");
                return;
            }
            serverSocket = socket(AF_INET, SOCK_STREAM, 0);
            if (serverSocket == -1)
            {
                printf("Could not create socket\n");
                return;
            }
            struct sockaddr_in serverSocketAddress;
            serverSocketAddress.sin_addr.s_addr = inet_addr(argv[2]);
            serverSocketAddress.sin_family = AF_INET;
            serverSocketAddress.sin_port = htons(port);
            if (connect(serverSocket, (struct sockaddr *) &serverSocketAddress, sizeof(serverSocketAddress)) < 0)
            {
                printf("Could not connect to server\n");
                return;
            }
        }
        char line[256];
        while (fgets(line, 256, pMapsFile) != NULL)
        {
            unsigned long start_address;
            unsigned long end_address;
            sscanf(line, "%08lx-%08lx\n", &start_address, &end_address);
            dump_memory_region(pMemFile, start_address, end_address - start_address, serverSocket);
        }
        fclose(pMapsFile);
        fclose(pMemFile);
        if (serverSocket != -1)
        {
            close(serverSocket);
        }

        ptrace(PTRACE_CONT, pid, NULL, NULL);
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
    }
    else
    {
        printf("%s <pid>\n", argv[0]);
        printf("%s <pid> <ip-address> <port>\n", argv[0]);
        exit(0);
    }
}

To cross-compile it for Android your Android.mk should look like this:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := memdump
LOCAL_SRC_FILES := memdump.c
include $(BUILD_EXECUTABLE)
  • 2
    What a great response! To build this you need the android NDK. Make a subfolder called 'jni', and in it place the first block in a file named 'memdump.c' and the second block in a file named 'Android.mk', then run ndk-build from the NDK – fuzzyTew Nov 1 '16 at 14:32
  • See also LiME which allows memory dump of the entire device, rather than a specific process: github.com/504ensicsLabs/LiME – fuzzyTew Nov 1 '16 at 14:37
  • 1
    I had to change the int main to void main to make it work because for some reason my compiler was complaining that the main function was not returning anything. Without this small change, I was getting a couple of errors because of the many return statements without return variables. – Irvin H. Dec 23 '16 at 20:32
8

You can dump the memory info using the Android Debug Bridge (ADB) by using the following command:

adb shell dumpsys meminfo > mem.txt

To get info for a particular app, use this:

adb shell dumpsys meminfo 'your apps package name'

This answer gives a detailed overview of the dumpsys tool. Do take a look. Also, this blog post explains another method to dump the memory of a particular running process (just found it in my Google search result).

  • 2
    that only dumps the amount of memory an app uses? – 4oxer Jul 2 '14 at 14:33
  • Updated my answer. Take a look. – Rahil Arora Jul 2 '14 at 15:04
  • This works if the device is not rooted? – CodeB Jan 12 '16 at 17:11
  • 5
    This doesn't actually dump memory, only prints some general statistics on memory usage. – ivan_pozdeev Dec 13 '17 at 22:43
1

You also have a built-in tool in Android-Studio for that, which is called 'Profiler'.

You can profile from:

  1. Attach the Profiler to the device (further explanation here)
  2. hprof file (can be generated by the 'heapdump' command in the device shell)

Example of using the Profiler:

Profiler Example

  • The picture you posted is too small to be useful. Did you accidentally post a thumbnail? – MechMK1 Jun 4 at 7:42
  • Thank you for the comment, I will fix it – user3467955 Jun 4 at 16:46
0

There are techniques to capture the Android RAM into a memory file or dump much like you could with any desktop OS and analyze the mem dump using a framework like volatility.For Android it is more than likely that you have to root the device. If you have the time this is a great 2 part guide on extracting Android memory that starts here https://www.youtube.com/watch?v=KN9kxn6htMU

Using volatility you could extract strings, see running process etc... The volatility foundation has a great blog post here on identifying AES encryption keys for true crypt in a memory dump. http://volatility-labs.blogspot.com/2014/01/truecrypt-master-key-extraction-and.html

It sounds like you could use a very similar methodology in your use case. I hope this can be of some assistance.

0

You can use GameGuardian for this. Need root.

Memory editor tab - menu - memory dump - select range and folder - press ok - wait for toast "Dump end".

Here some video examples how to do this:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.