Archive for June 10th, 2008

Data Hiding in Crash Dumps

Tuesday, June 10th, 2008

Suppose we want to send a complete memory dump to a vendor but want to remove certain sensitive details or perhaps the whole process or image from it. In this case we can use f WinDbg command (virtual addresses) or fp (physical addresses) to fill pages with zeroes. Let’s open a complete memory dump and erase environment variables for a process:

kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS fffffadfe7afd8e0
    SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 0014a000  ObjectTable: fffffa8000000c10  HandleCount: 730.
    Image: System

PROCESS fffffadfe6edc040
    SessionId: none  Cid: 0130    Peb: 7fffffdf000  ParentCid: 0004
    DirBase: 34142000  ObjectTable: fffffa80009056d0  HandleCount:  19.
    Image: smss.exe

[...]

PROCESS fffffadfe67905a0
    SessionId: 0  Cid: 085c    Peb: 7fffffd4000  ParentCid: 0acc
    DirBase: 232e2000  ObjectTable: fffffa8000917e10  HandleCount:  55.
    Image: SystemDump.exe

kd> .process /r /p fffffadfe7287610
Implicit process is now fffffadf`e7287610
Loading User Symbols

kd> !peb
PEB at 000007fffffd4000
[...]
    Environment:  0000000000010000

kd> dd 10000
00000000`00010000  004c0041 0055004c 00450053 00530052
00000000`00010010  00520050 0046004f 004c0049 003d0045
00000000`00010020  003a0043 0044005c 0063006f 006d0075
00000000`00010030  006e0065 00730074 00610020 0064006e
00000000`00010040  00530020 00740065 00690074 0067006e
00000000`00010050  005c0073 006c0041 0020006c 00730055
00000000`00010060  00720065 002e0073 00320057 0033004b
00000000`00010070  00410000 00500050 00410044 00410054

kd> f 10000 10000+1000 0
Filled 0x1000 bytes

kd> dd 10000
00000000`00010000  00000000 00000000 00000000 00000000
00000000`00010010  00000000 00000000 00000000 00000000
00000000`00010020  00000000 00000000 00000000 00000000
00000000`00010030  00000000 00000000 00000000 00000000
00000000`00010040  00000000 00000000 00000000 00000000
00000000`00010050  00000000 00000000 00000000 00000000
00000000`00010060  00000000 00000000 00000000 00000000
00000000`00010070  00000000 00000000 00000000 00000000

Now we can save the modified complete dump file:

kd> .dump /f c:\Dumps\SecuredDump.dmp

If we want to find and erase read-write pages, for example, we can use !vad WinDbg command to get the description of virtual address ranges:

kd> !process
PROCESS fffffadfe67905a0
    SessionId: 0  Cid: 085c    Peb: 7fffffd4000  ParentCid: 0acc
    DirBase: 232e2000  ObjectTable: fffffa8000917e10  HandleCount:  55.
    Image: SystemDump.exe
    VadRoot fffffadfe6f293e0 Vads 65 Clone 0 Private 388. Modified 84. Locked 0.
    DeviceMap fffffa80020777c0
    Token                             fffffa80008e5b50
    ElapsedTime                       00:00:06.265
    UserTime                          00:00:00.031
    KernelTime                        00:00:00.062
    QuotaPoolUsage[PagedPool]         113464
    QuotaPoolUsage[NonPagedPool]      5152
    Working Set Sizes (now,min,max)  (1429, 50, 345) (5716KB, 200KB, 1380KB)
    PeakWorkingSetSize                1429
    VirtualSize                       61 Mb
    PeakVirtualSize                   63 Mb
    PageFaultCount                    1555
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      471

kd> !vad fffffadfe6f293e0
VAD             level      start      end    commit
fffffadfe682bdf0 ( 6)         10       10         1 Private      READWRITE
fffffadfe73a0e10 ( 5)         20       20         1 Private      READWRITE
fffffadfe73a0dd0 ( 4)         30      12f         8 Private      READWRITE
fffffadfe71a4770 ( 5)        130      134         0 Mapped       READONLY
fffffadfe781bbe0 ( 3)        140      141         0 Mapped       READONLY
[…]
fffffadfe772d630 (-2)   7fffffdc 7fffffdd         2 Private      READWRITE
fffffadfe788e180 (-1)   7fffffde 7fffffdf         2 Private      READWRITE

Total VADs:    65  average level: 66076419  maximum depth: -1

In the output start and end columns refer to virtual page numbers (VPN). To get an address we need to multiply by 0×1000, for example,  7fffffde000

Filling memory with zeroes to hide data with subsequent saving of a modified crash dump is applicable to user dumps too. Please also check for additional security-related flags in .dump command:

WinDbg is privacy-aware

Another application for data hiding and modification could be the creation of the customized crash dumps for digital forensics exercises and contests.

- Dmitry Vostokov @ DumpAnalysis.org -

Crash Dump Analysis Patterns (Part 16b)

Tuesday, June 10th, 2008

I’ve just found that although I covered Stack Overflow in kernel mode I didn’t do this for user mode. In fact this is one of the simplest patterns to see in crash dumps. It has its own characteristic exception code and stack trace:

FAULTING_IP:
StackOverflow!SoFunction+27
00401317 6a00            push    0

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 00401300 (StackOverflow!SoFunction+0x00000010)
   ExceptionCode: c00000fd (Stack overflow)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 00082ffc

0:000> kL
ChildEBP RetAddr 
00083000 00401317 StackOverflow!SoFunction+0x10
00083010 00401317 StackOverflow!SoFunction+0×27
00083020 00401317 StackOverflow!SoFunction+0×27
00083030 00401317 StackOverflow!SoFunction+0×27
00083040 00401317 StackOverflow!SoFunction+0×27
00083050 00401317 StackOverflow!SoFunction+0×27
00083060 00401317 StackOverflow!SoFunction+0×27
00083070 00401317 StackOverflow!SoFunction+0×27
00083080 00401317 StackOverflow!SoFunction+0×27
00083090 00401317 StackOverflow!SoFunction+0×27
000830a0 00401317 StackOverflow!SoFunction+0×27
000830b0 00401317 StackOverflow!SoFunction+0×27
000830c0 00401317 StackOverflow!SoFunction+0×27
000830d0 00401317 StackOverflow!SoFunction+0×27
000830e0 00401317 StackOverflow!SoFunction+0×27
000830f0 00401317 StackOverflow!SoFunction+0×27
00083100 00401317 StackOverflow!SoFunction+0×27
00083110 00401317 StackOverflow!SoFunction+0×27
00083120 00401317 StackOverflow!SoFunction+0×27
00083130 00401317 StackOverflow!SoFunction+0×27

There could be thousands of stack frames:

0:000> kL 2000
[...]
000a2fa0 00401317 StackOverflow!SoFunction+0x27
000a2fb0 00401317 StackOverflow!SoFunction+0x27
000a2fc0 00401317 StackOverflow!SoFunction+0x27
000a2fd0 00401317 StackOverflow!SoFunction+0x27
000a2fe0 00401317 StackOverflow!SoFunction+0x27
000a2ff0 00401317 StackOverflow!SoFunction+0x27

To reach the bottom and avoid over scrolling we can dump the raw stack data, search for the end of the repeating pattern of StackOverflow!SoFunction+0×27 and try to manually reconstruct the bottom of the stack trace:

0:000> !teb
TEB at 7efdd000
    ExceptionList:        0017fdf0
    StackBase:            00180000
    StackLimit:           00081000

    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7efdd000
    EnvironmentPointer:   00000000
    ClientId:             00001dc4 . 00001b74
    RpcHandle:            00000000
    Tls Storage:          7efdd02c
    PEB Address:          7efde000
    LastErrorValue:       0
    LastStatusValue:      c0000034
    Count Owned Locks:    0
    HardErrorMode:        0

0:000> dds 00081000 00180000
[...]
0017fc74  00401317 StackOverflow!SoFunction+0×27
0017fc78  00000000
0017fc7c  a3a8ea65
0017fc80  0017fc90
0017fc84  00401317 StackOverflow!SoFunction+0×27
0017fc88  10001843
0017fc8c  a3a8ea95
0017fc90  0017fca0
0017fc94  00401317 StackOverflow!SoFunction+0×27
0017fc98  0017fcb8
0017fc9c  a3a8ea85
0017fca0  0017fcb0
0017fca4  00401317 StackOverflow!SoFunction+0×27
0017fca8  00000003
0017fcac  a3a8eab5
0017fcb0  0017fcc0
0017fcb4  00401317 StackOverflow!SoFunction+0×27
0017fcb8  76c68738 user32!_EndUserApiHook+0×11
0017fcbc  a3a8eaa5
0017fcc0  0017fcd0
0017fcc4  00401317 StackOverflow!SoFunction+0×27
0017fcc8  76c6a6cc user32!DefWindowProcW+0×94
0017fccc  a3a8ead5
0017fcd0  0017fce0
0017fcd4  00401317 StackOverflow!SoFunction+0×27
0017fcd8  0037311e
0017fcdc  a3a8eac5
0017fce0  0017fcf0
0017fce4  00401317 StackOverflow!SoFunction+0×27
0017fce8  0017fcd0
0017fcec  a3a8eaf5
0017fcf0  0017fd00
0017fcf4  00401317 StackOverflow!SoFunction+0×27
0017fcf8  76c6ad0f user32!NtUserBeginPaint+0×15
0017fcfc  a3a8eae5
0017fd00  0017fd5c
0017fd04  00401272 StackOverflow!WndProc+0xe2
0017fd08  00401190 StackOverflow!WndProc
0017fd0c  00000003
0017fd10  cf017ada
[…]

We use the extended version of k WinDbg command and supply EBP, ESP and EIP to see in what function it started:

0:000> r
eax=a3b739e5 ebx=00000000 ecx=ac430000 edx=ffefd944 esi=0037311e edi=00000000
eip=00401300 esp=00082ff8 ebp=00083000 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010282
StackOverflow!SoFunction+0×10:
00401300 89442404        mov     dword ptr [esp+4],eax ss:002b:00082ffc=00000000

0:000> k L=0017fcf0 00082ff8 00401300
ChildEBP RetAddr 
0017fcb0 00401317 StackOverflow!SoFunction+0×10
0017fd00 00401272 StackOverflow!SoFunction+0×27

0017fd5c 76c687af StackOverflow!WndProc+0xe2
0017fd88 76c68936 user32!InternalCallWinProc+0×23
0017fe00 76c6a571 user32!UserCallWinProcCheckWow+0×109
0017fe5c 76c6a5dd user32!DispatchClientMessage+0xe0
0017fe98 77ccee2e user32!__fnDWORD+0×2b
0017fedc 0040107d ntdll!KiUserCallbackDispatcher+0×2e
0017ff08 0040151e StackOverflow!wWinMain+0×7d
00402ba0 20245c8b StackOverflow!__tmainCRTStartup+0×176

- Dmitry Vostokov @ DumpAnalysis.org -