Source Code
Note: These instructions are for use with Ether 0.1, released on April 7, 2009. You can also obtain the instructions for the original release of Ether.
For changes between versions, please see the changelog.
Ether comes in two components: one is patch set to the Xen hypervisor (version 3.1.0), and the other a userspace application which runs in a Xen dom0.
Ether is research quality code. It has only been tested on Debian Etch and Lenny as the host operating system, and Windows XP Service Pack 2 as the guest operating system. In its present form Ether is not meant to be used in a production environment, but should instead be used as a research tool. All code is licensed under the GPL, unless otherwise noted in the file.
The directions for downloading, building and using Ether are outlined below in several separate sections.- Prerequisites the necessary background information one needs to know before installing Ether, and links to obtain all prerequisite software.
- Patching the Xen Hypervisor describes how to patch Xen 3.1.0 with the Ether patches and how to successfully build the resulting code.
- Building the Ether Controller details the prerequisites for building the Ether controller application and the application build process.
- Preparing the Guests lists the requirements for guest operating systems Ether can trace and how to make them more compatible with Ether.
- Using Ether outlines the features of Ether and how to make use of Ether to do analysis on guest virtual machines.
Prerequisites
Ether uses Intel VT for transparent malware analysis, and therefore must be run on bare metal. Also, the machine onto which you are installing Ether must have an Intel VT capable processor and have Intel VT enabled in the BIOS. By default most BIOSes leave Intel VT disabled. Do not attempt to install Ether in a virtual machine. Ether requires a 64-bit capable CPU. Ether will not compile on a 32-bit platform. The latest version of Ether compiles and runs on Debian Lenny. Other Linux distributions could conceivably work, but Debian Lenny is the only one on which Ether has been tested. The only guest operating system tested with Ether is Windows XP Service Pack 2, hence a Windows XP SP2 installation medium is also required. Prerequisite download links:- Debian Lenny: http://www.debian.org/distrib/
- Xen 3.1.0 Source: http://bits.xensource.com/oss-xen/release/3.1.0/src.tgz/xen-3.1.0-src.tgz
- Ether Xen Patch Set: ether.0.1.patch.gz
- Ether Controller: ether_ctl.0.1.tar.gz
- Ether Paper: ether_ccs_2008.pdf
- Start with a fresh bare-metal install of Debian Lenny.
- Install Xen 3.1.0 from source and verify the Xen install works.
- Patch the Xen hypervisor with the Ether patches.
- Install the Ether userspace.
- Install Windows XP SP2 domUs.
- Analyze malware!
Patching the Xen Hypervisor
- Start with a vanilla install of Debian Lenny.
- Install the Xen kernel package for the kernel revision you are using. As of this writing, the package to install is linux-image-2.6.26-1-xen-amd64. Do not install all of Xen, only the Xen-enabled kernel, and do not boot into this kernel, yet.
- Download the source to the Xen hypervisor version 3.1.0. The Xen source code is available directly from XenSource at http://bits.xensource.com/oss-xen/release/3.1.0/src.tgz/xen-3.1.0-src.tgz
artem@vmstudent:~/$ mkdir ether
artem@vmstudent:~/$ cd ether
artem@vmstudent:~/ether$ wget http://bits.xensource.com/oss-xen/release/3.1.0/src.tgz/xen-3.1.0-src.tgz
artem@vmstudent:~/ether$ tar -xvzf ./xen-3.1.0-src.tgz
- Build and install Xen 3.1.0 from the source you just downloaded. There are many excellent installation guides available on the web and can be found via a simple search. Keep in mind that you will not be using the 2.6.18 kernel that the Xen 3.1.0 installation will try to use by default. Double check any /boot/grub/menu.lst entries to ensure they point at the Xen kernel in the Debian package you installed earlier.
- Once Xen is installed and working, make a copy of the source tree you installed from for use as a backup.
- Download and apply the Ether patch to the original source tree:
- Compile the modified Xen source. Only Xen itself needs to be recompiled, and not the dom0 kernel.
artem@vmstudent:~/ether$ cd xen-3.1.0-src/xen
artem@vmstudent:~/ether/xen-3.1.0-src/xen$ make clean && make
- Copy the Ether patched Xen to your /boot directory.
artem@vmstudent:~/ether/xen-3.1.0-src/xen$ sudo cp -v ./xen.gz /boot/xen-ether.gz
- Create a new entry in your /boot/grub/menu.lst file for the Ether patched Xen hypervisor. This should be the same as the normal Xen entry, but of course modified to point to the new hypervisor. Double check that your boot entry points to the correct kernel and to the correct hypervisor.
- Insert a symbolic link from the public Ether header files in the source tree to the global include directory. This will ensure the Ether userspace will compile. There is a script provided for this, which assumes default locations present on Debian Lenny.
artem@vmstudent:~/ether/xen-3.1.0-src/xen$ chmod +x ./symlink_header.sh
artem@vmstudent:~/ether/xen-3.1.0-src/xen$ sudo ./symlink_header.sh
- Restart the machine and cross your fingers. Be sure to select the boot entry you created for Ether in the GRUB menu during bootup. Once the machine boots up, proceed to the next step of building the Ether controller.
artem@vmstudent:~/ether$ gunzip ether.0.1.patch.gz
artem@vmstudent:~/ether$ patch -p0 < ether.0.1.patch
patching file ./xen-3.1.0-src/tools/libxc/Makefile
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/ether_bp.c
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/ether.c
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/ether_unpack.c
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/hvm.c
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/Makefile
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/nls.c
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/vmx/vmcs.c
patching file ./xen-3.1.0-src/xen/arch/x86/hvm/vmx/vmx.c
patching file ./xen-3.1.0-src/xen/arch/x86/mm/shadow/common.c
patching file ./xen-3.1.0-src/xen/arch/x86/mm/shadow/multi.c
patching file ./xen-3.1.0-src/xen/arch/x86/mm/shadow/private.h
patching file ./xen-3.1.0-src/xen/arch/x86/mm/shadow/types.h
patching file ./xen-3.1.0-src/xen/common/domctl.c
patching file ./xen-3.1.0-src/xen/common/event_channel.c
patching file ./xen-3.1.0-src/xen/drivers/char/console.c
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/domain.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/ether_bp.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/ether.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/ether_unpack.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/msw.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/nls.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/support.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/vmx/vmcs.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/hvm/vmx/vmx.h
patching file ./xen-3.1.0-src/xen/include/asm-x86/paging.h
patching file ./xen-3.1.0-src/xen/include/public/domctl.h
patching file ./xen-3.1.0-src/xen/include/public/hvm/ether.h
patching file ./xen-3.1.0-src/xen/include/xen/event.h
patching file ./xen-3.1.0-src/xen/symlink_header.sh
Building the Ether Controller
- The Ether controller relies on several external libraries. On Debian Lenny, the following packages must be installed prior to building Ether.
- libdisasm0
- libdisasm-dev
- bison
- flex
- Download the Ether controller source: ether_ctl.0.1.tar.gz. This application is meant to be run in domain 0 of an Ether patched Xen hypervisor.
artem@vmstudent:~/ether$ wget http://ether.gtisc.gatech.edu/ether_ctl.0.1.tar.gz
artem@vmstudent:~/ether$ tar -xvzf ./ether_ctl.0.1.tar.gz
- Build the Ether controller.
artem@vmstudent:~/ether/ether_ctl$ make clean && make
Preparing the Guests
The only guest operating system Ether has been extensively tested with is Windows XP Service Pack 2. When installing the OS on a domU, do it with the APIC disabled in the hvm guest configuration file.
There is a Windows guest installation guide provided by XenSource available at http://ether.gtisc.gatech.edu/xen_install_windows.pdf
Example hvm guest configuration file:
arch = os.uname()[4]
if re.search('64', arch):
arch_libdir = 'lib64'
else:
arch_libdir = 'lib'
#----------------------------------------------------------------------------
# Kernel image file.
kernel = "/usr/lib/xen/boot/hvmloader"
# The domain build function. HVM domain uses 'hvm'.
builder='hvm'
# Initial memory allocation (in megabytes) for the new domain.
memory = 128
# A name for your domain. All domains must have different names.
name = "windows-001"
# enable/disable HVM guest ACPI, default=0 (disabled)
acpi=0
# enable/disable HVM guest APIC, default=0 (disabled)
apic=0
# Pae
pae=0
cpus = "1" # all vcpus run on CPU1
vif = [ 'type=ioemu, mac=aa:cc:b0:00:00:11, bridge=xenbr1' ]
disk = [ 'file:<path to disk image>,ioemu:hda,w' ]
boot="cda"
vnc=1
vncviewer=0
ne2000=0
Once the Windows XP Service Pack 2 guest is installed, the boot.ini file needs to be edited to disable PAE in the guest. The current version of Ether does not support memory write detection in PAE guests. Both the /noexecute=alwaysoff and the /nopae options must be added to boot.ini to actually disable PAE in Windows.
Example Windows boot.ini file:
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /fastdetect /nopae /noexecute=alwaysoff
Using Ether
This version of Ether can be used to trace Windows Native API calls executed by an application (and their return values), instructions executed by that application, any unpack-execution behavior, and also memory writes. In addition, introspection of Native API calls is performed. Such introspection includes displayin system call names, interpretation of typed arguments, attempted DNS lookups, and TCP connection attempts.
The general format of Ether controller invocation is:
Specific Ether Features:
- System Call Tracing
System call tracing is performed by the systrace command. By default, Ether will trace system calls executed by every process in the guest operating system. However, a specific process may also be selected. The other optional parameter passed to the systrace command is the guest virtual address on a page guaranteed to be marked as non-present. By default it is assumed to be 0xFFFFD0AE.To trace all Native API calls executed by every process in the guest:
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 systrace
To trace system calls for a specific process:
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 systrace exe_file
To trace system calls for a specific process using an alternate not-present address:
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 systrace exe_file 0xDDDD1234
To trace system calls for a all processes using an alternate not-present address:
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 systrace % 0xDDDD1234
- Unpack-Execution Detection
The unpack commands are responsible for instructing Ether to perform unpack execution detection. These commands will only attempt to detect unpack execution in a specific process, the name of which is specified as a parameter to the command. Any unpack-execution layers found in the guest are saved in the images directory. The target does not have to be executing when the command is issued, Ether will attempt to match the name to any processes executed after the command is entered.
Since Ether 0.1, there are two ways to do unpack-execution detection. One method, used via the unpack_hypervisor command, allocates 256Mb of memory from the domain heap and uses it as a bit map to track memory locations which have been written. The other method, used via the unpack_userspace command, does not require a single large allocation and instead uses a hash table in dom0 userspace to keep track of locations which have been written to.
While the unpack_hypervisor method is faster, the unpack_userspace method uses less memory. Both should be equally effective.
Prior to issuing the unpack_hypervisor command, the maximum memory for a domain should be set to 256Mb more than the domain will use. Ether needs to allocate 256Mb of memory from the domain heap to keep track of dirty guest memory addresses. A shell script, prepare_domain.sh, is provided for the purpose of automating this preparation process.
The unpack commands will not automatically terminate. You must manually terminate the ether_ctl process via SIGINT (Ctrl + C).artem@vmstudent:~/ether/ether_ctl$ sudo ./prepare_domain.sh 1
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 unpack_hypervisor packed_file
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 unpack_userspace packed_file
EtherUnpack will also attempt to repair memory dumps to be more like normal PE files. The original executable can be given as a parameter to EtherUnpack to aid in this task. It does not matter whether hypervisor unpacking or user-space unpacking is used.
artem@vmstudent:~/ether/ether_ctl$ sudo ./prepare_domain.sh 1
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 unpack_hypervisor packed_file ~/malware/packed_file.exe
- Instruction-Level Tracing
The instrtrace command will display instructions executed by a specific process in the system. The parameters to this command are the domain and the process name to trace. The Ether controller will attempt to disassemble and display the executed instructions. Some instructions however do not disassemble correctly. I believe this is a fault of the disassembler library
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 instrtrace exe_file
- Memory Write Detection
Memory write detection is performed by the memwrite command. As an argument, the command takes the name of a process for which to trace memory writes. The guest virtual address of the instruction causing the write, the guest virtual address of the write location, and the calculated length of the write are reported.
artem@vmstudent:~/ether/ether_ctl$ sudo ./ether 1 memwrite exe_file