Windows Objects and Pool Allocations

Presenter Notes

What

Windows Executive Objects

Kernel Pool Allocations

Pool Tag Scanning

Finding Objects in memory

Presenter Notes

Windows NT

Windows New Technology (NT) is the family of products from Microsoft

Windows NT 3.1 first OS in 1993

NT still in product version string, but does not refer to anything in product naming.

  • XP = NT 5.1 and 5.2
  • Vista = NT 6.0
  • Windows 7 = NT 6.1
  • Windows 8 = NT 6.2 an 6.3 (8.1)
  • Windows 10 = NT 10

NT* represents Kernel mode in Windows and is still used for the API

Every resource is an object consisting of data and methods to manipulate them

Presenter Notes

Windows API and Hungarian Notation

Microsoft has a naming convention for their API that adds a prefix to the identifier name to indicate its functionality type.

The creator of this scheme, Dr. Charles Simonyi, was from Hungary, hence Hungarian Notation.

Microsoft keeps a list of their coding conventions here and their coding style conventions here.

Presenter Notes

Using Windows API

Understand the basic prefixes for Hungarian notation.

| Prefix   | Description    |
|----------|----------------|
| b        | BOOL           |
| c        | char           |
| cb       | count of bytes |
| dw       | DWORD          |
| h        | Handle         |
| i        | Integer        |
| lp       | long pointer   |
| str      | string         |
| lpstr    | lp to ASCII str|
| lpvoid   | void*          |

Presenter Notes

API Example

BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);

Presenter Notes

Windows NT Operating System Kernel / Ntoskrnl.exe



Contains Kernel and Windows Executive layers of Windows NT

Object Management

Security and Process Management

Cache Manager

Nt or Zw API routines go through ntdll.dll and run in th kernel.

Kernel drivers can call them directly whereas user-mode applications use normal system calls.

Kernel32.CreateFileA -> NtCreateFile

Zw has no significance and was just added to avoid naming conflicts.

There are Ansi and Unicode versions for most API calls

  • A = Ansi
  • W = Unicode/Wide

Presenter Notes

Windows NT Layout

winowsLayout

Presenter Notes

Windows Executive

Upper level of Ntoskrnl.exe

Contains base OS services

Process/Thread management

Security Reference Monitor

I/O System

Presenter Notes

Executive

Exported functions via Ntdll.dll

DeviceIoControl

Kernel mode functions through Windows Driver Development Kit

Memory Manager

Virtual memory management and support for cache management.

Object Management

Create, manage and delete Windows Executive Objects to represent system resources.

Configuration Manager for system registry

Presenter Notes

Kernel

Lower level of Ntoskrnl.exe

Thread scheduling

Synchronization

Interrupt and Exception dispatching

Does not make policies... tasked to Executive

Kernel Objects encapsulated by Executive Objects

Presenter Notes

Executive Objects

Structure → Executive Object

  • OS adds headers to manage services such as naming, access control, reference counters, etc.

25+ Objects

| Object Name  | Strucutre            | Description                                                                |
|--------------|----------------------|----------------------------------------------------------------------------|
| File         | _FILE_OBJECT         |Instance of an open file                                                    |
| Process      | _EPROCESS            |Container that allows threads to execute in a private virtual address space.|
| SymbolicLink | _OBJECT_SYBOLIC_LINK |Alias to map network share paths and removable media                        |
| Token        | _TOKEN               |Security information such as SID and privileges for processes and threads   |
| Thread       | _ETHREAD             |Scheduled execution entry and its CPU context                               |
| Mutant       | _KMUTANT             |Mutal exclision and is used for synchronization                             |

Created by environment subsystem user application

Presenter Notes

WINAPI functions create a ton CreateMutext creates a Mutant object

WINOBJ

Display information on NT Object Manager.

The object management maintains an internal namespace for OS components, drivers and programs.

winObj

Presenter Notes

Important Note

All addresses and structure layouts differ between versions of Windows

Service Packs are known to change memory layout of key structures

Several structures are undocumented

Microsoft adds and removes information from everything all the time

My slides will differ from your output of a structure and I cannot cover all possibilities

  • VolShell
  • Windbg
  • nirsoft
  • The Google

Presenter Notes

Executive Objects

Presenter Notes

OBJECT Structure

objectStructure

Presenter Notes

_OBJECT_HEADER

State information used by the Object Manger

Common to all objects

Up to four optional headers

Precedes the the executive object structure

Weirdly enough, also precedes optional headers

Constant offsets between header and optional headers.

Following the header is the object body for the executive object

Presenter Notes

TName, Quota, Handle, and Creator information headers. executive object = file, proces, symlink, etc. Optional Headers located at a negative offset from start of Object Header

_OBJECT_HEADER

>>> dt("_OBJECT_HEADER")
 '_OBJECT_HEADER' (32 bytes)
0x0   : PointerCount                   ['long']
0x4   : HandleCount                    ['long']
0x4   : NextToFree                     ['pointer', ['void']]
0x8   : Lock                           ['_EX_PUSH_LOCK']
0xc   : TypeIndex                      ['unsigned char']
0xd   : TraceFlags                     ['unsigned char']
0xe   : InfoMask                       ['unsigned char']
0xf   : Flags                          ['unsigned char']
0x10  : ObjectCreateInfo               ['pointer', ['_OBJECT_CREATE_INFORMATION']]
0x10  : QuotaBlockCharged              ['pointer', ['void']]
0x14  : SecurityDescriptor             ['pointer', ['void']]
0x18  : Body                           ['_QUAD']

Presenter Notes

Object Header Layout

objectHeader

Presenter Notes

OBJECT HEADER INFORMATION

Pointer Count

  • Number of references to the object.

Handle Count

  • Number of opened handles to the object.
  • If any handles are open to an object it is locked from certain tasks (file deletion)

Type Index

  • Type of Object

Info Mask

  • Optional Headers in a bit mask if they are present.

Body

  • Start of the structure contained within the object

Presenter Notes

Optional Headers

_OBJECT_HEADER.InfoMask tells us what optional headers are present above the object header

0x1 – CREATOR_INFO

  • Information of creation of object. Back trace of object creation.

0x2 - NAME_INFO

  • Object Name. Named Mutants utilize this.

0x4 – HANDLE_INFO

  • Database of entries for a process that has an open handle to the object.

0x8 – QUOTA_INFO

  • Tracks resources.
  • Idle and System will never have this as an optional header.

0x10 – PROCESS_INFO

  • Identifies owing process if it is an exclusive object.

0x20 - AUDIT_INFO

  • New on Windows 7
  • Contains a pointer to a SecurityDescriptor for the object

Presenter Notes

_OBJECT_HEADER.TypeIndex

Index into nt!ObTypeIndexTable array of Type Objects

Common meta-data for all objects of said type.

typeIndex

Presenter Notes

_OBJECT_TYPE

'_OBJECT_TYPE' (136 bytes)
0x0   : TypeList                       ['_LIST_ENTRY']
0x8   : Name                           ['_UNICODE_STRING']
0x10  : DefaultObject                  ['pointer', ['void']]
0x14  : Index                          ['unsigned char']
0x18  : TotalNumberOfObjects           ['unsigned long']
0x1c  : TotalNumberOfHandles           ['unsigned long']
0x20  : HighWaterNumberOfObjects       ['unsigned long']
0x24  : HighWaterNumberOfHandles       ['unsigned long']
0x28  : TypeInfo                       ['_OBJECT_TYPE_INITIALIZER']
0x78  : TypeLock                       ['_EX_PUSH_LOCK']
0x7c  : Key                            ['String', {'length': 4}]
0x80  : CallbackList                   ['_LIST_ENTRY']

Name: String of object type. Process, File, etc.

TotalNumberOfObjects: Count of objects of this type on system.

TotalNumberOfHandles: Total handles open to this object type on the system

TypeInfo: Type of memory used to allocate object. Paged, Nonpaged. Flags, Type codes, access mask (rwx).

Key: Four-byte tag used to mark memory allocations for this object type.

TypeInfo is the where and Key is the what.

Presenter Notes

objtypescan

Scan for Windows object type objects by enumerating Nt!ObTypeIndexTable

Scans for _OBJECT_TYPE

[root&windows]#volatility -f sample002.bin --profile=Win7SP0x86 objtypescan
Offset       nObjects   nHandles Key      Name                           PoolType
---------- ---------- ---------- -------- ------------------------------ --------------------
0x3f2927c8       0x10       0x10 PcwO     PcwObject                      PagedPool
0x3f4ad6b0        0x0        0x0 Filt     FilterConnectionPort           NonPagedPool
0x3f4b26b0        0x0        0x0 Filt     FilterCommunicationPort        NonPagedPool
0x3ff070f8      0x75d      0x6b5 EtwR     EtwRegistration                NonPagedPool
0x3ff07bb0       0x11       0x11 WmiG     WmiGuid                        NonPagedPool
0x3ff08040        0x6        0x6 EtwC     EtwConsumer                    NonPagedPool
0x3ff599d0        0x5        0x1 Powe     PowerRequest                   NonPagedPool
0x3ff66330     0x10c0     0x1125 Even     Event                          NonPagedPool
0x3ff68350      0x35f      0x361 Sema     Semaphore                      NonPagedPool
0x3ff68418       0x10        0x0 Call     Callback                       NonPagedPool
0x3ff69350        0x0        0x0 Prof     Profile                        NonPagedPool
0x3ff69418       0xba       0xba Time     Timer                          NonPagedPool
0x3ff6b3c0     0x120b      0x3ae File     File                           NonPagedPool
0x3ff6b488       0x6b       0x64 IoCo     IoCompletion                   NonPagedPool
0x3ff6b550       0x7c        0x0 Driv     Driver                         NonPagedPool
0x3ff6b618      0x1a4        0x0 Devi     Device                         NonPagedPool

Presenter Notes

Kernel Pool Allocations

Presenter Notes

Kernel Pools

Range of memory divided into small blocks for storing data from kernel components.

  • Accounting and debug information.
  • Attributes back to driver that owns them.

_POOL_HEADER sits above any optional headers from _OBJECT_HEADER

Presenter Notes

_POOL_HEADER





'_POOL_HEADER' (8 bytes)
0x0   : PoolIndex   #Total size of allocation including all of the object information
0x0   : PreviousSize                   
0x0   : Ulong1                         
0x2   : BlockSize                      
0x2   : PoolType    #Type of system memory. A lot of objects are allocated using nonpageable memory 
0x4   : AllocatorBackTraceIndex        
0x4   : PoolTag     #Four-byte value to identify code path taken to produce the allocation 
0x6   : PoolTagHash

Presenter Notes

Kernel Pool Layout

poolHeader

Presenter Notes

Kernel Pool Allocation

Any instance of an object must be allocated by the kernel from an OS memory pool.

Ntoskrnl.ExAllocatePoolWithTag

PVOID ExAllocatePoolWithTag(
    _In_  POOL_TYPE PoolType,
    _In_  SIZE_T NumberOfBytes, 
    _In_  ULONG Tag
);

Tag comes from _OBJECT_TYPE.Key and needs to match the tag used with ExAllocatePoolWithTag to safeguard memory

Presenter Notes

ObCreateObject

ObCreateObject is an undocumented function that creates executive objects.

  • Determines size of structure to allocate and adds any optional headers before ExAllocatePoolWithTag is called

Size of executive objects + size of _OBJECT_HEADER + size of Optional Headers

  • 1304 for _EPROCESS
  • 1248 Threads
  • 128 Mutant
  • . . .

Presenter Notes

Example Object Creation

  1. Process calls Kernel32.CreateFileA
  2. API leads into ntdll.dll and calls native NtCreateFile
  3. NtCreateFile calls ObCreateObject to request file object
  4. ObCreateObject calculates size of _FILE_OBJECT
  5. ObCreateObject finds _OBJECT_TYPE and determines pool tag
  6. ExAllocateWithPoolTag is called
  7. File handle is now returned to calling process (More to it than that, though.. handle tables, etc)

Presenter Notes

Kernel32.CloseHandle

When a process no longer needs a handle, it is deallocated with CloseHandle()

BOOL WINAPI CloseHandle(
    _In_  HANDLE hObject
);

Block of memory returns to free list

Contents of memory still intact until overwritten.

Object still resident in RAM.

Presenter Notes

ExFreePoolWithTag

It is worth noting that Kernel mode objects are freed with ExFreePoolWithTag which sometimes leaves a protected bit in the tag.

Ntoskrnl.lib
VOID ExFreePoolWithTag(
  _In_  PVOID P,
  _In_  ULONG Tag
);

poolTags

Presenter Notes

Pool-tag Scanning

Search memory for four-byte tags from allocation of executive objects.

  • Using the Key from _OBJECT_HEADER->_OBJECT_TYPE->Key

Finds historical objects

Finds hidden objects from anti-techniques

Can't just look for “Proc”... might not be _EPROCESS.

More or less brute forcing all of memory!

Why pool-tag scan?

Find unlinked, linked and unreachable objects!

For example, a terminated process is no longer in the PsActiveProcessList, but an EPROCESS strucutre is still in memory somewhere!

Robust signatures to determine if an object actually exists. . .

Presenter Notes

Pool Tags

Pooltag.txt from Drive Development Kit lists them... there are A LOT.

PoolMon.exe

  • Live updates pool tag usage
  • Pool tag, type, allocations, frees


c:\bin\poolmon.exe
Memory:  260620K Avail:   96364K  PageFlts:     0   InRam Krnl: 1916K P:17856K
Commit: 203500K Limit: 640916K Peak: 260632K            Pool N: 8332K P:27220K
System pool information
Tag  Type     Allocs            Frees            Diff   Bytes       Per Alloc
Wait Nonp    3971107 (   0)   3971077 (   0)       30    8456 (     0)    281
ObSt Nonp    2791258 (   0)   2791258 (   0)        0       0 (     0)      0
Gxlt Paged   1161638 (   0)   1161630 (   0)        8     864 (     0)    108
Ustm Paged   1088342 (   0)   1088298 (   0)       44    2464 (     0)     56
Io   Nonp    1021112 (   1)   1020985 (   1)      127   91912 (     0)    723

Presenter Notes

In Memory

Pool tag information still in memory (What poolmon uses)

_KDDEBUGGER_DATA64._POOL_TRACKER_TABLE

'_POOL_TRACKER_TABLE' (28 bytes)
0x0   : Key                            ['String', {'length': 4}]
0x4   : NonPagedAllocs                 ['long']
0x8   : NonPagedFrees                  ['long']
0xc   : NonPagedBytes                  ['unsigned long']
0x10  : PagedAllocs                    ['unsigned long']
0x14  : PagedFrees                     ['unsigned long']
0x18  : PagedBytes                     ['unsigned long']

Presenter Notes

PoolTracker

PoolMon in memory implemented in Volatility

Show a summary of pool tag usage

Size per allocation:

  • NpBytes / (NpAllocs-NpFrees)

Gives size of each allocation for a robust pool scanner.

[root&windows]#volatility -f sample002.bin --profile=Win7SP0x86 pooltracker
Tag    NpAllocs NpFrees  NpBytes  PgAllocs PgFrees  PgBytes  Driver               
------ -------- -------- -------- -------- -------- -------- --------------------
Io      67539   66947   55576     27308     27303   224
Even    62482   58194   275952    0         0       0
File    61964   57345   822824    0         0       0
SeTl    27610   26517   69952     0         0       0
Vad     14588   10225   314136    0         0       0
FOCX    12505   12411   4512      0         0       0
usbp    11537   11422   90208     51        49      96
Wait    11179   11124   21704     0         0       0

#Note: I used pooltracker and performed sed and sort on the data to get
#the number of NpAllocs in sorted order.

Presenter Notes

NP = nonpaged P = paged

Volatility Pool Scanning

Robust signature by ensuring adjacent memory near a pool is valid.

OBJECT_HEADER + POOL_HEADER + Executive Object = Size

Similar to total size per allocation from previous slide.

EPROCESS Detection Coniditions

  1. _EPROCESS.Pcb.Header.Type == 0x03 and eprocess.Pcb.Header.Size == 0x1b
  2. _EPROCESS.Pcb.DirectoryTableBase must be aligned to 0x20
  3. _EPROCESS thread list points to the kernel Address Space (Both Flink and Blink for eprocess.ThreadListHead)
  4. _EPROCESS.WorkingSetLock and _EPROCESS.AddressCreationLock look valid

Presenter Notes

Signature

poolScanDiagram

Presenter Notes

Plugins for Executive Objects

| Object Name    | Plugin      |
|----------------|-------------|
| Process        | psscan      |
| Threads        | thrdscan    |
| Desktops       | deskscan    |
| Window Station | wndscan     |
| Mutants        | mutantscan  |
| File           | filescan    |
| Drivers        | driverscan  |
| Symbolic Links | symlinkscan |

Presenter Notes

Pool Scanning Limitations

Untagged memory

  • ExAllocatePool does not allocate a tag for the object

False positives

  • Correlate with other tools/scanners

Large Allocations

Decoy Tags

Arbitrary Tags (“Ddk” for drivers)

Manipulated tag

  • Tags are optional in OS and do not change operation.

Presenter Notes

Scanning Examples

[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 filescan
Volatility Foundation Volatility Framework 2.4
Offset(P)            #Ptr   #Hnd Access Name
------------------ ------ ------ ------ ----
0x000000003da00038      1      1 R--rw- \Device\HarddiskVolume1\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2
0x000000003da00730      8      0 R--rw- \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\LW3MMD1X\widgets[1].js
0x000000003da00b88      7      0 R--r-d \Device\HarddiskVolume1\Windows\System32\srchadmin.dll
0x000000003da00c40      4      0 R--r-d \Device\HarddiskVolume1\Windows\System32\dssenh.dll
0x000000003da00ec8      8      0 R--rw- \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\UWEOZDSW\client[1].js
0x000000003da012b0      8      0 R--r-d \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\47XIWBRS\hub[1].htm
0x000000003da01be0      6      0 R--r-d \Device\HarddiskVolume1\Windows\System32\QAGENTRT.DLL
0x000000003da02188      4      0 RW-rwd \Device\HarddiskVolume1\$Directory
0x000000003da03748      8      0 R--r-d \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\7SYX623H\xd_arbiter[1].htm
[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 dumpfiles -Q 0x000000003da03748 -D html/
Volatility Foundation Volatility Framework 2.4
DataSectionObject 0x3da03748   None   \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\7SYX623H\xd_arbiter[1].htm

We can now open that file

<!DOCTYPE html><html><head><title>Facebook Cross-Domain Messaging helper</title></head><body><script> document.domain = 'facebook.com'; var ES5 = function(){
__d("ES5ArrayPrototype",[],function(a,b,c,d,e,f){var g={};g.map=function(h,i){if(typeof h!='function')throw new TypeError();var j,k=this.length,l=new Array(k);for(j=0;j<k;++j)if(j in this)l[j]=h.call(i,this[j],j,this);return l;};g.forEach=function(h,i){g.map.call
-- CUT --

Presenter Notes

Dumpfiles

Cached files appear in memory dumps and can be recovered using Dumpfiles.

Dumpfiles iterates through the VAD and extracts all files that are mapped as DataSectionObject, ImageSectionObject or SharedChacheMap.

-r REGEX, --regex=REGEX
                Dump files matching REGEX
-i, --ignore-case     Ignore case in pattern match
-o OFFSET, --offset=OFFSET
                Dump files for Process with physical address OFFSET
-Q PHYSOFFSET, --physoffset=PHYSOFFSET
                Dump File Object at physical address PHYSOFFSET
-D DUMP_DIR, --dump-dir=DUMP_DIR
                Directory in which to dump extracted files
-S SUMMARY_FILE, --summary-file=SUMMARY_FILE
                File where to store summary information
-p PID, --pid=PID     Operate on these Process IDs (comma-separated)
-n, --name            Include extracted filename in output file path
-u, --unsafe          Relax safety constraints for more data
-F FILTER, --filter=FILTER
                Filters to apply (comma-separated)

Dumped files are shown as file.[PID].[OFFSET].[EXT] OR named if -n is used.

Presenter Notes

Symlinkscan

Scan for symbolic link objects

  -V, --virtual         Scan virtual space instead of physical
  -W, --show-unallocated
                        Skip unallocated objects (e.g. 0xbad0b0b0)
  -A START, --start=START
                        The starting address to begin scanning
  -G LENGTH, --length=LENGTH
                        Length (in bytes) to scan from the starting address


[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 symlinkscan
Volatility Foundation Volatility Framework 2.4
Offset(P)            #Ptr   #Hnd Creation time                  From                 To
------------------ ------ ------ ------------------------------ -------------------- ------------------------------------------------------------
0x0000000002de3278      1      0 2013-10-15 18:45:58 UTC+0000   Global               \Global??
0x00000000030b40a8      1      0 2013-10-15 18:45:46 UTC+0000   DosDevices           \??
0x00000000030b8470      1      0 2013-10-15 18:45:46 UTC+0000   Global               \GLOBAL??
0x000000000f3c77d8      1      0 2013-10-15 18:45:59 UTC+0000   Z:                   \Device\hgfs\;Z:0000000000027f8d\vmware-host\Shared Folders
0x00000000122c0ce8      1      0 2013-10-15 18:45:53 UTC+0000   Local                \BaseNamedObjects
0x0000000012474030      1      0 2013-10-15 18:46:00 UTC+0000   UMB#UMB#1...e1ba19f} \Device\00000069
0x0000000012dca868      1      0 2013-10-15 18:45:56 UTC+0000   $VDMLPT1             \Device\ParallelVdm0

Presenter Notes

EOF

Photos snipped from Windows Internals 6th Edition Volume 1 & 2, David Solomon and Mark Russinovich.

Presenter Notes