-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First three chapters. Tested locally. Signed-off-by: Matteo Cafasso <[email protected]>
- Loading branch information
Showing
4 changed files
with
276 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
Hello Sandbox | ||
============= | ||
|
||
Now that the basics are ready, we can start building our automated test environment. | ||
|
||
Core elements of SEE consist of the Environment, which takes care of resources management, and the Context which wraps the sandbox allowing to control its lifecycle. | ||
|
||
The following example shows the basic workflow. Once initialized the Context, we power on the sandbox, we let it run for one minute and then we power it off. | ||
|
||
:: | ||
|
||
import time | ||
|
||
from see import Environment | ||
from see.context import QEMUContextFactory | ||
|
||
|
||
def main(): | ||
context_factory = QEMUContextFactory('/home/username/context.json') | ||
|
||
with Environment(context_factory, {}) as environment: | ||
context = environment.context | ||
|
||
context.poweron() | ||
|
||
time.sleep(60) | ||
|
||
context.poweroff() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() | ||
|
||
SEE takes care of the resources allocation/deallocation as well as for their isolation. This script can be executed multiple times resulting in multiple test environment running concurrently. | ||
|
||
Once the execution ends, no trace will remain of the virtual machine. | ||
|
||
Controlling the Sandbox | ||
----------------------- | ||
|
||
Every proper tutorial includes the "Hello World" example, we cannot be outdone. | ||
|
||
To better control the execution flow, SEE provides an event-driven architecture allowing to trigger Events and subscribe handlers through the Context object. | ||
|
||
In the next code snippet, we print the "Hello Sandbox" string after starting the sandbox. At the same go we open a VNC connection to inspect its execution. | ||
|
||
To complete the script, we turn it into a command line tool complete with parameters. | ||
|
||
:: | ||
|
||
#!/usr/bin/env python3 | ||
|
||
import time | ||
import argparse | ||
import subprocess | ||
|
||
from see import Environment | ||
from see.context import QEMUContextFactory | ||
|
||
|
||
def hello_sandbox_handler(event): | ||
print("Hello Sandbox") | ||
|
||
|
||
def vnc_handler(event): | ||
command = ('virt-viewer', '--connect', 'qemu:///system', event.identifier) | ||
subprocess.call(command) | ||
|
||
|
||
def main(): | ||
arguments = parse_arguments() | ||
|
||
context_factory = QEMUContextFactory(arguments.context) | ||
|
||
with Environment(context_factory, {}) as environment: | ||
context = environment.context | ||
|
||
context.subscribe('vm_started', hello_sandbox_handler) | ||
|
||
# asynchronous handlers do not block the execution | ||
# when triggering the Event | ||
context.subscribe_async('vm_started', vnc_handler) | ||
|
||
context.poweron() | ||
|
||
# the Environment ID is appended to the event as extra information | ||
context.trigger('vm_started', identifier=environment.identifier) | ||
|
||
time.sleep(60) | ||
|
||
context.poweroff() | ||
|
||
|
||
def parse_arguments(): | ||
parser = argparse.ArgumentParser(description='Run a Sandbox.') | ||
|
||
parser.add_argument('context', help='path to Context JSON configuration') | ||
|
||
return parser.parse_args() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() | ||
|
||
|
||
Now we can run multiple isolated test cases through our command line script. | ||
|
||
:: | ||
|
||
./sandbox.py context.json | ||
Hello Sandbox |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
Installation | ||
============ | ||
|
||
Please refer to the `installation documentation <http://libvirt.org/docs.html>`_ if problems are encountered. | ||
|
||
Requirements | ||
------------ | ||
|
||
The following base Debian packages are required. | ||
|
||
- python3 | ||
- python3-pip | ||
|
||
The following Debian packages provide the core virtualization technologies. | ||
|
||
- qemu | ||
- qemu-tools | ||
- dnsmasq | ||
- python3-libvirt | ||
- virt-viewer | ||
- virtinstall | ||
|
||
These Debian packages are not strictly necessary. They are required in order to run the scanning plugins. | ||
|
||
- python3-guestfs | ||
- tshark | ||
- volatility | ||
|
||
Additional Python packages. | ||
|
||
- vminspect | ||
|
||
Set up | ||
------ | ||
|
||
SEE can be installed using pip. | ||
|
||
:: | ||
|
||
# pip3 install python-see | ||
|
||
For correct operation, the user which will run the analysis platform will need to be part of the following groups. | ||
|
||
- kvm | ||
- libvirt | ||
- libvirt-qemu | ||
|
||
The following command allows to add a user to a group. | ||
|
||
:: | ||
|
||
# adduser <username> <group> | ||
|
||
Make sure hardware acceleration is supported. | ||
|
||
To verify that KVM is available it is enough to run: | ||
|
||
:: | ||
|
||
# modprobe kvm | ||
# modprobe kvm_intel | ||
|
||
for Intel processors or: | ||
|
||
:: | ||
|
||
# modprobe kvm | ||
# modprobe kvm_amd | ||
|
||
for AMD ones. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
Environment setup | ||
================= | ||
|
||
Preparing the Guest Image | ||
------------------------- | ||
|
||
In order to perform our tests, we need to provide a copy of a Windows Operating System to be executed within a Virtual Machine. | ||
|
||
Microsoft made available for downloading `ready-made virtual machine disk images <https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/>`_ containing Windows 7. | ||
|
||
These images are for testing purposes only and they do not allow samples analysis at scale. Yet they are a good starting point for our analysis environment. | ||
|
||
Unfortunately, there are no QCOW2 copies available. Even though QEMU allows to execute other disk formats, it is highly recommended to convert the downloaded disk image in QCOW2 format. | ||
|
||
The downloaded file will be a ZIP archive containing a OVA file. OVA files can be extracted in the following way. | ||
|
||
:: | ||
|
||
$ tar -xvf "IE8 - Win7.ova" | ||
IE8 - Win7.ovf | ||
IE8 - Win7-disk1.vmdk | ||
|
||
The OVF file can be automatically converted and imported using virt-convert tool. | ||
|
||
:: | ||
|
||
$ mkdir /home/username/images | ||
$ virt-convert --disk-format qcow2 --destination /home/username/images --connect qemu:///system "IE8 - Win7.ovf" | ||
|
||
If successful, the User will be prompted to a VNC connection where the Operating System will be booting. Make sure the drivers get automatically installed (it might require to reboot the OS). Once done, ensure basic things such as Internet connection are working. | ||
|
||
Proceed with the desired customisation. As an additional action, install Python3 within the OS. This is not strictly necessary but will help later in the Tutorial. | ||
|
||
Make sure the virtualized OS is correctly shut down once done. | ||
|
||
Configuring SEE | ||
--------------- | ||
|
||
SEE requires few configuration files to correcly operate. | ||
|
||
The libvirt XML configuration related to the imported Windows image must be stored somewhere. | ||
|
||
:: | ||
|
||
$ virsh --connect qemu:///system list --all | ||
Id Name State | ||
|
||
- IE8_-_Win7.ovf shut off | ||
|
||
$ virsh --connect qemu:///system dumpxml IE8_-_Win7.ovf >> /home/username/windows7.xml | ||
|
||
Then, a JSON file will be used to describe the Context configuration. | ||
|
||
:: | ||
|
||
/home/username/context.json | ||
|
||
{ | ||
"domain": | ||
{ | ||
"configuration": "/home/username/windows7.xml" | ||
}, | ||
"disk": | ||
{ | ||
"image": "/home/username/images/IE8_-_Win7-disk1.qcow2", | ||
"clone": | ||
{ | ||
"storage_pool_path": "/home/username/instances", | ||
"copy_on_write": true | ||
} | ||
} | ||
} | ||
|
||
The following configuration will instruct SEE to create a virtual machine (a domain) using the above mentioned libvirt configuration file. | ||
|
||
The domain will use the disk image we just converted. The `clone` field, instructs SEE to make a clone of the given disk. In this way, the running test will not change or affect the base disk image. The clone will be located in `storage_pool_path` and it will be few Mb in size as `copy_on_write` is enabled. | ||
|
||
Advanced configuration | ||
---------------------- | ||
|
||
TODO |