Physical memory forensics has gained a lot of traction over the past five or six years. While it will never eliminate the need for disk forensics, memory analysis has proven its efficacy during incident response and more traditional forensic investigations. Previously, memory forensics, although useful, focused on a process' address space in the form of Virtual Address Descriptors (VADs) but ignored other rich sources of information. In the past, some techniques of process reconstitution have been auspicious at best and erroneous at worst. This presentation will build upon lessons learned and propose more thorough ways to reconstruct process contents, and therefore a process' address space. By using the methods presented, it will be possible to further reduce the data you care about in an incident response or forensic investigation and to better apply the traditional computer security techniques such as reverse engineering, hash matching, and byte pattern or signature matching such as those provided by ClamAV and VxClass.
 Welcome, this is physical memory forensics for files and cache. I'm Justin Murdoch and to my right is Jamie Butler. Just a bit of background information. Jamie Butler is the director of research and development at Mandiant. He focuses mainly on host analysis and operating systems research. I'm a computer science major at the Rochester Institute of Technology, but I'm currently on co-op at Mandiant working on their enterprise product as a software developer. So we're going to speak today about physical memory forensics and this is kind of a layout of the talk. First we're going to go over traditional forensic methods, kind of a background information, and then specifically move on to memory forensics. And given that background, we're going to speak about the issues that are in existing tools right now. So a lot of them are missing important information and often misattributing data to executables. So most memory forensics also deals with utilizing files. So we're going to speak about memory mapped files, reconstituting binaries and data files, and specifically the role that cache plays in this process. Then we're going to talk about possible applications of our new techniques and show you guys a couple of demos and then we're going to speak about our new tool that we're going to be releasing pretty soon that uses these new techniques and speak about, wrap up with just some further work that needs to be done in the area. So traditional forensics is kind of a broad overview. A host has two large sources of information for forensics, so the disk and memory. And lately memory has become a great way to triage a host, say in a forensics investigation. So the reasons for this are the average size of disk is growing extremely high. So most hard drives out there come at least 250 gigabytes. I know people in this room probably have way more storage space than that. So searching through that whole image or just dumping a full copy of the hard drive is getting to be a much longer process. And memory can really help you out to speed up what you're looking for. It's relatively small comparatively, so you can scan the whole space pretty quickly. Also, for intruders to get their code running on a system, they have to load it into memory. And in almost all cases out there, they aren't covering their tracks. They aren't cloaking their memory footprint, because that's really just too much work in the most case. So also many of the artifacts that the kernel needs to load the program into memory we can use to gain a lot more information about the executable. So specifically for memory forensics, memory is divided really into two basic sections, userland and kernel memory. This talk is going to focus on userland memory, again, because in most attacks, most intrusions, they're focusing on userland memory. It's easier to get execution and it's more resilient to coding errors. Basically, if you're developing this attack, then if you got a couple bugs in your program, all of a sudden you have to crash the system because it's running in the kernel. So it becomes very costly to develop these kind of attacks. So memory forensics traditionally focuses on recovering all the binaries out of the memory. So all the executables, DLLs, this is one of the main focuses of any investigation. And most of these tools rely on virtual address descriptors or VADs. These describe the processes address based in memory. And they make up, they're made up of these objects. So as you can see, it's got a pointer to left and right child. It's usually in a tree structure. And each VAD also contains the starting address and the size of the memory, along with a pointer to the control area. So here's a representation of a typical VAD tree. You can see it starts with a VAD root and just each one of those VADs contains information about the virtual addresses of the process. So traditionally, you would scan physical memory for an E process block. And that kind of lets you know that there's a process at that location. From there, you get the directory table base or DTB in the E process. And this will help you translate from virtual to physical addresses. From there, you locate the root of the VAD tree and just kind of step through the tree, translating the virtual addresses to physical, and usually start with the starting address, take the size, and just grab all the data in between there. Some other tools also utilize information about the PE headers to reconstruct the executable with their knowledge about the different sections inside. An alternate approach is to just use the DTB to try and translate, basically brute force the whole address space. And it kind of just starts at a beginning address and goes all the way through to the end. And this has its limitations, really. On a 32-bit system, this pretty much works because you got an upper bound of about like four gigabytes. But on 64-bit, the size can just be enormous. This also leads to some misattribution of the data because the virtual addresses could translate globally, not particularly for that process. And this kind of leads us to problems that are in existing tools right now being used. So with that, I'm going to hand it off to Jamie Bowling. So as Justin mentioned, the traditional approach in the current memory forensic tools is to really take a virtual address, its base and the size. Even if that virtual start is zero and size is four gig, you're going to brute force across the whole thing and you're going to do the translation in the context of the process that you're trying to analyze. So every process as the previous slide showed has a directory table base and that is used for the virtual to physical translation and that should tell you what's in the process context. Well, what we found in our research is that there's a lot of data that's actually missing if you do this. For instance, the first thing that we encountered is when we're trying to reconstruct a process, obviously like the attackers usually injecting code, you know, in the form of an injected DLL or whatever into the process address base, so in order to analyze that and to detect it, we need to be able to translate the code for that DLL. Well, the operating system, the Windows loader is going to load the DLL as a memory map file. So memory map files are stored in a special way because basically the OS doesn't want to waste space. And what do we mean by that? Well, on a Windows host, you have, let's say, a user mode process or every user mode process, most likely has the DLL, NTDLL.DLL mapped into its address space. So if the OS did not use memory map files or the shared files across the address bases of all processes, then that DLL would have to be replicated for every single process that loads. So obviously that would waste a lot of physical memory and this design was thought up, you know, back in the probably Windows 16 bit versions when there wasn't a lot of memory to waste in the first place. Plus it's also just more efficient in today's world, you know, we're a greener, so let's not waste memory. So these memory map files are shared across all processes even if they're only used once, right? So because of this, they may not, they may be in your process address space, but the address that they represent may not translate in your page table entries. So I won't go into the depths of how you do virtual to physical translation. If you want to learn more about that, there's slides on the internet and so forth, you can Google those. But basically the page table entry is the very last table structure you'll find when doing a virtual to physical address translation. When you go to read it to find out where the physical page is, lo and behold, it's all zeros. So that doesn't tell you anything. That means typically we just had to ignore that region because we couldn't get access to it. And here's an example of taking the Honeynap project challenge 3. If you're familiar with that, that was a memory image. It came out about a year and a half ago. It translated or I acquired these files out of the memory image. And there I just chose file at random. And you see the file size there in the first column. And then the bytes acquired with the traditional approach. So that's using the VADs. That's a starting virtual address, ending virtual address, and using the DTB of the process to acquire it. And that's how much of the file that we could acquire. And then I used a different technique that we'll cover in the last half of this presentation, which was using what's called file objects, which represent the memory map files. So for instance, with the ace.dll, we got 70% of it using the traditional method, but we were able to increase that to 93% using this more accurate method of the file objects. Also, we'll talk about in a moment what you can do, how this number may go up to actually 100% if you're running on a live system and non-memory image because you have access to the disk. The second problem that we ran into is basically when you're doing... We come from a background where we build products and tools to do incident response. So in that context and even in probably some of your more traditional forensic investigations, trying to determine exactly which process is infected is important. So knowing the whole host is infected is perhaps interesting, but then the next question you're also going to ask you is, well, which process is... Or how do you know what artifacts within that host are infected? Because they may lead to things like user accounts have been compromised. Also, processes have a creation time to tell you perhaps around the time of the infection if they were creating new processes and so forth. So attribution is important to us. One of the issues with the traditional approaches, especially with the brute forcing method, is if you brute force over the global address space, as Justin alluded to, there's areas of the address space that are global for every process. So basically when you cross from virtual address in user land and you go into virtual addresses there in kernel land, most kernel addresses will translate appropriately in every context address space. And the reason this works and everything, you can read Marcus Onovich's Windows internal books and take those to bed at night and it'll keep you warm. But basically if you do that over a couple of years, you'll figure out that the kernel addresses appear global because Microsoft wanted to save entries within the cache. Within the actual cache that's on the chip, you know, like your L2 cache, they wanted to save cache lines so they have these global addresses and save time on speed transfer context switching so they didn't have to flush the cache every time and so on and so forth, so kernel addresses basically are global. Here is a graphic that someone else stole from the Windows internal books that we stole from the person off the internet because I don't like to draw. So this is a virtual representation of a 32-bit system. And basically all I want to show here is you'll see there at C100, 0000, is the beginning of system cache. So that is a cache that the operating system is keeping that's different from your L1, L2 cache that the CPU is keeping. This cache is going to be used for things like file I.O. So if you request to read a page of a file, the operating system is going to assume that you're probably actually going to want to read more than one page, so it's going to read ahead. And that read ahead is going to cache for you and it's assuming locality of reference, all your future reads statistically should be relatively close to where you're currently reading in typical programs. So those go into the cache of that virtual address. Well, if we acquire memory or acquire a process and we're brute forcing basically anything in the cache will appear to be in every single process. So that's really bad for attribution. So let's talk about ways to make this process better. So we're going to utilize file objects. And file objects can represent a number of different things. They can be, for instance, memory map files that we kind of touched on, which would include DLLs and EXEs. They also include data files, which may not be mapped into memory but are in the cache in different places, like a word or PDF or registry hive, web history. We've seen restore points, Windows XP, those nice restore points so we can actually see after the attack are attacked we can see what was happening on the system, what they installed because of the restore points. So the vads are still interesting to us but we're going to utilize a little bit more data that they make available. So vads describe a range of memory that the file occupies. And if it's a memory map file or if it's a file object represents that region of memory then the VAD will have what's called a control area. And if you're very familiar with Windybug you'll be used to these structures that we're talking about. Control area would have a pointer back to the file object. So we're finding vads in memory because we found the E-process block. Once we find the VAD we're trying to parse it to see its control area. Once we get to the control area we're parsing it to find its file object. Now file objects contain some useful data including the device name that would be things like hard disk volume 1 as you see in this example. You can then translate that for the OS in question for your host that's probably C colon or whatnot. Also it will contain the file name itself and then the next thing that we're going to talk about today is this table of three pointers depending on where the file data is actually backed up. So the three things we're going to look at are image section objects, data section objects and shared cache map. Here's a graphical representation of a file object. It contains a pointer called section object pointers and section object pointers only has three members and Windy Bug will tell you all this or Rosonovich might as well. So image section objects represent, are very interesting to us in forensics and IR because they represent binaries that are loaded in memory. So if binaries load up the windows loaders go to create a section object for that binary. But this pointer, this image section object thing is not actually a pointer to the structure called image section object that doesn't exist, it's actually a pointer to a control area. So yet another control area. That control area will have a pointer to what's called a segment object. This segment object can be used for sanity checking like if you were just scanning through memory you may find some artifacts that are no longer in use that aren't actually usable. If you try to parse them in certain code you probably crash. So we'll use this for sanity checking. That segment object will contain a segment size and the total number of PTs represented by that segment. So we'll talk about PTs in a moment. But basically for sanity checking you can compare the segment size equal, should be equal to the total number of PTs times the page size. Page size in Windows for the most part you can just there is a small alteration on page size but for the most part you can assume that that's 4K or 1000 hex. The thing that you're going to want to be parsing if you're trying to dig out the binary data from memory would be the subsections. So subsections represent the individual pieces of a file. How many here has ever loaded up like a, looked at a PE a portable executable in PE view or Lord PE or some other viewer. Basically what you'll see in there is that the PE file is broken into a bunch of sections. So there's like a code section that's usually called.txt. There's a data section, there's a resource section. There's different things like that, relocation section. Well all these sections have a relative virtual offset relative virtual address within the PE and then they also have permissions. So once this thing loads into memory what should the permissions on that section be? Well since each section within the PE file probably has different permissions then there has to be a subsection object that represents every single section within the PE. We couldn't find a pointer that would show us where the subsection object was. So if you just stare at the hex for long enough the math starts to come out at you. Basically the subsections all seem to line up at the very end of the control area that we just found. So although the segment object was way away in virtual memory the subsection object was immediately following the control area. So that was nice for us. Basically for every version of the OS you can just determine how large the control area is add that to where the base of control area was and then cast that as a subsection object. So the subsections will contain an array of prototype PTEs. This is the crux of the data that we have to parse in order to get the binary out of memory. So the prototype PTEs contain the physical address of each memory page in physical memory. So we'll have a graphic in a moment. It may be a little bit more useful for you, but I'm not sure. Basically though, if the prototype PTE contains the virtual address of that subsection object that it's within then that means all bets are off. Basically this page of memory is on disk. And when I say on disk, I don't mean probably you've heard arguments back and forth about, hey, can you acquire the page file and use that for memory forensics and stuff too. I personally believe you can't. You can only use the page file at runtime. But even if you were to be able to use offline page files and marry those up with offline memory images, even if that were possible, you won't be able to access the data that's represented here because memory map files mean exactly that. They're memory mapped. So if they're page to disk, they don't go to the page file. They are represented by themselves on disk. So if you want to get that data, you have to go to the location of NTDLL.DLL on disk for sector 15 or what you need or what not and read the data. So the page file is not useful in this case. Also something else that's within this subsection object will be the number of full sectors and the number of prototype PTs for the subsection. So again, going back to disk, when we're looking at the on disk, the disk sectors are 512 bytes. And the page alignment in the Windows OS is 4K. So there's a little bit of a fix up that you have to do. So you have to take into account the total number of PTs that this subsection represents, but also the total number of sectors, full sectors that it represents. And it contains these numbers in the structure. So you use that in order to parse it correctly. Because if you were just reading PTs blindly, you would get more data than is actually within that subsection. And the file in memory wouldn't line up like it does on disk. So we're going to use those full sectors to our advantage. And basically by keeping track of where we are when we walk these sectors in memory, you know, 512 bytes at a time, we will know the offset that we need to read if the file is page to disk. So using that, we can get all the data if we're running on a live system. Another thing of interest is there may be, there's probably definitely more than one subsection, especially if it's PE file. So there will be a pointer to the next subsection. And you basically just chase the chain, right? So this is just a nice graphic of what that looks like in memory with our array for each subsection. Now data section objects, they represent data files in memory. I'm not sure what types of files load themselves as a data section object. I know that PDFs don't, but Word documents do. So if you're loading up Microsoft Office documents, they're going to look like in memory the data section object. That structure actually is exactly like an image section object besides a few sandy checks that don't work in this case. But basically since they're the same, you know, data section objects and image section objects, they point to the same structures, we can surmise that the data access for a Word document would be just as fast as the access, as any data access or code access in this case, for an image section object. So Word documents are going to perform as well as EXEs, right? Because the structures are the same. It's a shortcut of where to get the data. It's not relying upon the cache, which is somewhat subjective. The OS defines how to load the cache and when and when to flush it based upon utilization on the system and the number of resources available. Well, if you have a data section object, that's not the case. All your structures are right there. You have quick immediate access to the data. So I thought that was kind of cool. Maybe Adobe should change how they load their files. So we've covered image section objects and we've covered data section objects. The last thing we'll touch on here is the shared cache map. So the shared cache map is used to represent the file data in the cache. So if all other bets are off, you know, if you don't have an image section object, you don't have a data section object, then you should go parse the cache structures in order to get as much data as is available. Now, again, that may be nothing or it may be more or less the whole file. It really all depends. So in the shared cache map structure, this structure is actually defined by Microsoft and in Windybug. It contains the file size, the amount of valid data within the file, within the cache. The valid data should never be larger than the file size because if that happens, then you're actually looking at uninitialized data. Also, it contains an array of pointers to VACBs. So VACBs are virtual address control blocks. This is the structures that define where the data is in virtual memory in the cache. So if the file is one megabyte or less, then Microsoft decided to put in some performance improvements by embedding an array of four VACBs right into the shared cache map itself. So no reason to chase anything. They've just embedded it right there, which works really nice for them because often the things in the cache are less than a meg. You'll probably go have a lot of web images and so forth that are in the cache. There will be less than a meg in size, so let's keep it simple. Each VACB, I should mention, represents 256 kilobytes. So if you have four of those, obviously you can represent a one meg file. If it's larger than a meg, though, we have to go to an array of pointers. So what that looks like is it's a nested structure. If it's one level deep, basically there's one array that points to the VACBs themselves. It can represent 32 megabytes if it's one level deep. I think, I forget the number, I believe each array has 128 entries. So if you read Marcus Hanovich's and David Solomon's book on Windows Internals Chapter 13, I believe, in the newest version is all about the cache. And they'll tell you how to calculate the depth of this tree. So arrays of arrays of arrays of arrays, it gets really fun. I recommend recursion. But anyway, the largest file that you can have on Windows OS is 2 to the 63rd power. So that's the largest you can have, and because of the number of entries in each array and so on and so forth, and the number of blocks that they can represent, your tree can be no deeper than seven levels deep. Here's what the shared cache map would look like, kind of conceptually. This, obviously, at the bottom is just two levels deep. And if we parse this, we'll get all the file data that is present in the cache. So let's talk about some of the applications in this technology. Well, in the past, most of the tools, I believe all the tools that are out there freely available, will parse the VAD tree in order to do process reconstitution. But probably since we care about some data that's in the file system or in the file cache, we should probably also parse the handle table. So we'll go parse the handle table, we'll go parse the VAD tree, and then once we get there, we'll go parse the file objects that we find. Now, the Windows registry hives are a nice example of how you can use this. If you would analyze the system process, basically it has a handle to every registry hive that's in memory so you can get all the data there. So let's say you're going to acquire this to your local hard drive or to your system analyst station so that you can do parsing with your traditional registry forensic tools, you would want to acquire the system process out of memory. Once you have that, it'll literally write the individual file names to the local hard drive with the content of those files. Also PDFs, as I mentioned, are found in the cache. We haven't had a ton of time to research all the things we can get out of the cache. If you're on a Windows XP system, you can get the restore points because it has a handle to a file that is basically keeping the data for the restore points. So you can get that out of memory in some cases. But as the caveat for the cache is, it's all bets are off. It's hit or miss or other would be useful. The way we're going to use this most likely and some of the free tools that we're releasing are to do data reduction. So we have a hashing. We beat up on the AV industry all the time about hashing and how it sucks. That's nice. I've done it myself. However, hashing can also be useful. I mean, we have over two decades of data, so let's start to use it to our advantage to make the problem simpler. Memory forensics is all about data reduction. So we went from a 250 gigabyte hard drive. Now we're down to a 4 gigabyte memory image, probably. Now in that memory image we're going to find roughly on the Vista or the Windows 7 machine, I looked at, we're going to find about over 4,000 files in memory, right? If you don't take into account eliminating duplicates. So everything's going to have a handle or a VAD to NTDLL. Everything's going to have a VAD to kernel32.dll and so on and so forth. So now we went from 250 gigabyte that we care about, maybe at first, down to 4,000 files. And then we do a data reduction to get rid of redundancy, and now we're down to about 1,500 files. Well, now the problem is starting to get a little bit more manageable in finite time. So if we could use white listing and hashing to eliminate the other components of the operating system that we don't care about, that number would get a lot more manageable. So there's been some efforts in the past, not my research, but others, who've done fuzzy hashing and different things like that, in order to try to make the hash that's found in memory match the hash on disk. The problem with these fuzzy hashing techniques is we don't have the data going back years, because they just take subsections of files. And most white listing technologies and so forth use the full hash of the file. So the comparison is difficult to make, and it may have benefitted in your organization, like if you had a white list, I mean a gold master that you were deploying across the enterprise. You may be able to use data reduction with fuzzy hashing. However, we found that most people don't have this, and so we went to the section image object, and we parsed it like on a law of system, which means we can get access to the file system as well if there's a page that's not there in memory. And by utilizing this data, we can make the hash that we find in memory match the hash that's on disk. So we call this memd5. It's a cute name of our other coworkers came up with. That will be released in the free tool that I'll talk about in a moment. Another application for this better process reconstitution or binary acquisition, what have you, is that there's a lot of tools out there that are starting to use, you know, like byte patterns of malware and things like that. There was a tool developed by Xonamix, which was acquired by Google, unfortunately, and they killed the project or took it internally. They came by it anymore, but it was called VX class, and it was kind of cool. I liked it enough that I convinced my company to buy it. But VX class would generate byte pattern signatures for classes of malware, so families of malware. So what the VX class leveraged was that if you had a malware sample or a lot of malware samples, they were reusing code. And if you were doing IR, you probably didn't want to focus, you know, all your... You have a limited amount of resources, so you probably don't have a large malware team, what not, you don't want to focus all your efforts looking at the last 50 variations of ZOOspot. You just want to throw it into some automated system and have it spit out, hey, this is ZOOspot, right? So that's what they did with their VX class. And then it would generate, someone else joined the company, and one of his PhD ideas, I think, were around generating the commonality between all these things in the byte pattern. So you have 100 samples, they all say I'm Zeus. Well, let's generate one pattern that matches for all 100 samples. So we could use this to search memory, and it was fine, but we got some false negatives. Well, by utilizing this, the image section objects and so forth, we no longer get the false negatives, so it's more useful to us. Also, how many people have ever used ClamAV? So the large number here, they've heard of it, they used it. Well, ClamAV also has this concept of a byte signature match for malware. So I think in the last time I downloaded ClamAV, they released 40 signatures that are what they classify as byte pattern. So I didn't look at what the database is and what those signatures represent, but there are 40 signatures in there that now we'll be able to use in memory analysis. So we're trying to use the tools that we already have, apply them in a triage scenario. So we have a few minutes left here. I'm just going to cover some demos quickly. I apologize, my laptop died right before I came to Black Hat, so I had a fast machine, now I have a really crappy one. So anyway, basically, I won't run the acquisitions on this hard drive because it would take about six minutes per sample. But this, if you have memorized, you can do this at home as soon as we release the new tool, the new version. Here we're going to run a process of acquisition, pull the binaries out of memory, and then we'll go look at what we got. So the first example was the registry hive. If I acquire the system process, I have a bunch of data here, along with the sizes. So we're pulling out individual files and we're giving them a name. It's encoded so that we can write it all to the local file. So you'll see the encoding of C colon slash, things like that. If we couldn't determine like it didn't have a name, it didn't have a control area associated with it, we'll just give you the range that we found it in and so forth. But if it did have a name, we'll write that out. There's some files we couldn't find any data. We could find a file object, we could find its name, but it just didn't have any data that we could carve out of memory. So those will be zero in size. But what I want to show you is loading this into a registry viewer because again, this is a system process. So we're going to load it up into registry viewer. And since this is coming from the cache, there may be some pages that are not there, right? But if we encounter one of those in the cache example, we'll just write a page basically of no-ups because we need to keep the linear order of things in the file so that it can be parsed by tools like this is access data's registry viewer. If you see here, you know, I can drill down into things and I can see when the key was created. So I can do all my traditional forensics on it. There's no guesswork, there's no carving hives out of memory and guessing where they are and stuff like that just works. Another thing I'll show you is here I'm going to... I've acquired basically the... So from the Honey Nut Challenge, the Honey Nut Challenge 3, there was a memory image that had... It was basically infection through the web. I think it was Zeus. And when I acquired the Firefox process, I was able to get the web cache information, the URL history information. So I load this up into one of our free tools called WebHistorian. And there wasn't much data here because they were just demonstrating an attack and seeing what you could find, this last entry here contains the exploit codes, pdf.php. So I can see the URL, I can see the access time, like when the user clicked to go there and stuff like that. Because it's all in the WebHistory log that Firefox is keeping and I just acquired Firefox out of memory so I can use my traditional tools. Also, I acquired the Microsoft Word process out of memory. And this was a memory image that Toma asked my wife if she would load up Word Document Center and then take an image of her laptop. It was around the windows of Vista. Here you see we were able to acquire the Word template and an actual Word document. So if we try to open that Word document, it's going to complain. The Word document is written in the Word 2010. This is Word, this is Microsoft Office 2007. It's going to complain about the content. It's a little corrupted, it's probably also dealing because we're coming from cache. We're just going to go ahead and say, okay, let's go say, do you really trust this? We're going to say yes. And here's the Word document for this presentation. So there's a 13-page white paper. And it is all there. So I'm not really sure if this has any applicability to IR and forensics which is my day job, but I thought it was kind of sexy cool, so what the hell? I guess for all you e-discovery types, you might like it. Then the last thing I'll show you before I go is this is the UI for our memory analysis tool that is also free. The UI is open source. It's called AuditViewer. We're going to be releasing a new version where you can say, filter out the known MD5s. So if it's going to do the MD5, compare that to a known set. Here if you had something like bit 9, you could whitelist, you could utilize their service, and this will just fire a bunch of crap at bit 9. I don't know if that's legal, but if you have a password and a user account, I'm sure they'll probably let you do it. So we're going to say cancel because we don't have a bit 9 account for today's demonstration. It's still running. Okay, finished. You could also use the NSLR from NIST and stuff to do your known whitelist. And then we're going to say filter on trust. And there we've reduced, oh, by the way, this is every single process on the system because I double-clicked the root node here. So this is every process. These are the things I have to care about now as an incident responder triaging this host. So we went from 1,500 down to, I don't know, maybe 30 or something like that. So it's a big time saver. And that's about the end of my time. There are a few caveats where places we need to continue the work, basically dealing with the tool will be available in the coming weeks. You can check the blog. These slides will be on the web. The white paper will be on the black-out site. But dealing with ASLR because it changes the address space a little bit when programs load. But we have all the data we need to actually reverse that trend. So we can fix it up and just run the fixed-up data through our hash and get the same hash values. Also, there's something called the security directory. That's on some files. It's the certificate info. And that won't be present. There are no artifacts representing that on Windows 7 and Windows 2008. Previous versions, there were only artifacts. So again, we have the PE header in memory. So we can detect that that exists. We can go to the disk. We can run it through our hash. And MIMD5 will work again. So that's really the end. I'll be available at the Q&A room after this. Thank you. Thank you.
 Welcome, this is physical memory forensics for files and cache.  I'm Justin Murdoch and to my right is Jamie Butler.  Just a bit of background information.  Jamie Butler is the director of research and development at Mandiant.  He focuses mainly on host analysis and operating systems research.  I'm a computer science major at the Rochester Institute of Technology,  but I'm currently on co-op at Mandiant working on their enterprise product as a software developer.  So we're going to speak today about physical memory forensics and this is kind of a layout of the talk.  First we're going to go over traditional forensic methods, kind of a background information,  and then specifically move on to memory forensics.  And given that background, we're going to speak about the issues that are in existing tools right now.  So a lot of them are missing important information and often misattributing data to executables.  So most memory forensics also deals with utilizing files.  So we're going to speak about memory mapped files, reconstituting binaries and data files,  and specifically the role that cache plays in this process.  Then we're going to talk about possible applications of our new techniques  and show you guys a couple of demos and then we're going to speak about our new tool  that we're going to be releasing pretty soon that uses these new techniques  and speak about, wrap up with just some further work that needs to be done in the area.  So traditional forensics is kind of a broad overview.  A host has two large sources of information for forensics, so the disk and memory.  And lately memory has become a great way to triage a host, say in a forensics investigation.  So the reasons for this are the average size of disk is growing extremely high.  So most hard drives out there come at least 250 gigabytes.  I know people in this room probably have way more storage space than that.  So searching through that whole image or just dumping a full copy of the hard drive  is getting to be a much longer process.  And memory can really help you out to speed up what you're looking for.  It's relatively small comparatively, so you can scan the whole space pretty quickly.  Also, for intruders to get their code running on a system, they have to load it into memory.  And in almost all cases out there, they aren't covering their tracks.  They aren't cloaking their memory footprint,  because that's really just too much work in the most case.  So also many of the artifacts that the kernel needs to load the program into memory  we can use to gain a lot more information about the executable.  So specifically for memory forensics, memory is divided really into two basic sections,  userland and kernel memory.  This talk is going to focus on userland memory, again, because in most attacks,  most intrusions, they're focusing on userland memory.  It's easier to get execution and it's more resilient to coding errors.  Basically, if you're developing this attack, then if you got a couple bugs in your program,  all of a sudden you have to crash the system because it's running in the kernel.  So it becomes very costly to develop these kind of attacks.  So memory forensics traditionally focuses on recovering all the binaries out of the memory.  So all the executables, DLLs, this is one of the main focuses of any investigation.  And most of these tools rely on virtual address descriptors or VADs.  These describe the processes address based in memory.  And they make up, they're made up of these objects.  So as you can see, it's got a pointer to left and right child.  It's usually in a tree structure.  And each VAD also contains the starting address and the size of the memory,  along with a pointer to the control area.  So here's a representation of a typical VAD tree.  You can see it starts with a VAD root and just each one of those VADs contains information  about the virtual addresses of the process.  So traditionally, you would scan physical memory for an E process block.  And that kind of lets you know that there's a process at that location.  From there, you get the directory table base or DTB in the E process.  And this will help you translate from virtual to physical addresses.  From there, you locate the root of the VAD tree and just kind of step through the tree,  translating the virtual addresses to physical, and usually start with the starting address,  take the size, and just grab all the data in between there.  Some other tools also utilize information about the PE headers to reconstruct the executable  with their knowledge about the different sections inside.  An alternate approach is to just use the DTB to try and translate,  basically brute force the whole address space.  And it kind of just starts at a beginning address and goes all the way through to the end.  And this has its limitations, really.  On a 32-bit system, this pretty much works because you got an upper bound of about like  four gigabytes.  But on 64-bit, the size can just be enormous.  This also leads to some misattribution of the data because the virtual addresses could  translate globally, not particularly for that process.  And this kind of leads us to problems that are in existing tools right now being used.  So with that, I'm going to hand it off to Jamie Bowling.  So as Justin mentioned, the traditional approach in the current memory forensic tools is to  really take a virtual address, its base and the size.  Even if that virtual start is zero and size is four gig, you're going to brute force across  the whole thing and you're going to do the translation in the context of the process that  you're trying to analyze.  So every process as the previous slide showed has a directory table base and that is used for  the virtual to physical translation and that should tell you what's in the process context.  Well, what we found in our research is that there's a lot of data that's actually missing if you do this.  For instance, the first thing that we encountered is when we're trying to reconstruct a process,  obviously like the attackers usually injecting code, you know, in the form of an injected  DLL or whatever into the process address base, so in order to analyze that and to detect it,  we need to be able to translate the code for that DLL.  Well, the operating system, the Windows loader is going to load the DLL as a memory map file.  So memory map files are stored in a special way because basically the OS doesn't want to waste space.  And what do we mean by that?  Well, on a Windows host, you have, let's say, a user mode process or every user mode process,  most likely has the DLL, NTDLL.DLL mapped into its address space.  So if the OS did not use memory map files or the shared files across the address bases of all processes,  then that DLL would have to be replicated for every single process that loads.  So obviously that would waste a lot of physical memory and this design was thought up, you know,  back in the probably Windows 16 bit versions when there wasn't a lot of memory to waste in the first place.  Plus it's also just more efficient in today's world, you know, we're a greener, so let's not waste memory.  So these memory map files are shared across all processes even if they're only used once, right?  So because of this, they may not, they may be in your process address space,  but the address that they represent may not translate in your page table entries.  So I won't go into the depths of how you do virtual to physical translation.  If you want to learn more about that, there's slides on the internet and so forth, you can Google those.  But basically the page table entry is the very last table structure you'll find when doing a virtual to physical address translation.  When you go to read it to find out where the physical page is, lo and behold, it's all zeros.  So that doesn't tell you anything. That means typically we just had to ignore that region because we couldn't get access to it.  And here's an example of taking the Honeynap project challenge 3.  If you're familiar with that, that was a memory image.  It came out about a year and a half ago. It translated or I acquired these files out of the memory image.  And there I just chose file at random. And you see the file size there in the first column.  And then the bytes acquired with the traditional approach.  So that's using the VADs. That's a starting virtual address, ending virtual address,  and using the DTB of the process to acquire it. And that's how much of the file that we could acquire.  And then I used a different technique that we'll cover in the last half of this presentation,  which was using what's called file objects, which represent the memory map files.  So for instance, with the ace.dll, we got 70% of it using the traditional method,  but we were able to increase that to 93% using this more accurate method of the file objects.  Also, we'll talk about in a moment what you can do, how this number may go up to actually 100%  if you're running on a live system and non-memory image because you have access to the disk.  The second problem that we ran into is basically when you're doing...  We come from a background where we build products and tools to do incident response.  So in that context and even in probably some of your more traditional forensic investigations,  trying to determine exactly which process is infected is important.  So knowing the whole host is infected is perhaps interesting,  but then the next question you're also going to ask you is, well, which process is...  Or how do you know what artifacts within that host are infected?  Because they may lead to things like user accounts have been compromised.  Also, processes have a creation time to tell you perhaps around the time of the infection  if they were creating new processes and so forth.  So attribution is important to us.  One of the issues with the traditional approaches, especially with the brute forcing method,  is if you brute force over the global address space, as Justin alluded to,  there's areas of the address space that are global for every process.  So basically when you cross from virtual address in user land  and you go into virtual addresses there in kernel land,  most kernel addresses will translate appropriately in every context address space.  And the reason this works and everything, you can read Marcus Onovich's Windows internal books  and take those to bed at night and it'll keep you warm.  But basically if you do that over a couple of years, you'll figure out that the kernel addresses  appear global because Microsoft wanted to save entries within the cache.  Within the actual cache that's on the chip, you know, like your L2 cache,  they wanted to save cache lines so they have these global addresses  and save time on speed transfer context switching so they didn't have to flush the cache every time  and so on and so forth, so kernel addresses basically are global.  Here is a graphic that someone else stole from the Windows internal books  that we stole from the person off the internet because I don't like to draw.  So this is a virtual representation of a 32-bit system.  And basically all I want to show here is you'll see there at C100, 0000,  is the beginning of system cache.  So that is a cache that the operating system is keeping  that's different from your L1, L2 cache that the CPU is keeping.  This cache is going to be used for things like file I.O.  So if you request to read a page of a file, the operating system is going to assume  that you're probably actually going to want to read more than one page,  so it's going to read ahead.  And that read ahead is going to cache for you and it's assuming locality of reference,  all your future reads statistically should be relatively close  to where you're currently reading in typical programs.  So those go into the cache of that virtual address.  Well, if we acquire memory or acquire a process  and we're brute forcing basically anything in the cache  will appear to be in every single process.  So that's really bad for attribution.  So let's talk about ways to make this process better.  So we're going to utilize file objects.  And file objects can represent a number of different things.  They can be, for instance, memory map files that we kind of touched on,  which would include DLLs and EXEs.  They also include data files, which may not be mapped into memory  but are in the cache in different places,  like a word or PDF or registry hive, web history.  We've seen restore points, Windows XP, those nice restore points  so we can actually see after the attack are attacked  we can see what was happening on the system,  what they installed because of the restore points.  So the vads are still interesting to us  but we're going to utilize a little bit more data that they make available.  So vads describe a range of memory that the file occupies.  And if it's a memory map file  or if it's a file object represents that region of memory  then the VAD will have what's called a control area.  And if you're very familiar with Windybug  you'll be used to these structures that we're talking about.  Control area would have a pointer back to the file object.  So we're finding vads in memory because we found the E-process block.  Once we find the VAD we're trying to parse it to see its control area.  Once we get to the control area we're parsing it to find its file object.  Now file objects contain some useful data  including the device name  that would be things like hard disk volume 1 as you see in this example.  You can then translate that for the OS in question for your host  that's probably C colon or whatnot.  Also it will contain the file name itself  and then the next thing that we're going to talk about today  is this table of three pointers  depending on where the file data is actually backed up.  So the three things we're going to look at are image section objects,  data section objects and shared cache map.  Here's a graphical representation of a file object.  It contains a pointer called section object pointers  and section object pointers only has three members  and Windy Bug will tell you all this  or Rosonovich might as well.  So image section objects represent,  are very interesting to us in forensics and IR  because they represent binaries that are loaded in memory.  So if binaries load up the windows loaders  go to create a section object for that binary.  But this pointer, this image section object thing  is not actually a pointer to the structure called image section object  that doesn't exist, it's actually a pointer to a control area.  So yet another control area.  That control area will have a pointer to what's called a segment object.  This segment object can be used for sanity checking  like if you were just scanning through memory  you may find some artifacts that are no longer in use  that aren't actually usable.  If you try to parse them in certain code you probably crash.  So we'll use this for sanity checking.  That segment object will contain a segment size  and the total number of PTs represented by that segment.  So we'll talk about PTs in a moment.  But basically for sanity checking you can compare  the segment size equal, should be equal to the total number of PTs  times the page size.  Page size in Windows for the most part you can just  there is a small alteration on page size  but for the most part you can assume that that's 4K  or 1000 hex.  The thing that you're going to want to be parsing  if you're trying to dig out the binary data from memory  would be the subsections.  So subsections represent the individual pieces of a file.  How many here has ever loaded up like a, looked at a PE  a portable executable in PE view or Lord PE  or some other viewer.  Basically what you'll see in there is that the PE file  is broken into a bunch of sections.  So there's like a code section that's usually called.txt.  There's a data section, there's a resource section.  There's different things like that, relocation section.  Well all these sections have a relative virtual offset  relative virtual address within the PE  and then they also have permissions.  So once this thing loads into memory  what should the permissions on that section be?  Well since each section within the PE file  probably has different permissions  then there has to be a subsection object  that represents every single section within the PE.  We couldn't find a pointer that would show us  where the subsection object was.  So if you just stare at the hex for long enough  the math starts to come out at you.  Basically the subsections all seem to line up  at the very end of the control area that we just found.  So although the segment object was way away in virtual memory  the subsection object was immediately following the control area.  So that was nice for us.  Basically for every version of the OS  you can just determine how large the control area is  add that to where the base of control area was  and then cast that as a subsection object.  So the subsections will contain an array of prototype PTEs.  This is the crux of the data that we have to parse  in order to get the binary out of memory.  So the prototype PTEs contain the physical address  of each memory page in physical memory.  So we'll have a graphic in a moment.  It may be a little bit more useful for you, but I'm not sure.  Basically though, if the prototype PTE contains  the virtual address of that subsection object that it's within  then that means all bets are off.  Basically this page of memory is on disk.  And when I say on disk, I don't mean probably you've heard  arguments back and forth about, hey, can you acquire the page  file and use that for memory forensics and stuff too.  I personally believe you can't.  You can only use the page file at runtime.  But even if you were to be able to use offline page files  and marry those up with offline memory images,  even if that were possible, you won't be able to access  the data that's represented here because memory map files  mean exactly that.  They're memory mapped.  So if they're page to disk, they don't go to the page file.  They are represented by themselves on disk.  So if you want to get that data, you have to go to the  location of NTDLL.DLL on disk for sector 15 or what you  need or what not and read the data.  So the page file is not useful in this case.  Also something else that's within this subsection object  will be the number of full sectors and the number of  prototype PTs for the subsection.  So again, going back to disk, when we're looking at the  on disk, the disk sectors are 512 bytes.  And the page alignment in the Windows OS is 4K.  So there's a little bit of a fix up that you have to do.  So you have to take into account the total number of PTs  that this subsection represents, but also the total number  of sectors, full sectors that it represents.  And it contains these numbers in the structure.  So you use that in order to parse it correctly.  Because if you were just reading PTs blindly, you would  get more data than is actually within that subsection.  And the file in memory wouldn't line up like it does on disk.  So we're going to use those full sectors to our advantage.  And basically by keeping track of where we are when we walk  these sectors in memory, you know, 512 bytes at a time,  we will know the offset that we need to read if the file  is page to disk.  So using that, we can get all the data if we're running on  a live system.  Another thing of interest is there may be, there's  probably definitely more than one subsection, especially if  it's PE file.  So there will be a pointer to the next subsection.  And you basically just chase the chain, right?  So this is just a nice graphic of what that looks like  in memory with our array for each subsection.  Now data section objects, they represent data files in memory.  I'm not sure what types of files load themselves as a data  section object.  I know that PDFs don't, but Word documents do.  So if you're loading up Microsoft Office documents,  they're going to look like in memory the data section object.  That structure actually is exactly like an image section  object besides a few sandy checks that don't work in this  case.  But basically since they're the same, you know, data section  objects and image section objects, they point to the same  structures, we can surmise that the data access for a Word  document would be just as fast as the access, as any data  access or code access in this case, for an image section  object.  So Word documents are going to perform as well as EXEs,  right?  Because the structures are the same.  It's a shortcut of where to get the data.  It's not relying upon the cache, which is somewhat  subjective.  The OS defines how to load the cache and when and when to flush  it based upon utilization on the system and the number of  resources available.  Well, if you have a data section object, that's not the case.  All your structures are right there.  You have quick immediate access to the data.  So I thought that was kind of cool.  Maybe Adobe should change how they load their files.  So we've covered image section objects and we've covered  data section objects.  The last thing we'll touch on here is the shared cache map.  So the shared cache map is used to represent the file data in  the cache.  So if all other bets are off, you know, if you don't have an  image section object, you don't have a data section object,  then you should go parse the cache structures in order to get  as much data as is available.  Now, again, that may be nothing or it may be more or less the  whole file.  It really all depends.  So in the shared cache map structure, this structure is  actually defined by Microsoft and in Windybug.  It contains the file size, the amount of valid data within the  file, within the cache.  The valid data should never be larger than the file size  because if that happens, then you're actually looking at  uninitialized data.  Also, it contains an array of pointers to VACBs.  So VACBs are virtual address control blocks.  This is the structures that define where the data is in  virtual memory in the cache.  So if the file is one megabyte or less, then Microsoft  decided to put in some performance improvements by  embedding an array of four VACBs right into the shared cache  map itself.  So no reason to chase anything.  They've just embedded it right there, which works really  nice for them because often the things in the cache are less  than a meg.  You'll probably go have a lot of web images and so forth that  are in the cache.  There will be less than a meg in size, so let's keep it simple.  Each VACB, I should mention, represents 256 kilobytes.  So if you have four of those, obviously you can represent a  one meg file.  If it's larger than a meg, though, we have to go to an  array of pointers.  So what that looks like is it's a nested structure.  If it's one level deep, basically there's one array that  points to the VACBs themselves.  It can represent 32 megabytes if it's one level deep.  I think, I forget the number, I believe each array has 128  entries.  So if you read Marcus Hanovich's and David Solomon's book on  Windows Internals Chapter 13, I believe, in the newest version  is all about the cache.  And they'll tell you how to calculate the depth of this  tree.  So arrays of arrays of arrays of arrays, it gets really fun.  I recommend recursion.  But anyway, the largest file that you can have on Windows OS  is 2 to the 63rd power.  So that's the largest you can have, and because of the  number of entries in each array and so on and so forth, and  the number of blocks that they can represent, your tree can  be no deeper than seven levels deep.  Here's what the shared cache map would look like, kind of  conceptually.  This, obviously, at the bottom is just two levels deep.  And if we parse this, we'll get all the file data that is  present in the cache.  So let's talk about some of the applications in this  technology.  Well, in the past, most of the tools, I believe all the tools  that are out there freely available, will parse the VAD  tree in order to do process reconstitution.  But probably since we care about some data that's in the file  system or in the file cache, we should probably also parse the  handle table.  So we'll go parse the handle table, we'll go parse the VAD  tree, and then once we get there, we'll go parse the file  objects that we find.  Now, the Windows registry hives are a nice example of how  you can use this.  If you would analyze the system process, basically it has a  handle to every registry hive that's in memory so you can  get all the data there.  So let's say you're going to acquire this to your local  hard drive or to your system analyst station so that you can  do parsing with your traditional registry forensic tools,  you would want to acquire the system process out of memory.  Once you have that, it'll literally write the individual  file names to the local hard drive with the content of those  files.  Also PDFs, as I mentioned, are found in the cache.  We haven't had a ton of time to research all the things we can  get out of the cache.  If you're on a Windows XP system, you can get the restore  points because it has a handle to a file that is basically  keeping the data for the restore points.  So you can get that out of memory in some cases.  But as the caveat for the cache is, it's all bets are off.  It's hit or miss or other would be useful.  The way we're going to use this most likely and some of the free  tools that we're releasing are to do data reduction.  So we have a hashing.  We beat up on the AV industry all the time about hashing and how  it sucks.  That's nice.  I've done it myself.  However, hashing can also be useful.  I mean, we have over two decades of data, so let's start to use it  to our advantage to make the problem simpler.  Memory forensics is all about data reduction.  So we went from a 250 gigabyte hard drive.  Now we're down to a 4 gigabyte memory image, probably.  Now in that memory image we're going to find roughly on the  Vista or the Windows 7 machine, I looked at, we're going to  find about over 4,000 files in memory, right?  If you don't take into account eliminating duplicates.  So everything's going to have a handle or a VAD to NTDLL.  Everything's going to have a VAD to kernel32.dll and so on and so forth.  So now we went from 250 gigabyte that we care about, maybe at  first, down to 4,000 files.  And then we do a data reduction to get rid of redundancy, and now  we're down to about 1,500 files.  Well, now the problem is starting to get a little bit more manageable  in finite time.  So if we could use white listing and hashing to eliminate the  other components of the operating system that we don't care about,  that number would get a lot more manageable.  So there's been some efforts in the past, not my research, but others,  who've done fuzzy hashing and different things like that,  in order to try to make the hash that's found in memory match the hash on disk.  The problem with these fuzzy hashing techniques is we don't have the data  going back years, because they just take subsections of files.  And most white listing technologies and so forth use the full hash of the file.  So the comparison is difficult to make, and it may have benefitted  in your organization, like if you had a white list, I mean a gold master  that you were deploying across the enterprise.  You may be able to use data reduction with fuzzy hashing.  However, we found that most people don't have this,  and so we went to the section image object, and we parsed it like on a law  of system, which means we can get access to the file system as well  if there's a page that's not there in memory.  And by utilizing this data, we can make the hash that we find in memory  match the hash that's on disk.  So we call this memd5.  It's a cute name of our other coworkers came up with.  That will be released in the free tool that I'll talk about in a moment.  Another application for this better process reconstitution  or binary acquisition, what have you, is that there's a lot of tools  out there that are starting to use, you know, like byte patterns of malware  and things like that.  There was a tool developed by Xonamix, which was acquired by Google, unfortunately,  and they killed the project or took it internally.  They came by it anymore, but it was called VX class, and it was kind of cool.  I liked it enough that I convinced my company to buy it.  But VX class would generate byte pattern signatures for classes of malware,  so families of malware.  So what the VX class leveraged was that if you had a malware sample  or a lot of malware samples, they were reusing code.  And if you were doing IR, you probably didn't want to focus, you know, all your...  You have a limited amount of resources, so you probably don't have a large malware team,  what not, you don't want to focus all your efforts looking at the last 50 variations of ZOOspot.  You just want to throw it into some automated system and have it spit out,  hey, this is ZOOspot, right?  So that's what they did with their VX class.  And then it would generate, someone else joined the company, and one of his PhD ideas, I think,  were around generating the commonality between all these things in the byte pattern.  So you have 100 samples, they all say I'm Zeus.  Well, let's generate one pattern that matches for all 100 samples.  So we could use this to search memory, and it was fine, but we got some false negatives.  Well, by utilizing this, the image section objects and so forth,  we no longer get the false negatives, so it's more useful to us.  Also, how many people have ever used ClamAV?  So the large number here, they've heard of it, they used it.  Well, ClamAV also has this concept of a byte signature match for malware.  So I think in the last time I downloaded ClamAV,  they released 40 signatures that are what they classify as byte pattern.  So I didn't look at what the database is and what those signatures represent,  but there are 40 signatures in there that now we'll be able to use in memory analysis.  So we're trying to use the tools that we already have, apply them in a triage scenario.  So we have a few minutes left here.  I'm just going to cover some demos quickly.  I apologize, my laptop died right before I came to Black Hat,  so I had a fast machine, now I have a really crappy one.  So anyway, basically, I won't run the acquisitions on this hard drive  because it would take about six minutes per sample.  But this, if you have memorized, you can do this at home  as soon as we release the new tool, the new version.  Here we're going to run a process of acquisition, pull the binaries out of memory,  and then we'll go look at what we got.  So the first example was the registry hive.  If I acquire the system process, I have a bunch of data here,  along with the sizes.  So we're pulling out individual files and we're giving them a name.  It's encoded so that we can write it all to the local file.  So you'll see the encoding of C colon slash, things like that.  If we couldn't determine like it didn't have a name,  it didn't have a control area associated with it,  we'll just give you the range that we found it in and so forth.  But if it did have a name, we'll write that out.  There's some files we couldn't find any data.  We could find a file object, we could find its name,  but it just didn't have any data that we could carve out of memory.  So those will be zero in size.  But what I want to show you is loading this into a registry viewer  because again, this is a system process.  So we're going to load it up into registry viewer.  And since this is coming from the cache,  there may be some pages that are not there, right?  But if we encounter one of those in the cache example,  we'll just write a page basically of no-ups  because we need to keep the linear order of things in the file  so that it can be parsed by tools like this is access data's registry viewer.  If you see here, you know, I can drill down into things  and I can see when the key was created.  So I can do all my traditional forensics on it.  There's no guesswork, there's no carving hives out of memory  and guessing where they are and stuff like that just works.  Another thing I'll show you is here I'm going to...  I've acquired basically the...  So from the Honey Nut Challenge, the Honey Nut Challenge 3,  there was a memory image that had...  It was basically infection through the web.  I think it was Zeus.  And when I acquired the Firefox process,  I was able to get the web cache information, the URL history information.  So I load this up into one of our free tools called WebHistorian.  And there wasn't much data here because they were just demonstrating an attack  and seeing what you could find,  this last entry here contains the exploit codes, pdf.php.  So I can see the URL, I can see the access time,  like when the user clicked to go there and stuff like that.  Because it's all in the WebHistory log that Firefox is keeping  and I just acquired Firefox out of memory so I can use my traditional tools.  Also, I acquired the Microsoft Word process out of memory.  And this was a memory image that Toma asked my wife if she would load up  Word Document Center and then take an image of her laptop.  It was around the windows of Vista.  Here you see we were able to acquire the Word template  and an actual Word document.  So if we try to open that Word document,  it's going to complain.  The Word document is written in the Word 2010.  This is Word, this is Microsoft Office 2007.  It's going to complain about the content.  It's a little corrupted, it's probably also dealing  because we're coming from cache.  We're just going to go ahead and say, okay,  let's go say, do you really trust this?  We're going to say yes.  And here's the Word document for this presentation.  So there's a 13-page white paper.  And it is all there.  So I'm not really sure if this has any applicability to IR  and forensics which is my day job,  but I thought it was kind of sexy cool, so what the hell?  I guess for all you e-discovery types, you might like it.  Then the last thing I'll show you before I go  is this is the UI for our memory analysis tool  that is also free.  The UI is open source.  It's called AuditViewer.  We're going to be releasing a new version where you can say,  filter out the known MD5s.  So if it's going to do the MD5, compare that to a known set.  Here if you had something like bit 9, you could whitelist,  you could utilize their service,  and this will just fire a bunch of crap at bit 9.  I don't know if that's legal, but if you have a password  and a user account, I'm sure they'll probably let you do it.  So we're going to say cancel because we don't have a bit 9 account  for today's demonstration.  It's still running.  Okay, finished.  You could also use the NSLR from NIST and stuff  to do your known whitelist.  And then we're going to say filter on trust.  And there we've reduced, oh, by the way,  this is every single process on the system  because I double-clicked the root node here.  So this is every process.  These are the things I have to care about now  as an incident responder triaging this host.  So we went from 1,500 down to, I don't know,  maybe 30 or something like that.  So it's a big time saver.  And that's about the end of my time.  There are a few caveats where places we need to continue the work,  basically dealing with the tool will be available  in the coming weeks.  You can check the blog.  These slides will be on the web.  The white paper will be on the black-out site.  But dealing with ASLR because it changes the address space  a little bit when programs load.  But we have all the data we need to actually reverse  that trend.  So we can fix it up and just run the fixed-up data  through our hash and get the same hash values.  Also, there's something called the security directory.  That's on some files.  It's the certificate info.  And that won't be present.  There are no artifacts representing that on Windows 7  and Windows 2008.  Previous versions, there were only artifacts.  So again, we have the PE header in memory.  So we can detect that that exists.  We can go to the disk.  We can run it through our hash.  And MIMD5 will work again.  So that's really the end.  I'll be available at the Q&A room after this.  Thank you.  Thank you.
DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_0_251.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_252_959.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_960_3119.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_3120_8183.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_8616_11855.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_11856_18767.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_18768_22223.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_24648_28331.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_28332_28811.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_28812_39923.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_40284_42815.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_42816_48215.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_48792_56927.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_56928_61055.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_61056_61115.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_72828_72875.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_72876_73103.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_73104_74387.png DEF_CON_19_-_Jamie_Butler_-_Physical_Memory_Forensics_for_Cache_xAB-tRAaqeI_1_74388_74573.png