Git Product home page Git Product logo

vmi-gui-reconstruction's Introduction

vmi-reconstruct-gui

A proof-of-concept to reconstruct the GUI of a Xen VM running Windows 7.

❗ Disclaimer

This repository is work in progress. It currently only works with 32-bit Windows 7 SP1 systems.

Description

vmi-reconstruct-gui is a reimplementation of Brendan Dolan-Gavitt’s Volatility screenshot-plugin using libvmi to reconstruct the GUI of a Windows 7-box running as a Xen-guest. It was developed as a draft and blueprint to incorporate GUI forensics into the black-box binary analysis system DRAKVUF in the future.

This tools reconstructs each desktop, that could be found in the memory of a running guest, and shows it one after another as a wireframe. To advance the presented desktop, press any key. Note that, Windows houses a lot of empty desktops, so many of those wireframes will be blank, if there are no visible desktops. res/screenshot.png

Dependencies

vmi-reconstruct-gui depends on the following libraries:

  • libvmi
  • libx11-dev
  • glib

Please make sure to install those libaries and then run make from within this directory.

Usage

To use this tool determine the Xen domain identifier of the Win 7 VM in question and run the compiled binary as illustrated below:

# Set name of the VM specified in its config file
VM_NAME="your-vm-name"

# Retrieve dom id
DOM_ID=$(sudo xl list | grep $VM_NAME | awk '{print $2}')

# Set path to separately created intermediate symbol file for ntoskrn
KRN_IST_FILE="/usr/local/share/vmi/windows7-sp1.json"

# Set path to separately created intermediate symbol file for ntoskrn
W32K_IST_FILE="/usr/local/share/vmi/windows7-sp1-win32k.json"

# Reconstruct the gui, using short opts
sudo ./vmi-reconstruct-gui -d $DOM_ID -k $KRN_IST_FILE -w $W32K_IST_FILE

Per default only the so-called desktop named Default of WinSta0 of session #1 is shown. To show all desktops – regardless, if they are empty or not – use the CLI-flag --all.

A full example with the more explicit CLI-options (long opts) looks like this:

sudo ./vmi-reconstruct-gui --all --domid $DOM_ID \
    --kernel $KRN_IST_FILE --win32k $W32K_IST_FILE

For information on the creation of the referenced intermediate symbo table-files, see section “Excursus: Derivation of IST-files” below.

Background on the working of the tool

The Windows GUI subsystem is structured by the concepts of sessions, window stations, desktops and windows. A session is the logon-environment of a user. Each session has multiple window stations – interactive ones for handling user input and non-interactive ones for services. Each window station has a so-called atom table, which is basically a hashtable of strings and a notable attribute in the context of GUI forensics. The atom entries are shared by processes and – among other things – used to track classes of GUI objects. Most important is, that each window station contains a list of associated desktops. Those house all GUI objects, such as windows, buttons, menus and the like, as the name implies [1].

To perform a reconstruction of the GUI presented to the use, the interactive window stations and all of their non-empty desktops have to be found. One of approach of finding all windows stations is to look at each thread of each process and determine, if it is a GUI-thread. Windows holds its processes in a doubly-link list of _EPROCESS-structs, which contain an ActiveProcessList-field. The kernel symbol PsActiveProcessHead points to the head of this list of active processes. Each process has one or more threads. If the thread environment block contains a pointer to a Win32Threadinfo-struct (and an tagDESKTOPINFO-struct) it is GUI-thread. If this is the case, the housing window station can be retrieved by looking at the Win32Threadinfo-struct more closely, which contains a field named pwinsta – a pointer to the window station. The address to the windowstation can then be collected in a set. Afterwards all windows stations can be traversed and all all desktops and then all windows can be retrieved [2]. For a detailed description of the procedure look at the following section.

Procedure to find windows

The following procedure is applied to reconstruct the GUI windows:

Retrieval of window stations

To find all Window Stations (WinStas), traverse the linked list of _EPROCESS-structs and perform the following steps for each process:

  1. Find ThreadListHead
  2. Traverse linked list of _ETHREAD-structs and check, if current _ETHREAD is a GUI thread This is done by using the TEB-struct in _KTHREAD, which houses a Win32ThreadInfo-struct, if it is a GUI thread
    1. If current _ETHREAD is a GUI-thread, retrieve pointer pwinsta to tagWINDOWSTATION-struct
    2. If current _ETHREAD is not a GUI-thread, continue

Parsing of window stations

To parse each tagWINDOWSTATION-struct, do

  1. Retrieve session ID
  2. Retrieve offset to _RTL_ATOM_TABLE and parse it (not detailed here)
  3. Retrieve flags (specifying, if interactive or not)
  4. Traverse all tagDESKTOP-structs associated with the winsta
    1. Find rpdesklist-pointer to the head of the linked list of associated desktops
    2. Traverse linked list of desktops by using their rpnext-pointers

Retrieval of windows

To get a list of all windows associated with a desktop in their Z-order (bottom to top), traverse each interactive window station and perform for each associated desktop the following steps:

  1. Find the root window
    1. Find _DESKTOPINFO
    2. Find spwnd (struct pointer to the first tagWND-struct)
  2. Allocate an empty list of windows
  3. Form a list of top windows by following pNextWindow of the tagWND-struct until NULL or seen
    1. Check the visibility of each window (WS_VISIBLE-flag has to be set)
      • If not visible, continue
      • If visible, add to list of visible windows
  4. Traverse list of visbile windows in reverse order
    • For each window in list, get child window and recurse to 3.3

After performing this last step, the depth-ordered list of the addresses to all visible tagWND-structs of a desktop is available, this list can be traverse and each tagWND-struct can be parsed.

Note, that Brendan Dolan-Gavitt followed a slightly different approach and retrieved the top window directly by utilizing the following fields: Win32Threadinfo->pDeskInfo->spwnd

Excursus: Derivation of IST-files in JSON-Format from PDB-files

Libvmi can read its intermediate symbol files in two variants – Volatility’s or Rekall’s format. To generate an IST-file in any of the two formats, you need to know the GUID and the age of the kernel-module in question – here win32k.sys. Those uniquely identify a particular version of a PDB-file. You can retrieve those two values, by utilizing a utility drakpdb.py from CERT.pl’s Drakvuf Sandbox.

# Get drakpdb.py
wget https://raw.githubusercontent.com/CERT-Polska/drakvuf-sandbox/master/drakrun/drakrun/drakpdb.py

# Get the GUID and age from the file in question
python3 drakpdb.py pdb_guid --file ~/share/win32k.sys

Generate IST in Volatility’s format

Since the GUID is now known, an IST-file can be generated by retrieving the PDB-file matching the given GUID from Microsoft’s symbol servers and converting it to the JSON-format, which is used by Volatility:

python3 ./volatility3/volatility/framework/symbols/windows/pdbconv.py \
         --guid 6a1a499eed2d42d29e40866f0c374d492 \
         -p win32k.pdb -o windows7-sp1-win32k.json  \

Rekall’s format

To generate a IST-file in Rekalls’ format, you can use the following commands:

# Use the GUID age to retrieve the PDB-file from Microsoft's symbol servers
python3 drakpdb.py fetch_pdb --pdb_name win32k.pdb --guid_age 6a1a499eed2d42d29e40866f0c374d492

# Generate an intermediate symbol file from the retrieve PDB-file
python3 drakpdb.py parse_pdb --pdb_name win32k.pdb > win32k.json

Footnotes

[1] Cf. Ligh, M. H., Case, A., Levy, J., & Walters, A. (2014). The art of memory forensics. John Wiley & Sons. p. 408 f.

[2] This information is based Brendan Dolan-Gavitt’s work on GDI utilities. https://www.cc.gatech.edu/~brendan/volatility/

References

vmi-gui-reconstruction's People

Contributors

jgru avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.