Month of Volatility Plugins
We previously discussed sessions, which are containers for processes and other objects related to a user’s logon session. Among those other objects are window stations, which act as security boundaries for processes and desktops. If you’re not already familiar with these objects, see Sessions, Desktops, and Window Stations (Technet) or Window Stations and Desktops (MSDN). From a forensic standpoint, by analyzing window stations objects, you can detect applications snooping on clipboard activity along with the frequency of clipboard usage and the available data formats.
Data Structures
The window station structure is tagWINDOWSTATION. A structure from Windows 7 64-bit is shown below.
>>> dt(“tagWINDOWSTATION”)
‘tagWINDOWSTATION’ (152 bytes)
0x0 : dwSessionId [‘unsigned long’]
0x8 : rpwinstaNext [‘pointer64’, [‘tagWINDOWSTATION’]]
0x10 : rpdeskList [‘pointer64’, [‘tagDESKTOP’]]
0x18 : pTerm [‘pointer64’, [‘tagTERMINAL’]]
0x20 : dwWSF_Flags [‘unsigned long’]
0x28 : spklList [‘pointer64’, [‘tagKL’]]
0x30 : ptiClipLock [‘pointer64’, [‘tagTHREADINFO’]]
0x38 : ptiDrawingClipboard [‘pointer64’, [‘tagTHREADINFO’]]
0x40 : spwndClipOpen [‘pointer64’, [‘tagWND’]]
0x48 : spwndClipViewer [‘pointer64’, [‘tagWND’]]
0x50 : spwndClipOwner [‘pointer64’, [‘tagWND’]]
0x58 : pClipBase [‘pointer’, [‘array’, <function <lambda> at 0x10195a848>, [‘tagCLIP’]]]
0x60 : cNumClipFormats [‘unsigned long’]
0x64 : iClipSerialNumber [‘unsigned long’]
0x68 : iClipSequenceNumber [‘unsigned long’]
0x70 : spwndClipboardListener [‘pointer64’, [‘tagWND’]]
0x78 : pGlobalAtomTable [‘pointer64’, [‘void’]]
0x80 : luidEndSession [‘_LUID’]
0x88 : luidUser [‘_LUID’]
0x90 : psidUser [‘pointer64’, [‘void’]]
- dwSessionId can be used to link a window station to its owning session (it will match _MM_SESSION_SPACE.SessionId).
- rpwinstaNext can be used to enumerate all window stations in the same session as the current one.
- rpdeskList is a pointer to the window station’s first desktop.
- dwWSF_Flags can tell you if the window station is interactive or not (see the WSF_NOIO flag).
- Several of the fields can tell you which thread is viewing the clipboard, which thread owns the clipboard, and which thread (if any) may be listening to clipboard operations (i.e. snooping).
- pClipBase is a pointer to an array of tagCLIP structures that describe the available clipboard formats and contain handles to clipboard objects. The array size is taken from cNumClipFormats.
- iClipSequenceNumber increments by 1 for each object copied to the clipboard. By looking at this number, you can tell how frequently copy operations occur.
- pGlobalAtomTable points to the window station’s atom table.
Many malware samples snoop on clipboard operations. One method is by hooking SetClipboardData and stealing the data as its placed into the clipboard, but that modifies the system in obvious ways. Another method, which you probably will never see is calling GetClipboardData at a fast-paced regular interval (i.e. in a loop with Sleep(100)). Why is this a bad idea? Because before requesting the clipboard data, you must call OpenClipboard, and only one window can have the clipboard open at a time. If malware opens the clipboard to check for data every 100ms, it could accidentally prevent (by blocking) legit applications from accessing the clipboard.
The recommended way to access data as soon as its copied to the clipboard is to register as a clipboard viewer (SetClipboardViewer) or format listener (AddClipboardFormatListener). These functions allow applications to receive notifications (via WM_DRAWCLIPBOARD messages) whenever the content of the clipboard changes. They can then safely open the clipboard and query the data. As always, the most interesting part of all this is the laundry list of artifacts left in physical memory as a result of calling these APIs. The following example uses Nirsoft’s clipboardic (you can also use InsideClipboard) to demonstrate. These tools use the same APIs that malware uses, and since they’re not actually malicious, you can follow along on your own systems.
To help illustrate the exact changes made from specific behaviors, we’ll start with a fresh system just rebooted (i.e. no clipboard activity yet). Here’s the wndscan output for the user’s WinSta0:
$ python vol.py -f memory.dmp –profile=Win7SP1x86 wndscan
**************************************************
WindowStation: 0x7ea45d00, Name: WinSta0, Next: 0x0
SessionId: 1, AtomTable: 0x93b107f0, Interactive: True
Desktops: Default, Disconnect, Winlogon
ptiDrawingClipboard: pid – tid –
spwndClipOpen: 0x0, spwndClipViewer: 0x0
cNumClipFormats: 0, iClipSerialNumber: 0
pClipBase: 0x0, Formats:
Notice the clipboard base is NULL, there are no formats, no clipboard owners or viewers, and the serial number is zero. We can use the wintree plugin (see a future MoVP post) to grep for the initial windows of the class CLIPBRDWNDCLASS.
$ python vol.py -f memory.dmp –profile=Win7SP1x86 wintree | grep CLIPBRDWNDCLASS
Volatile Systems Volatility Framework 2.2_alpha
.#10062 explorer.exe:372 CLIPBRDWNDCLASS
.#100f0 explorer.exe:372 CLIPBRDWNDCLASS
.#1011e vmtoolsd.exe:2224 CLIPBRDWNDCLASS
.#1014a SnagIt32.exe:2300 CLIPBRDWNDCLASS
As you can see, explorer, vmtoolsd (VMware Tools), and SnagIt32 (a screen shot application that allows you to copy/paste images) have windows of this class. That all makes perfect sense. Do you see other applications on your system? If so, do they have a functional need to access the clipboard? These are questions you’ll ask yourself when trying to determine if there are malicious processes snooping on your clipboard.
Now, on my test VM, I opened Notepad++ and Nirsoft’s clipboardic.exe program. I copied some data from my host OS and pasted it into the running VMware guest. I also copied some data from the Notepad++ release notes onto the clipboard. As you can see, the text was captured by clipboardic.exe as expected:
Let’s take a second look at the physical memory after those actions. Keep in mind, malware would use the exact same APIs and produce similar effects.
$ python vol.py -f memory.dmp –profile=Win7SP1x86 wndscan
**************************************************
WindowStation: 0x7ea45d00, Name: WinSta0, Next: 0x0
SessionId: 1, AtomTable: 0x93b107f0, Interactive: True
Desktops: Default, Disconnect, Winlogon
ptiDrawingClipboard: pid – tid –
spwndClipOpen: 0x0, spwndClipViewer: 0xfea5db80 3616 Clipboardic.ex
cNumClipFormats: 4, iClipSerialNumber: 11
pClipBase: 0xfccb2be8, Formats: CF_UNICODETEXT,Unknown choice 8192,CF_TEXT,Unknown choice 197569
What do you see? A new clipboard viewer has been registered by pid 3616 (Clipboardic.exe). There are four clipboard formats, among them are ANSI text and Unicode text (the others are probably OLE data – more on that in a future MoVP post). The serial number has now been increased to 11. Furthermore, there are several new windows of the clipboard class:
$ python vol.py -f memory.dmp –profile=Win7SP1x86 wintree | grep CLIPBRDWNDCLASS
Volatile Systems Volatility Framework 2.2_alpha
.#10062 explorer.exe:372 CLIPBRDWNDCLASS
.#100f0 explorer.exe:372 CLIPBRDWNDCLASS
.#1011e vmtoolsd.exe:2224 CLIPBRDWNDCLASS
.#1014a SnagIt32.exe:2300 CLIPBRDWNDCLASS
.#4002c vmtoolsd.exe:2224 CLIPBRDWNDCLASS
.#10288 notepad++.exe:3140 CLIPBRDWNDCLASS
.#1032c Clipboardic.ex:3616 CLIPBRDWNDCLASS
Conclusion
By analyzing window station objects, you can get a better understanding of the GUI landscape at the time of a compromise or malware infection. Further more, you can easily enumerate desktops, locate atom tables, and determine which processes have registered to receive clipboard notifications. With Volatility, now you can detect which applications may be stealing clipboard data in entirely new ways!
