Tuesday, September 4, 2007

Administrativa

As I've mentioned to a few people, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 past two posts have been cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start of what I hope will become a trend: posting at least one piece of new, technically interesting content per week. With any luck, new posts will come out on Mondays (I cheated a bit this week and took Labor Day off).

Topics covered will center around memory analysis, as this is my primary area of research, but I have a few posts planned on topics like network-based exploitation and cryptography.

I hope any readers of this blog will enjoy cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sudden influx of new content; don't hesitate to contact me with comments, criticisms, or ideas for new posts.

Challenges in Carving Registry Hives from Memory

As I mentioned last week, I moved to a new apartment this week, and as a result I didn't have a lot of time to do any serious work. Still, I didn't want to let cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire week go to waste, so I decided to try and tackle a problem that I thought would be relatively simple: extracting a copy of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 binary registry hives out of memory. As it turned out, this was actually a bit more difficult than I expected, and I'll have to get back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 problem at a later date, but I thought in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 meantime I'd write about what steps I took, where I ran into trouble, and describe cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 approach I hope to take when I revisit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue.

There were several reasons to suspect that one might find at least partial copies of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry in memory: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry stores all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration data for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows operating system, and its contents are referred to and updated quite often during normal operation (let Sysinternals' Regmon run for few minutes and look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output if you have doubts about this). In addition, it seemed to me that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 binary structure of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry hives was in many ways well-suited to an in-memory representation: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of a block in a registry file, 0x1000 bytes (4096 bytes, or 4KB) is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of a page in memory, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 various data structures present in registry hives have a clear interpretation as C structures in memory.

Indeed, it appears that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire registry is stored in memory, at least in Windows 2000. Quoting Russinovich and Solomon's excellent Windows Internals:

Windows 2000 keeps a version of every hive in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's address space. When a hive initializes, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration manager determines cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive file, allocates enough memory from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's paged pool to store it, and reads cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive file into memory. [...]

In Windows XP and Windows Server 2003, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration manager maps portions of a hive into memory as it needs to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. It uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache manager's file mapping functions to map in 16-KB views into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive files.

Windows Internals, p. 203

For simplicity's sake, I'm not going to deal with XP and Server 2003 in this entry; it seems unlikely that very much of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry will be recoverable under those OSes, given cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapping mechanism described above. Instead, we'll look at recovering registry hives from Windows 2000, specifically cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two memory images released for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DFRWS 2005 Memory Analysis Challenge.

As mentioned earlier, registry hives are divided into fixed blocks of size 0x1000 bytes; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se blocks is called cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base block, and it begins with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 signature "regf". The base block also contains four dwords giving cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 version of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive structure in use (at offsets 0x14, 0x18, 0x1C, and 0x20), and in Windows 2000 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se values are always 1, 3, 0, and 1. These two facts togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r make for an excellent signature to search for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start of a hive in a Windows 2000 memory dump. Using XMagic:

# XMagic

# Windows Registry files.
# updated by Joerg Jenderek
0 string = regf Windows 2000 registry file
# Reg version
<0x14 lelong = 1
<<0x18 lelong = 3
<<<0x1c lelong = 0
<<<<0x20 lelong = 1
Using this signature in conjunction with FTimes finds four hive headers in dfrws2005-physical-memory1.dmp, and ten in dfrws2005-physical-memory2.dmp. Going to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offests given in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory dump and examining cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 results, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re do not appear to be any false positives. The fact that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are so many more results from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second memory dump is likely due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hives reside in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's paged pool; this means that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y can be swapped out to disk. Since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second image was taken right after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system was booted (according to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 challenge details), it seems likely that some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive headers in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first image were paged out.

My first, naive attempt to carve out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files was to simply calculate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of each hive and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n use dd to carve out that much data from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offset given by FTimes. The size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive can be easily calculated by looking at offset 0x28 in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive header; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dword at this position gives cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offset of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last block in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry hive. Since each block in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive is 0x1000 bytes, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive as a whole should be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offset of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last block plus 0x1000. This method of extracting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry fails, however – although it is reasonable to expect that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry is contiguous in memory, this assumption would only hold for virtual memory, and our carving method is trying to extract a contiguous range from physical memory.

Clearly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, what's needed is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive in memory. To obtain this, I decided to generate a map of each process's address space, showing each virtual address and its corresponding physical address (if any). A good tool to do this is Andreas Schuster's memdump.pl; I wrote my own version of this in Python, drawing on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address translation routines from x86.py in Volatility (you'll need to copy in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "forensics" directory from Volatility into wherever you save memdump.py in order for it to work). Both memdump.pl and memdump.py take a memory dump and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of a page directory and generate a list of all offsets by trying to translate each possible virtual address from 0x00000000 up to 0xFFFFFFFF using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given page directory. (Note: PTFinder or my own XMagic signatures can be used to locate processes and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir page directories in a memory dump.)

Once such a map has been generated, we find that physical offset 0x01614000 (which appeared to contain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SYSTEM hive) is mapped in at 0xE1012000 in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual address space of every process (addresses above 0x80000000 are generally reserved for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel and are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same for every process). I wrote a small program to extract a range of virtual memory from an image, given a page directory, a start address, and a length. (Note: this time I've used my own memutil.py to do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address translations; it was easier to modify to continue despite invalid pages and to give verbose debug output.) After invoking it like so:

./regdump.py dfrws2005-physical-memory1.dmp \
0x00030000 0xE1012000 0x28A000 > test.sys
we get something that we might hope is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 complete SYSTEM hive for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DFRWS 2005 test system (modulo any memory pages that were swapped out).

Alas, we are not so lucky. Trying to validate this structure by using a small C program I had around that attempts to walk cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tree of registry keys and print cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir names caused it to die after reading only a small portion of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file. An bit of manual examination of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file we have shows why: it appears that for some reason parts of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file are no longer in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct position. We can tell this because registry hives store cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir data in bins, and each bin has a header with a signature ("hbin"), its offset from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first hbin block (i.e., its position in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file), and its size. We immediately notice that at offset 0x4000, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a block that claims its offset is 0, meaning it should be found at file position 0x1000.

Putting aside for now cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 question of why cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hbin blocks are not in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 order we expected, could we perhaps get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file to validate by taking each block and placing it in its correct position? To do this, we scan cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file on block boundaries for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "hbin" header, read in its offset, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n write it out at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct position. The program reorder_hbins.py does just this: it takes a list of hbin offsets on standard input (such a list can be trivially generated with FTimes in dig mode) and a file containing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry data, and writes out a new version with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hbins in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir "correct" places.

With this modification, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry hive comes closer to being parsable – regview.c gives cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following output:

$$$PROTO.HIV
ControlSet001
Control
Arbiters
AllocationOrder
ReservedResources
BackupRestore
FilesNotToBackup
KeysNotToRestore
Biosinfo
BootVerificationProgram
Class
{018713C0-14ED-11D2-88FC-0000F49094C7}
Fatal: encountered unknown subkey type at 00277dc0
However, at this point, if we look at offset 0x00277dc0, we find that it is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 middle of a page of zeroes. It seems that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was no hbin that claimed to be at that position in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original section of memory we carved out.

There could be several reasons for this. First, it is possible that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hbin we're looking for is simply paged out; if this is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case, no amount of searching through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory image will give us cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 block we need. To fully recover cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry we would need cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pagefile from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system, and since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 challenge is now two years old, we are unlikely to get a copy of it. Still, we could take cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following approach to try and at least partially reconstruct cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tree: now that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hbin blocks appear to be in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct positions, we can scan through to find individual nodes (so-called nk cells), and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n reconstruct subtrees from each of those until we run into trouble again. This might at least allow us to reconstruct interesting information such as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BootKey used in SYSKEY mechanism, which we could cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n use to decrypt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 local password hashes for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SAM hive (for more details on how to extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 necessary information from SYSKEY, take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bkhive and samdump2 programs by Nicola Cuomo).

The ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r possible explanation for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 missing block can be found by again consulting Windows Internals – which also may help explain why some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 blocks were in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wrong position.

If hives never grew, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration manager could perform all its registry management on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 in-memory version of a hive as if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hive were a file. Given a cell index, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration manager could calculate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location in memory of a cell by adding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cell index, which is a hive file offset, to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 in-memory hive image. [...] Unfortunately, hives grow as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y take on new keys and values, which mans cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system must allocate paged pool memory to store cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new bins that contain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 added keys and values. Thus, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 paged pool that keeps cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry data in memory isn't necessarily contiguous. [emphasis mine]

Windows Internals, p. 204

So our earlier assumption may not be valid, especially if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re have been keys or values added (which is almost certainly cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case on a system that has been running for a while).

To deal with this, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration manager uses a scheme reminiscent of x86 virtual address translation, and has a translation table that maps each cell index (i.e. offset within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry hive) to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 appropriate location in memory.

Dealing with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se new complexities, however, is a bit too much for me, at least this week. The next steps down this path would involve locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data structures used by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration manager in memory, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parsing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to get an accurate picture of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registry in memory. If anyone wants to do some exploring on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir own, a good place to start would be to look at debug symbols starting with _CM, as well as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 !reg extension in WinDbg. Hopefully I'll be able to return to this topic in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 near future.

For next week, however, I'll be back to parsing PDB files; with some luck, I should have code to extract type information ready by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 beginnings of a full-fledged Python module to handle PDB files.