[Vol-users] 29c3 defeating windows memory forensics

Luka Milkovic milkovic.luka at gmail.com
Wed Jan 9 14:23:39 CST 2013


Matthieu,

hmm, this is a bit strange.

Here is an output from win32dd (community edition, version
1.3.1.20100417, downloaded from your website some minutes ago):

-- win32dd --
Acquisition finished at:  [2013-01-09 (YYYY-MM-DD) 20:07:49 (UTC)]
Time elapsed:             0:11 minutes:seconds (11 secs)

Created file size:          205520896 bytes (    196 Mb)

NtStatus (troubleshooting):   0x00000000
Total of written pages:         50061
Total of inacessible pages:         0
Total of accessible pages:      50061

----SHA-256: 81454EFC92D357C68CE778FC3D74C22C3C4192D6A3B6F048102D97A95DAD0BCE----

-- end_of_win32dd --

Checksum of dump returns: SHA256:
81454efc92d357c68ce778fc3d74c22c3c4192d6a3b6f048102d97a95dad0bce

So the checksums are the same.

When reverse engineering the driver (sorry), I see this:

...
.text:00011009                 push    eax             ; ByteOffset
.text:0001100A                 push    esi             ; Length
.text:0001100B                 push    [ebp+Mdl]       ; Buffer
.text:00011011                 lea     eax, [ebp+IoStatusBlock]
.text:00011017                 push    eax             ; IoStatusBlock
.text:00011018                 push    ebx             ; ApcContext
.text:00011019                 push    ebx             ; ApcRoutine
.text:0001101A                 push    ebx             ; Event
.text:0001101B                 push    [ebp+FileHandle] ; FileHandle
.text:00011021                 call    ds:ZwWriteFile  ;
ZwWriteFile(Handle, NULL, NULL, NULL, ioStatusBlock, Buffer, Length,
byteOffset, NULL) - write the file
.text:00011027                 mov     [ebp+retStatus], eax
.text:0001102D                 cmp     eax, 103h
.text:00011032                 jnz     short loc_1106C
.text:00011034                 push    ebx             ; Timeout
.text:00011035                 push    ebx             ; Alertable
.text:00011036                 push    [ebp+FileHandle] ; Handle
.text:0001103C                 call    ds:NtWaitForSingleObject
.text:00011042                 jmp     short loc_11066
.text:00011044 ;
---------------------------------------------------------------------------
.text:00011044
.text:00011044 loc_11044:                              ; CODE XREF:
sub_10D38+2C8j
.text:00011044                 cmp     [ebp+dwPort?], 1
.text:0001104B                 jnz     short loc_1106C
.text:0001104D                 lea     eax, [ebp+var_1FC]
.text:00011053                 push    eax             ; int
.text:00011054                 push    esi             ; Length
.text:00011055                 push    [ebp+Mdl]       ; Mdl
.text:0001105B                 push    [ebp+FileObject] ; FileObject
.text:00011061                 call    sub_16D8E
.text:00011066
.text:00011066 loc_11066:                              ; CODE XREF:
sub_10D38+30Aj
.text:00011066                 mov     [ebp+retStatus], eax
.text:0001106C
.text:0001106C loc_1106C:                              ; CODE XREF:
sub_10D38+2FAj
.text:0001106C                                         ; sub_10D38+313j
.text:0001106C                 cmp     [ebp+retStatus], ebx
.text:00011072                 jl      loc_11297
.text:00011078                 mov     eax, [ebp+dwHashAlgorithm]  ;
check whether hash algorithm is being used for checksumming
.text:0001107E                 dec     eax
.text:0001107F                 jz      short loc_110AE ; user specified SHA1
.text:00011081                 dec     eax
.text:00011082                 jz      short loc_1109C ; user specified MD5
.text:00011084                 dec     eax
.text:00011085                 jnz     short loc_110C1 ; no checksum
.text:00011087                 push    esi             ; size_t
.text:00011088                 push    [ebp+Mdl]       ; void *
.text:0001108E                 lea     eax, [ebp+var_D4]
.text:00011094                 push    eax             ; int
.text:00011095                 call    SHA256Sum ; do a SHA256
checksum over the buffer
.text:0001109A                 jmp     short loc_110C1
.text:0001109C ;
---------------------------------------------------------------------------
.text:0001109C
.text:0001109C loc_1109C:                              ; CODE XREF:
sub_10D38+34Aj
.text:0001109C                 push    esi
.text:0001109D                 push    [ebp+Mdl]
.text:000110A3                 lea     eax, [ebp+var_6C]
.text:000110A6                 push    eax
.text:000110A7                 call    MD5Sum ; do a MD5Sum over the buffer
.text:000110AC                 jmp     short loc_110C1
.text:000110AE ;
---------------------------------------------------------------------------
.text:000110AE
.text:000110AE loc_110AE:                              ; CODE XREF:
sub_10D38+347j
.text:000110AE                 push    esi             ; size_t
.text:000110AF                 push    [ebp+Mdl]       ; void *
.text:000110B5                 lea     eax, [ebp+var_1B0]
.text:000110BB                 push    eax             ; int
.text:000110BC                 call    SHA1Sum ; do a SHA1Sum

Some of the annotations could be wrong because this was done in a hurry:)
But it seems that the checksums are calculated after the write. This
pattern repeats itself (depending on the method used for storing the
dump - whether the dump is stored locally or transferred over the
network).
So, the file is not read before comparing the checksum, but the
checksum is performed buffer-by-buffer before writing it to disk.

Maybe things are different in professional version, but I don't have
access to it:(

Cheers,
Luka


More information about the Vol-users mailing list