So there are so many pen-testing tools that perform a memory dump on the system. How exactly do they work - what exactly happens ?


A core dump, either of the entire system, or single executable, is the entire contents of that processes' memory, or in the case of the system, everything's memory, written out to a file. There can be a lot of data in such a dump - here's an abbreviated form of the memory space of gvim, which I'm currently running:

pmap 19133
19133:   gvim fsstate.py
0000000000400000   2184K r-x--  /usr/bin/gvim    ; program code
0000000000821000    100K rw---  /usr/bin/gvim    ; program code again
000000000083a000     52K rw---    [ anon ]
0000000000a39000     56K rw---  /usr/bin/gvim    ; more program code
0000000002469000   3592K rw---    [ anon ]
0000003d53c00000     16K r-x--  /lib64/libuuid.so.1.3.0 ; shared object
0000003d53c04000   2044K -----  /lib64/libuuid.so.1.3.0
0000003d53e03000      4K rw---  /lib64/libuuid.so.1.3.0
0000003d55000000     28K r-x--  /usr/lib64/libSM.so.6.0.1
0000003d55007000   2044K -----  /usr/lib64/libSM.so.6.0.1
00007f46d66c7000     20K r----  /usr/share/locale/en_GB/LC_MESSAGES/gdk-pixbuf.mo
00007f46d66cc000      4K r----  /usr/share/locale/en_GB/LC_MESSAGES/libc.mo
00007f46d66cd000     56K r----  /usr/share/locale/en_GB/LC_MESSAGES/gtk20.mo
00007f46d66db000     28K r--s-  /usr/lib64/gconv/gconv-modules.cache
00007f46d66e5000      4K rw---    [ anon ]
00007fffc9ed9000    132K rw---    [ stack ]    ; stack!
00007fffc9f9b000      4K r-x--    [ anon ]
ffffffffff600000      4K r-x--    [ anon ]

From that address space, shared objects wouldn't be dumped, but everything else, stack, heap, would be. Addresses will be relative to certain versions of shared objects and potentially with ASLR they may not line up process to process. A kernel dump can be configured to contain varying amounts of information, from small dumps to everything.

What does this tell you? Exactly the state of the system or program at the time of being dumped - what it has on the stack (and so probably which function it is in). Most core dumps also contain other useful information like what is in the registers of the processor at the time of the dump.

In terms of how you work out what is going on, EIP or RIP on x86 (x64) will tell you at exactly which memory address the process was executing. rbp or ebp will tell you where abouts on the stack your function is working. You'd expect to find local variables there. You could also potentially look for all system calls and their arguments made in a core dump.

All of this serves to tell you what is going on with a process at that specific point in time. It isn't just a tool for pen testing either; it's possible to analyse core dumps as a form of debugging applications, particularly where running debuggers is hard or impossible. For example, you might analyse a kernel core dump to work out why the kernel crashed (what was it doing when it panicked?) rather than attaching a debugger and trying again - it also allows other people to send dumps to you for analysis.

How does this help with pen testing? The same way debugging helps with pen testing. You can see what's loaded in memory, what the current state is. You can work out what a process might be doing when you took the dump and perhaps most crucially, any data stored in any executable in memory (heap, stack etc) will also end up in the core dump, including passwords stored as plaintext in memory.

What do the analysis tools do? Look for patterns and structures indicative of a potential exploit (or error, if you're after debugging). A full explanation of that is probably beyond the scope of this box - there are many books dedicated to techniques for analysing memory dumps. Much of this is also system and architecture dependent; techniques for Windows x86 are different to techniques for Linux on MIPS.

As an example of something that might be indicative of an error, here's an example AviD will really appreciate:

push    rbp
mov rbp, rsp
sub rsp, 32
mov QWORD PTR [rbp-24], rdi  ; this is a char* argument stored on stack
mov rdx, QWORD PTR [rbp-24]  ; and this is a pointer loading it into a register
lea rax, [rbp-16]            ; this is only 8 bytes further down
mov rcx, QWORD PTR [rdx]     ; load contents of rdx into rcx
mov QWORD PTR [rax], rcx     ; put those 8 bytes to rbp-16
mov rcx, QWORD PTR [rdx+8]   ; load next 8 butes
mov QWORD PTR [rax+8], rcx   ; write to rbp-8   
mov rcx, QWORD PTR [rdx+16]
mov QWORD PTR [rax+16], rcx  ; write to rbp     
mov rcx, QWORD PTR [rdx+24]
mov QWORD PTR [rax+24], rcx  ; write to rbp+8   
mov rcx, QWORD PTR [rdx+32]
mov QWORD PTR [rax+32], rcx  ; write to rbp+16  
mov rcx, QWORD PTR [rdx+40]
mov QWORD PTR [rax+40], rcx  ; write to rbp+24  
mov rcx, QWORD PTR [rdx+48]
mov QWORD PTR [rax+48], rcx  ; write to rbp+32
mov rdx, QWORD PTR [rdx+56]
mov QWORD PTR [rax+56], rdx  ; write to rbp+40
lea rax, [rbp-16]

As you can see, the first space available to this function on the stack for local variables was rbp-16 and below. Above that, we've just happily clobbered a stack frame with a whole pile of data, probably causing the program to crash. However, this code may well indicate a possible exploit. Looking for patterns like that in a crash dump is what makes them useful, and moreover rip in this case will tell you exactly which memory access caused the problem, because it'll point at the offending instruction (in theory).

In case you're wondering, the offending piece of code was simply a memcpy from an unbounded buffer into a much smaller target space. The function call to memcpy was optimised out.

| improve this answer | |

First of all, there are two main users of memory dumps in security - forensics and exploit writing guys. Pen-testers, not so much - of course it depends on the pentest ;)

The usual way tools that dump memory work is by opening the memory pseudo-device and reading all the contents to a file.

For example with dd in windows you would do something like dd if=\\.\Device\PhysicalMemory of=memory.bin bs=4096 (pre win-2003, after that you need a kernel driver)

The same applies to linux e.g. dd if=/dev/mem of=/home/john/mem.bin bs=1024

This is the simpliest way of course. Other ways to acquire memory are by using crash dumps as Ninefingers mentions, LiveKd dumps, get the memory through the hypervisor if we are talking about a VM, get the hibernation file if one exists or even get the memory through fireware or another DMA interface. Of course, then there's the cold boot attack too.

Having the memory on a file, you can do many things, depends on what you want. The common one is to search for strings, e.g. password tokens, private keys and the rest, this is the easiest one.

If you want to do any more than that, usually a lot more work is needed, but is automated with varying degrees of success using commercial or open source tools. The main idea is that physical memory in your dump will be scattered in pages. To make any sense of it, you locate by heuristic search the page tables, and try to reconstruct a logical view of the memory. Having done that, you can perform other searches and locate structures for the various running processes, open files, network connections etc. It really depends on what your goals are.

| improve this answer | |
  • That's a good point. It's also possible to implement a rootkit via this mechanism - the Linux-based suckit rootkit opens /dev/kmem and manipulates kernel structures directly. +1 – user2213 Jul 12 '11 at 12:21

It would help if you listed which tools, as there are differences - eg whole memory vs specific areas. I can't think of any attack tools I use regularly that dump memory.

But simply, taking a dump of memory let's you look at not only the application code in situ, but also variable values.

The memory is just copied to a disk similarly to the way memory pages are swapped to disk in normal usage, or a tool reads memory directly.

| improve this answer | |

If you're on Windows, use Process Explorer from the SysInternals suite. Just right-click a process and elect to dump the memory for that process.


| improve this answer | |
  • 1
    I think it was more a question about how the tools work, what they do, rather than "how do i work the tool".... See e.g. @Ninefingers' answer. – AviD Jul 20 '11 at 12:14

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.