Security Videos

Entries in Malware analysis (12)


Analyzing DarkComet in Memory

*Note: This article turned out much longer than I originally anticipated. For those who are looking actionable data from this report but don’t want to suffer through the entire article, there are Yara rules at the end!


In a recent case I came across DarkComet and had the opportunity to test out my new Volatility skills. Over the course of this article I will be using a memory dump from a Windows7 VM that I installed the following sample on:

f6351da84168d40fae8da0c156fbab0f – Downloaded from VirusTotal

If you would like to follow along feel free to Download a practice memdump. Keep in mind that the memdump available for download is from the same piece of malware but from a different machine then I used in the rest of the article, so PIDs won't match up. That should make the memdump a little more fun for you. In the case I was working, all I had was a memory sample and an alert from a network appliance stating that DarkComet communications came from the suspected host. My goal in the investigation was to determine if the host was actually infected, is the infection DarkComet, what was the malware doing, was there any exfiltration, and was this infection used to pivot elsewhere in the network.

Getting started

There are a few different approaches an analyst can take. Some will go research heavy and try to learn what they can about DarkComet before looking at the dump, while others like to dive right in. Me, I live dangerously sometimes, so I dove in without doing much research. I actually like a hybrid approach though. Just like when I get a PCAP I like to get a feel for a memory dump before doing too much research, mainly because I don’t want to subject myself to confirmation bias.

Process analysis

Like always I start off with an imageinfo to get an idea of what profile I should use, but also to understand the timezone of the image. Then I move onto psxview. Running psxview, Volatility will check for processes within the memory dump in various ways. This helps us find suspicious processes even if they try to circumvent analysis via one or multiple standard methods. Using the –A flag with psxview applies rules to help us understand what legitimate processes should show as “False” by replacing “False” with “Okay”.


In this case, we didn’t really have to do much analysis to figure out what our bad process probably is. The attackers made it somewhat easy on us by using a common misspelling runddl32.exe. In scenarios where the malware isn’t so obvious we may be looking at loaded dlls, launch times, parents, occurrences, hooks, and paths to find bad processes. So let’s do a dlllist on this guy to find out where it resides.

Ahh, no surprise here, as we typically see %APPDATA% paths leveraged by attackers. That gives us something to work from.

*MSDCSC is a common path utilized by DarkComet. Most likely a default path in the builder.

File extraction

Knowing the path we can check if the file is potentially still resident in memory with filescan. In this case it was, so I used dumpfiles to extract it out. In cases where that doesn’t work procexedump may be better suited.

With it extracted we can then do general analysis on it like one of my favorite commands ever: “strings”. I will skip that for this article though as I want to focus more on what is in memory rather than in the file extracted from memory.

Network communications

Now around this time in the actual case I began to take a closer look at the network connections. Unfortunately though, I did not simulate those connections in this memory dump to be able to show you, so we will skip that as well. Keep in mind you would be looking for what external addresses are involved, what ports, and of course when the network connections occurred. I usually feed the network indicators to Automater for OSINT analysis. Additionally, the connections may be a good place to start getting an idea if lateral movement may be occurring. Looking for connections over 445 or 3389 may indicate pivoting, especially when it is two workstations that are involved.

More process analysis

Getting back to the processes, I thought it would be good idea to do a pslist so I could understand what the parent pid was. The parent was no longer around, so I don’t know what did the initial launch, but I do see other processes launched by that same parent. Also, drawing more attention to the process we see notepad.exe launching under runddl32.exe. Usually when I see notepad.exe I will run the notepad plugin in volatility which will show the text of a notepad session. In this case that did not return any results. Using malfind on the notepad process we see that it is probably not doing any notepad like activity anyways.

Find the Mutants!

At this point there is no question that runddl32.exe is not a normal process. So let’s try to identify other indicators. A great place to start if you know the bad process is to look at handles to see what files, mutants, and registry keys may be of interest. To start off with the Mutants aka Mutex objects, there are some pretty apparent indicators.

DarkComet has a default mutex of “DC_MUTEX-<7 alphanumeric characters>”. For those who don’t understand what a mutex is, there are plenty of good articles you can read up on, but for the purpose of this discussion think of it as a way a program can let the OS know it is there so it doesn’t get launched again while it is already running.

I looked at a lot of DarkComet samples while trying to test the Yara rules that you will see at the bottom. In that testing here are the unique Mutex objects I saw:



*There are a couple in here that I am not positive were actually DarkComet as I used AV signatures to grab the sample set. As we all know AV can sometimes be misleading.

DarkComet config

We have already learned a lot about this malware, but there are still plenty of other things to know. For instance, did it implement a persistence mechanism, what capabilities does it have, how did it get on the system, and so on. To begin to answer those questions I like to dump out the memory of a process and then run strings against it to start to paint a picture. I ran the following command to generate a memdump of the process (runddl32.exe) itself.

python ~/Desktop/volatility/volatility_train/vol.py -f ~/interview/WIN-MKFGQA8PLLR-20131219-151611.raw --profile=Win7SP1x86 memdump -p 1972 -D.

Now with that I ran strings. Keep in mind that when running strings in Linux you need to use the –a options and you have to run separately for ASCII and UNICODE, which will look something like this:

strings -a 1972.dmp #ASCII

strings -a –e l 1972.dmp #UNICODE

*There are of course other methods that can be leveraged here to combine these commands

After spending a ton of time looking through these strings, I began to pick out some very obvious data. My favorite of which is the DarkComet configuration:

As you can imagine, once I found the DarkComet configuration in memory the case changed a lot for me. To really understand it though I had to do a bit of research to understand what each of these options meant.

Most of the data on these commands came from two places, searching through the posts on hackforums[.]net and and article from Context Information Security (http://contextis.com/research/blog/malware-analysis-dark-comet-rat/)

Some of them are obvious like NETDATA, PERSINT, KEYNAME, etc. Others are not so obvious though, like OFFLINEK which became a very important part of my case. So let’s explain some of these here:

MUTEX={DC_MUTEX-KHNEW06} # This is the Mutant/mutex value that is used

SID={Guest16} # Campaign name

FWB={0} # Firewall bypass (Windows Firewall)

NETDATA={test213.no-ip.info:1604} # C2 *Most seem to be 1604 so that is probably the default

GENCODE={F6FE8i2BxCpu} # Not quite sure on this one, perhaps part of building the encryption?

KEYNAME={MicroUpdate} # Registry key name

EDTDATE={16/04/2007} # Used for time stamp manipulation

PERSINST={1} # Persistence

MELT={0} # Delete the original executable or not

CHANGEDATE={1} # Use the EDTDATE to modify the $SI timestamps

DIRATTRIB={6} # Modify the attributes of a directory, such as make it hidden

FILEATTRIB={6} # Modify the attributes of a file, such as make it hidden

OFFLINEK={1} # Offline keylogging

So as you can tell, I didn’t find out what each option does, but enough to get by for now. If I was really interested in knowing each possible option and what it means, I would take the time to get the latest version of the builder and try out each option to determine what the config changed too. Now this sample's configuration differs slightly from the sample I had for the case, but the general strokes are the same.


The OFFLINEK option had me confused for a bit. So to explain it a bit better, when OFFLINEK is enabled “{1}” the malware will continue to log keystroke to a local file that can then be picked up by the attacker as they want. When disabled, the attacker only has access to keystrokes when the attacker has a live session open with the victim. Looking through the strings memdump in my case quickly showed artifacts that were indicative of a keylogger such as “[<-]” and the titles of open windows like outlook emails. Strings also showed a path that seemed somewhat suspicious as well.

In my actual case I did a filescan to see if there was a file object open for the file in the dclogs directory. There was, so I used dumpfiles to extract it. With the file in hand it was easy to see all the keystrokes that were logged in that file.

DarkComet logs keystrokes in a different file for each day. In all the testing and client work I have done, it seems that only the key log file for the day of the acquisition can be extracted as a full file from memory. The log for keystrokes by default are stored in a file named “dclogs\<Date>.dc”. This can be useful in finding the initial infection date, as the log files will have entries in the MFT (We’ll talk more on the timeline later). Within the log, the keystrokes and open windows are logged as seen below.

DarkComet commands

While looking through the strings in the memdump of the runddl32.exe process I also came across some commands that appear to be functions for DarkComet. This hints at some of the functionality. None of this is surprising though, as we have seen plenty or RATs that all have similar functionality.


At this point in the investigation I had about answered everything I had wanted to in my actual investigation. I did not find any evidence that would suggest lateral movement occurred, but I did see plenty of evidence that suggest exfiltration did. My guess is that the exfiltration data was the keylogger logs, but I was not able to prove with the memory image alone. I did not run the ethscan plugin on this occasion, but that may have been able to pull a pcap of suspect traffic. The only remaining items I really wanted to answer were where the persistence key is stored and when did the infection take place.

Let’s check out the persistence first. We know what the key name is based on the configuration artifacts we pulled (MicroUpdate). We also know via research that there are only a few methods available to DarkComet via the builder for persistence. The standard Run key is used most commonly so it is probably the default. Thanks to the printkey plugin this should be a breeze.

There we have it, a standard RUN key in the HKCU for the user that was logged on at the time of infection. With persistence understood, time to check out timeline related data.


In the Volatility Class @gleeda goes over making a “Super Timeline” using time data in the memory. This is done not just with the timeliner plugin, but also by extracting out the registry and a few other techniques. In my actual case that was what I did, but for this demonstration the MFT plugin alone will suffice. Keep in mind that running timeline data can take a while, so what I like to do is run your general plugins like psxview, pstree, pslist, dlllist, netscan, handles, etc and output them to separate files, so you can cat and grep your way through them for analysis while the timeline is building.

python ~/Desktop/volatility/volatility_train/vol.py -f ~/interview/WIN-MKFGQA8PLLR-20131219-151611.raw --profile=Win7SP1x86 mftparser --output=body --output-file=mft.csv

mactime -b mft.csv -d -z UTC-5 > mft2.csv

When analyzing the timeline data, I start with what I already know and pivot from that data. In this case, I know about two directories and some files that are directly involved with this malware. So I will start by grepping that material and looking around the same time frames for other suspicious data.

In this demonstration, svchosts.exe in the local temp directory stood out. Now that you have another file of interest you can do a lot of the same things we have already shown to extract it out and learn more about it. In a real case I am looking for what activity occurred right before, so I can understand what may have been the infection point. For instance if I saw a lot of browsing, than it may be a good idea to check out internet history, if I saw a prefetch file entry for java maybe I would look around for an idx file that could show me more. Additionally I am looking for other items that may indicate what the attacker has done once on the box. Here we see that there are key logs being stored, but in more advanced cases where an attacker manages to get a shell, we may see evidence of the tools the attacker was using. @jackcr had a recent post on this that goes into further details on that topic.

Wrap it up with Yara

I could really go into more details on other parts of this analysis but as this is already a very long article I should probably wrap it up. Part of the reason for writing this post is so that if others came across a DarkComet memory sample they could get to the data quicker than I did. To help along with this, the following Yara rules may prove useful:

rule DarkComet_Config_Artifacts_Memory



           Description = "Looks for configuration artifacts from DarkComet. Works with memory dump and unpacked samples."

           filetype = "MemoryDump"         

           Author = "Ian Ahl @TekDefese"

           Date = "12-19-2013"


           $s0 = "GENCODE={" ascii

           $s1 = "MELT={" ascii

           $s2 = "COMBOPATH={" ascii

           $s3 = "NETDATA={" ascii

           $s4 = "PERSINST={" ascii


           2 of them



rule DarkComet_Default_Mutex_Memory



           Description = "Looks for default DarkComet mutexs"

           filetype = "MemoryDump"              

           Author = "Ian Ahl @TekDefese"

           Date = "12-20-2013"


           $s = "DC_MUTEX-" ascii nocase


           any of them



rule DarkComet_Keylogs_Memory



           Description = "Looks for key log artifacts"

           filetype = "MemoryDump"              

           Author = "Ian Ahl @TekDefese"

           Date = "12-20-2013"


           $s0 = "[<-]"

           $s1 = ":: Clipboard Change :"

           $s2 = "[LEFT]"

           $s4 = "[RIGHT]"

           $s5 = "[UP]"

           $s6 = "[DOWN]"

           $s7 = "[DEL]"

           $s8 = /::.{1,100}\(\d{1,2}:\d{1,2}:\d{1,2}\s\w{2}\)/  


           any of them



Tektip ep25 - Static Malware Analysis With PEFRAME

In this episode of TekTip we cover using peframe to help with the automating of static analysis of Portable Executable (PE) files. While MASTIFF (which we covered extensively) will determine a file type and then based on the file type run the appropriate tools, peframe focuses specifically on PE files or what we generally consider standard windows executables. This focus allows peframe to pull out some great data that we don't see (at least not yet), in other static analysis frameworks.

Peframe was created by Gianni Amato (@guelfoweb) and added to the CAINE digital forensics distro.

Like MASTIFF peframe at its current release can only run against a single file at a time. The script I wrote to automate running MASTIFF against multiple files could be easily modified to do the same for peframe.

Installation for peframe is simple, just download the zip and extract to the directory you want to run it from, for me I chose /opt/peframe. The only dependencies I am aware of are python 2.7, and peid.

-h  --help This help
-a --auto Show Auto analysis
-i  --info PE file attributes
   --hash Hash MD5 & SHA1
   --meta Version info & metadata
   --peid PE Identifier Signature
   --antivm Anti Virtual Machine
   --antidbg Anti Debug | Disassembler
   --sections Section analyzer
 --functions Imported DLLs & API functions
 --suspicious Search for suspicious API & sections
 --dump Dumping all the information
 --strings Extract all the string
 --url Extract File Name and Url
 --hexdump Reverse Hex dump
 --import List Entry Import instances
 --export List Entry Export instances
 --resource List Entry Resource instances
 --debug List Entry DebugData instances

Example Usage:

For must the auto option will pull all the data needed.

tekmalinux@TekMALinux:/opt/peframe$ sudo python peframe.py --auto /opt/malware/e72f79a5399c84f11d954ce59e4186f2 

File Name: e72f79a5399c84f11d954ce59e4186f2

File Size: 752424 byte

Compile Time: 2013-02-26 17:35:54

DLL: False

Sections: 5

MD5   hash: e72f79a5399c84f11d954ce59e4186f2

SHA-1 hash: 8ed3ec95756f7be133f3e94309e0d22795f6da75

Packer: Microsoft Visual C++ 8

Anti Debug: Yes

Anti VM: None

File and URL:

FILE: ntdll.dll

FILE: kernel32.dll

FILE: s.dll

FILE: comctl32.dll

FILE: comdlg32.dll

FILE: shell32.dll


FILE: mfcm90.dll

FILE: user32.dll

FILE: ole32.dll

FILE: .com

FILE: .bat

FILE: .exe



FILE: gdiplus.dll




FILE: USER32.dll

FILE: GDI32.dll






FILE: oledlg.dll

FILE: ole32.dll


FILE: urlmon.dll


URL: http://schemas.microsoft.com/SMI/2005/WindowsSettings

FILE: Windows.Com

URL: http://crl.verisign.com/pca3.crl0

URL: https://www.verisign.com/cps0

URL: http://logo.verisign.com/vslogo.gif04

URL: http://ocsp.verisign.com0

URL: http://logo.verisign.com/vslogo.gif0

URL: https://www.verisign.com/rpa

URL: http://csc3-2010-crl.verisign.com/CSC3-2010.crl0D

URL: https://www.verisign.com/rpa0

URL: http://ocsp.verisign.com0

URL: http://csc3-2010-aia.verisign.com/CSC3-2010.cer0

URL: https://www.verisign.com/rpa

URL: http://csc3-2010-crl.verisign.com/CSC3-2010.crl0D

URL: https://www.verisign.com/rpa0

URL: http://ocsp.verisign.com0

URL: http://csc3-2010-aia.verisign.com/CSC3-2010.cer0

URL: https://www.verisign.com/rpa

URL: https://www.verisign.com/cps0

URL: https://www.verisign.com/rpa0

URL: http://logo.verisign.com/vslogo.gif04

URL: http://crl.verisign.com/pca3-g5.crl04

URL: http://ocsp.verisign.com0

URL: https://www.verisign.com/rpa

Suspicious API Functions:

Func. Name: GetFileAttributesA

Func. Name: GetFileSizeEx

Func. Name: GetModuleHandleW

Func. Name: UnhandledExceptionFilter

Func. Name: IsDebuggerPresent

Func. Name: GetDriveTypeA

Func. Name: GetCommandLineA

Func. Name: GetStartupInfoA

Func. Name: VirtualProtect

Func. Name: VirtualAlloc

Func. Name: ExitThread

Func. Name: CreateThread

Func. Name: FindNextFileA

Func. Name: CreateFileA

Func. Name: FindFirstFileA

Func. Name: GetFileSize

Func. Name: WriteFile

Func. Name: GetModuleFileNameW

Func. Name: GetModuleHandleA

Func. Name: CreateProcessA

Func. Name: GetTempFileNameA

Func. Name: DeleteFileA

Func. Name: CreateDirectoryA

Func. Name: GetTickCount

Func. Name: LoadLibraryA

Func. Name: LoadLibraryA

Func. Name: GetProcAddress

Func. Name: CreateToolhelp32Snapshot

Func. Name: Process32First

Func. Name: Process32Next

Func. Name: OpenProcess

Func. Name: TerminateProcess

Func. Name: GetTempPathA

Func. Name: GetModuleFileNameA

Func. Name: GetVersionExA

Func. Name: Sleep

Func. Name: FindResourceA

Func. Name: LockResource

Func. Name: CreateFileW

Func. Name: GetWindowThreadProcessId

Func. Name: SetWindowsHookExA

Func. Name: RegOpenKeyA

Func. Name: RegCreateKeyExA

Func. Name: RegCloseKey

Func. Name: RegEnumKeyA

Func. Name: RegDeleteKeyA

Func. Name: RegOpenKeyExA

Func. Name: ShellExecuteA

Func. Name: URLDownloadToFileA

Func. Name: InternetConnectA

Func. Name: HttpSendRequestA

Func. Name: InternetReadFile

Func. Name: InternetWriteFile

Func. Name: InternetOpenA

Func. Name: InternetCloseHandle

Func. Name: HttpQueryInfoA

Func. Name: InternetQueryDataAvailable

Func. Name: InternetQueryDataAvailable

Func. Name: InternetCrackUrlA

Suspicious API Anti-Debug:

Anti Debug: UnhandledExceptionFilter

Anti Debug: IsDebuggerPresent

Anti Debug: Process32First

Anti Debug: Process32Next

Anti Debug: TerminateProcess

Anti Debug: GetWindowThreadProcessId

Suspicious Sections:

InternalName: Setup.exe

FileVersion: 2.4.2

CompanyName: DownloadManager

ProductName: DownloadManager.exe

ProductVersion: 2.4.2

FileDescription: DownloadManager                  

OriginalFilename: Setup.exe

Translation: 0x0409 0x04e4

Now of course, if you don't want all the information that the auto option gives you can run the indivual options themselves. Additionally, you can use the --dump, --strings, --hexdump options to pull out more data if the auto option didn't give you what you want.

Overall, I think peframe is a great tool.  While it runs many of the tools that we see in other frameworks it also applies a little analytics to the results pointing out key data like, file names, urls, Anti Forensics techniques, and suspicious API calls.


Installing Cuckoo

In the first post of the Cuckoo Sandbox series, we will cover installation and basic configuration to get you started with automated dynamic malware analysis. 


Cuckoobox is an open source platform for automated dynamic analysis written by Claudio Guarnieri (nex) for the Google Summer of Code project in 2010. In 2012, Cuckoo was sponsored by Rapid7's Magnificent7 program "due to [its] innovative approach to traditional malware analysis". Currently Cuckoo can analyze Windows Executables, DLLs, PDF's, Office Docs, and URLs. Each sample to be analyzed is run through its own "clean" virtual machine, execution is tracked, and after completion the virtual machine is reverted back to its original "clean" state. A detailed report of the behavior the sample produced is generated and cataloged for later review. The system is written in Python and is very modular so it could be leveraged in other frameworks as well as extended for additional analysis or reporting. 


Cuckoo has EXCELLENT documentation so check there for any questions that may arise after running through this installation. There is also an IRC channel (#cuckoosandbox on freenode) and community question portal for additional help. 

As with the MASTIFF installation I am assuming a base installation of Ubuntu 12.10. As always the first step I perform is ensure that I have a fully updated system and have openssh installed for remote management. 

sudo apt-get update; sudo apt-get upgrade -y; sudo apt-get dist-upgrade -y; sudo apt-get autoremove -y; sudo apt-get install openssh-server -y; sudo shutdown -r now later

Next we will begin the installation of the required dependencies.

sudo apt-get install python python-dev python-sqlalchemy python-dpkt python-jinja2 python-magic python-pymongo python-bottle -y

It is also recommended to install python-pefile, this could be accomplished by installing pefile from the apt repo or from source. I mention this as MASTIFF required pefile to be built from source. If both applications will be installed on the same machine I recommend going with the source option. 

PEfile from APT

sudo apt-get install python-pefile

PEfile from source 

cd /opt
svn checkout http://pefile.googlecode.com/svn/trunk/ pefile
cd /opt/pefile
python setup.py build
sudo python setup.py build install
Next we need to install pydeep for ssdeep fuzzy hashes of samples.
sudo apt-get install build-essential git libpcre3 libpcre3-dev libpcre++-dev -y
cd /opt/
wget http://sourceforge.net/projects/ssdeep/files/ssdeep-2.9/ssdeep-2.9.tar.gz
tar -xvzf ssdeep-2.9.tar.gz
rm -f ssdeep-2.9.tar.gz
mv ssdeep-2.9 ssdeep
cd /opt/ssdeep/
sudo make install
sudo ldconfig
cd /opt/
git clone https://github.com/kbandla/pydeep.git pydeep
cd /opt/pydeep/
python setup.py build
sudo python setup.py install
Yara and Yara Python also need to be installed for Yara signature analysis.
sudo apt-get install automake -y
cd /opt
svn checkout http://yara-project.googlecode.com/svn/trunk/ yara
cd /opt/yara
sudo ln -s /usr/bin/aclocal-1.11 /usr/bin/aclocal-1.12
sudo make install
cd yara-python
python setup.py build
sudo python setup.py install
We need to install tcpdump in order to dump network traffic occurring during analysis. 
sudo apt-get install tcpdump
To ensure we do not need to run Cuckoo as root we need to set Linux capabilities for tcpdump.
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
Since Cuckoo leverages virtualization we will need to install a virtualization hypervisor. Since version 0.4 Cuckoo has been architecturally independent from the virtualization software. This means Cuckoo can leverage KVM, Virtualbox, or VMware as the hypervisor and could potentially be extended for use with other hypervisors. That being said THIS guide will focus on installation with VirtualBox for simplicity. However, there are pros and cons for each hypervisor that need to be taken into account for your specific environment. The following will document installing the latest version (as of this writing) of VirtualBox. 
sudo apt-get install libqt4-opengl libsdl1.2debian -y
wget http://download.virtualbox.org/virtualbox/4.2.8/virtualbox-4.2_4.2.8-83876~Ubuntu~quantal_amd64.deb
wget http://download.virtualbox.org/virtualbox/4.2.8/Oracle_VM_VirtualBox_Extension_
sudo dpkg -i virtualbox-4.2_4.2.8-83876~Ubuntu~quantal_amd64.deb
sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-4.2.8-83876.vbox-extpack
sudo /etc/init.d/vboxdrv setup
Now that VirtualBox is installed, create a user for cuckoo to utilize
sudo useradd cuckoo
sudo usermod -g vboxusers cuckoo
Now we are ready to pull down Cuckoo
git clone https://github.com/cuckoobox/cuckoo.git cuckoo
Thats it! Now we need to configure Cuckoo and create some analysis VMs. Change directories into /opt/cuckoo/conf. You will notice there are a few files, we will concern ourselves with three of them: cuckoo.conf, virtualbox.conf, and reporting.conf. First up cuckoo.conf - there is not much to change here if you are working with VirtualBox. The only thing you will need to do is specify some database credentials if you want to utilize something other than the default sqlite. I prefer mysql so I will install and configure that.
sudo apt-get install mysql-server python-mysqldb -y
mysql -u root -p
create database cuckoo;
grant all privileges on cuckoo.* to cuckoo@localhost identified by 'Cuck00@n@lyst!' ;
flush privileges;
Once  mysql is installed edit cuckoo.conf to reflect the database connection parameters you configured above, in this add  mysql://cuckoo:Cuck00@n@lyst!@localhost/cuckoo to the connection line under database.
Next we will look at virtualbox.conf.
mode = gui
path = /usr/bin/VBoxManage
machines = cuckoonode01, cuckoonode02, cuckoonode10,cuckoonode20
label = cuckoonode01
platform = windows
ip =
label = cuckoonode02
platform = windows
ip =
label = cuckoonode10
platform = darwin
ip =
label = cuckoonode20
platform = linux
ip =
The mode defaults to gui which means that you will be able to see the VirtualBox guest as the malware is executed. This option can also be changed to headless if you do not wish to see the VM. Next you will see the virtual machines directive. This is a comma separated list for each virtual machine that will be defined beneath the virtual machine list. Finally the details of the individual VMs are supplied. Platform can be either Windows, Darwin, or Linux. The IP address of the VM MUST be static as cuckoo needs to know this prior to booting the machine.


The last configuration file we need to concern ourselves with is the reporting.conf. This file contains the format of the reports that will be produced upon completion of analyzing a sample. By default the only output options that are enabled are jsondump and reporthtml. This is enough to produce a nice web report but I also like to enable the hpfclient option as well. If you haven't heard about hpfeeds, it is definitely worth the research. Setting up hpfeeds will be the topic of another blog post in the near future.


We are now done with the configuration of CuckooBox. We still need to build an analysis platform prior to submitting any samples. The installation and configuration of a "victim" machine / analysis platform is outside of the scope of this blog post. I will however briefly describe the steps necessary to build out a functioning VM for use in Cuckoo.
  • Install Windows XP SP3 or Windows 7 with UAC disabled
  • Disable Windows Firewall
  • Configure the network
    • Set a static IP address in the network range of the vboxnet0 (default host only network)
    • Configure iptables
      • sudo iptables -A FORWARD -o eth0 -i vboxnet0 -s -m conntrack --ctstate NEW -j ACCEPT
      • sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
      • sudo iptables -A POSTROUTING -t nat -j MASQUERADE
    • Enable forwarding
      • sudo sysctl -w net.ipv4.ip_forward=1
      • sudo sysctl -p
  • Rename VM based on virtualbox.conf
  • Install Python 2.7
  • Install Python Imaging Library 1.7 for Python 2.7 
  • Install additional software (not required but recommended)
    • Microsoft Office
    • Adobe Reader
    • Additional browsers
    • etc
  • Install the Cuckoo agent.py
    • Download from \\vboxsvr\ TEMPORARY share (remove prior to snapshot)
    • cd /opt/cuckoo/agent; python -m SimpleHTTPServer - and download to VM
    • Save/Rename agent.py to agent.pyw if you do not want the terminal window present
  • Execute agent.pyw
  • Snapshot the VM
    • VBoxManage snapshot "cuckoonode01" take "pristine" --pause
    • VBoxManage controlvm "cuckoonode01" poweroff
    • VBoxManage snapshot "cuckoonode01" restorecurrent
We are now done with the first analysis platform. To save time, this process can be simplified to a clone operation. Once the clone of the template is complete you will need to make a few small modifications:
  • Rename the VM (based on virtualbox.conf)
  • ReIP the machine (based on virtualbox.conf)
  • Stop the process associated with agent.py and reexecute agent.pyw
  • Take a new "pristine" snapshot using the steps outlined above
For the next step I recommend installing tmux or screen to manage cuckoo in one terminal (especially if you are remotely managing the machine).
sudo apt-get install tmux -y
cd /opt/cuckoo
Next start cuckoo with the following
python cuckoo.py
If you do not receive any errors and the status message indicates one or more VMs are loaded you are good to go. Open another screen in tmux (<ctrl>+b).
cd /opt/cuckoo/utils
python web.py
This should launch a web server on port 8080 for all interfaces. The web utility is a simple interface that will allow you to view the reports of submitted samples (clicking browse) and will also let you submit individual samples for processing. If you are adding multiple samples for processing it is best to utilize the submit.py utility. By default you can submit:
  • Windows PEs
  • DLLs
  • PDFs
  • Office Documents
  • URLs
usage: submit.py [-h] [--url] [--package PACKAGE] [--custom CUSTOM]
                 [--timeout TIMEOUT] [--options OPTIONS] [--priority PRIORITY]
                 [--machine MACHINE] [--platform PLATFORM] [--memory]
positional arguments:
  target               URL, path to the file or folder to analyze
optional arguments:
  -h, --help           show this help message and exit
  --url                Specify whether the target is an URL
  --package PACKAGE    Specify an analysis package
  --custom CUSTOM      Specify any custom value
  --timeout TIMEOUT    Specify an analysis timeout
  --options OPTIONS    Specify options for the analysis package (e.g.
  --priority PRIORITY  Specify a priority for the analysis represented by an
  --machine MACHINE    Specify the identifier of a machine you want to use
  --platform PLATFORM  Specify the operating system platform you want to use
  --memory             Enable to take a memory dump of the analysis machine
  --enforce-timeout    Enable to force the analysis to run for the full
                       timeout period
The options above provide a lot of flexibility to script the submission process, but it is as simple as
python submit.py --url http://www.tekdefense.com
python submit.py malware.exe
python submit.py malware.pdf
python submit.py malware.doc
Simple right? The above would have produced 4 entries in the submission queue. If there are more entries in the queue than machines available for processing, the sample will be submitted as soon as a VM is freed up and returned to its pristine state. It is also possible to pass a directory containing samples to submit.py. This will cause all samples contained within the directory to be processed. It is very powerful when used in conjunction with delete_original = on in the cuckoo.conf. Adding a large number of samples to the directory and deleting them after processing (copies are contained in storage/analyses/<sample number>). This approach is nice when using something like maltrieve and cron. 

Another nice utility is community.py also found in /opt/cuckoo/utils which will allow you to download the community signatures, machine manager, reporting, and processing modules. 

Cuckoo is an awesome product well worth the small amount of time you will need to invest to get it installed and configured. The amount of data that can be attained with it is astonishing and it can definitely help to speed up some of that analysis or at least help in determining which samples you should devote more of your precious time to.

Installing MASTIFF

So we have talked about using SecShoggoth 's MASTIFF (here, here, and here), but haven't really gone through the installation. Here goes...

I am assuming a base installation of Ubuntu 12.10 (because its easy and you can run it free on AWS). The first thing that we should do is update the base OS and install ssh for remote management.

sudo apt-get update; sudo apt-get upgrade -y; sudo apt-get dist-upgrade -y; sudo apt-get autoremove -y; sudo apt-get install openssh-server -y; sudo shutdown -r now later

Once that is back online we will begin installing the necessary packages for MASTIFF. I am running through the dependencies as they are introduced in the documentation. First lets get the python dependencies out of the way, as well as an editor (nano is fine...albeit evil)

sudo apt-get install python python-dev python-magic python-sqlite python-setuptools python-pip build-essential vim -y 

Install yapsy from pip

sudo pip install yapsy
Now, I tend to pull the majority of my software to /opt out of habit. You do not need to do the same but if you change the location be sure to update to commands below. First I will ensure that the user and group that I am currently using have access to /opt so I can write to that directory.
sudo chown -R `whoami`:`groups | awk '{print $1}'` /opt
Install TrID, download and run the TrID database updater.
cd /opt
mkdir /opt/trid
cd /opt/trid
wget wget http://mark0.net/download/trid_linux.zip
unzip trid_linux.zip
rm -f unzip trid_linux.zip
chmod +x trid
wget http://goo.gl/RQXV8
unzip RQXV8
rm -f RQXV8
chmod +x tridupdate.py
python tridupdate.py
*Note* if you are running this on a 64 bit machine you will need to install ia32-libs
sudo aptitude install ia32-libs
Next we will pull the dependencies down for ssdeep and pyssdeep and then install those packages
sudo apt-get install subversion libpcre3 libpcre3-dev libpcre++-dev -y
cd /opt/
wget http://sourceforge.net/projects/ssdeep/files/ssdeep-2.9/ssdeep-2.9.tar.gz
tar -xvzf ssdeep-2.9.tar.gz
rm -f ssdeep-2.9.tar.gz
mv ssdeep-2.9 ssdeep
cd /opt/ssdeep
sudo make install
sudo ldconfig
svn checkout http://pyssdeep.googlecode.com/svn/trunk/ pyssdeep
cd /opt/ssdeep/pyssdeep
python setup.py build
sudo python setup.py install
Next up is automake and yara:
sudo apt-get install automake -y
cd /opt
svn checkout http://yara-project.googlecode.com/svn/trunk/ yara
cd /opt/yara
sudo ln -s /usr/bin/aclocal-1.11 /usr/bin/aclocal-1.12
sudo make install
cd yara-python
python setup.py build
sudo python setup.py install
Now install simplejson from soure (NOT the APT repo)
sudo apt-get install git -y
cd /opt
git clone https://github.com/simplejson/simplejson simplejson
cd /opt/simplejson
python setup.py build
sudo python setup.py build install
Pull down Didier Stevens awesome pdf tools
mkdir /opt/pdftools
cd /opt/pdftools
wget http://didierstevens.com/files/software/pdf-parser_V0_3_9.zip
unzip pdf-parser_V0_3_9.zip
rm -f pdf-parser_V0_3_9.zip
chmod +x pdf-parser.py
wget http://didierstevens.com/files/software/pdfid_v0_0_12.zip
unzip pdfid_v0_0_12.zip
rm -f pdfid_v0_0_12.zip
chmod +x pdfid.py
cd /opt
wget http://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-9.22.tar.gz
tar -xvzf Image-ExifTool-9.22.tar.gz
rm Image-ExifTool-9.22.tar.gz
mv Image-ExifTool-9.22 exiftool
PE-File (again NOT from the apt repo)
cd /opt
svn checkout http://pefile.googlecode.com/svn/trunk/ pefile
cd /opt/pefile
python setup.py build
sudo python setup.py build install
mkdir /opt/disitool
cd /opt/disitool
wget http://www.didierstevens.com/files/software/disitool_v0_3.zip
unzip disitool_v0_3.zip
rm disitool_v0_3.zip
sudo apt-get install openssl -y
mkdir /opt/pyOLEScanner
cd /opt/pyOLEScanner
wget https://github.com/Evilcry/PythonScripts/raw/master/pyOLEScanner.zip
unzip pyOLEScanner.zip
rm pyOLEScanner.zip
chmod +x pyOLEScanner.py
cd /opt
svn checkout http://distorm.googlecode.com/svn/trunk/ distorm
cd /opt/distorm
python setup.py build
sudo python setup.py build install
And finally MASTIFF itself
cd /opt
wget http://downloads.sourceforge.net/project/mastiff/mastiff/0.5.0/mastiff-0.5.0.tar.gz
tar -xvzf mastiff-0.5.0.tar.gz
rm mastiff-0.5.0.tar.gz
mv mastiff-0.5.0/ mastiff
cd /opt/mastiff
sudo make install
Now that MASTIFF is good to go we will want to ensure that the config file is created / edited properly. Ensure that you read through the config file as you will want to add the appropriate VirusTotal API key. Also if you installed the dependencies to different locations now is the time to correct those paths. 
mkdir /etc/mastiff
cd /etc/mastiff
 cat > /opt/mastiff/mastiff.conf.TEST <<EOF
# This is the configuration file for mastiff.
# Comments are preceded by a # or ;
# log_dir is the base directory where the logs generated will
# be placed in.
#log_dir = /usr/local/mastiff/log
log_dir = ./work/log
# plugin_dir is a list of directories plugins may be present in.
# should be comma-separated.
plugin_dir = ./plugins, /etc/mastiff
# verbose = [on|off]
verbose = off
# Sqlite database options
# db_file = Name of the database file
db_file = mastiff.db
[File ID]
# trid is the location of the TrID binary
# trid_db is the location of the TrID database
#trid = /usr/local/bin/trid
trid = /opt/trid/trid
#trid_db = /usr/local/etc/triddefs.trd
trid_db = /opt/trid/triddefs.trd
[Embedded Strings Plugin]
# Options for the Embedded Strings Plugin.
# strcmd is the path to the strings command
strcmd = /usr/bin/strings
# Options for the VirusTotal Submission Plug-in.
# api_key is your API key from virustotal.com
#   - Leave this empty if you wish to disable this plug-in
api_key = GET_YOUR_OWN
# submit [on|off] - submit binary to VirusTotal
submit = off
# Options to run Didier Stevens pdfid.py script
# pdfid_cmd = Path to the pdfid.py script
#   - Leave blank if you want the script disabled.
# pdfid_opts = Options for program.
#   - Do not put multiple options in quotes.
# Note: pdfid.py has bugs that may cause errors when examining
#       malformed PDFs when using the -e option.
pdfid_cmd = /opt/pdftools/pdfid.py
#pdfid_opts = -e
pdfid_opts =
# Options to run Didier Stevens pdf-parser.py script
# pdf_cmd = Path to pdf-parser.py.
pdf_cmd = /opt/pdftools/pdf-parser.py
[PDF Metadata]
# Options for PDF Metadata script
# exiftool = path to exitfool
exiftool = /opt/exiftool/exiftool
# Options for the Yara signature plug-in
# yara_sigs = Base path to Yara signatures. This path will be recursed
#             to find additional signatures.
#             Leave blank to disable the plug-in.
yara_sigs = /opt/yara
[Digital Signatures]
# Options to extract the digital signatures
# disitool - path to disitool.py script.
# openssl - path to openssl binary
disitool = /opt/disitool/disitool.py
openssl = /usr/bin/openssl
[Office Metadata]
# Options for Office Metadata script
# exiftool = path to exitfool
exiftool = /opt/exiftool/exiftool
[Single-Byte Strings]
# options for single-byte string extraction plug-in
# length - Minimum length to extract
length = 3
# raw - print raw characters instead of formatted ones (e.g. \\n vs. \n)
raw = False
# options for Zip archive file extraction plug-in
# enabled: [on|off] - Extract files or not
# password: Password to use for zip file. OK to leave blank.
enabled = on
password = infected
[Office pyOLEScanner]
# olecmd = Path to pyOLEScanner.py
Now testing MASTIFF out is as simple as:
cd /opt/mastiff
zwned@malwr:/opt/mastiff$ python mas.py /opt/mastiff/tests/test.exe
[2013-03-10 15:11:47,324] [INFO] [Mastiff] : Starting analysis on /opt/mastiff/tests/test.exe
[2013-03-10 15:11:47,326] [INFO] [Mastiff.Init_File] : Analyzing /opt/mastiff/tests/test.exe.
[2013-03-10 15:11:47,326] [INFO] [Mastiff.Init_File] : Log Directory: ./work/log/c69ffb3057b2077fcaecc99b9f16c7c8
[2013-03-10 15:11:47,417] [INFO] [Mastiff.DB.Insert] : Adding ['Generic', 'EXE']
[2013-03-10 15:11:47,506] [INFO] [Mastiff.Analysis] : File categories are ['Generic', 'EXE'].
[2013-03-10 15:11:47,507] [INFO] [Mastiff.Plugins.Embedded Strings Plugin] : Starting execution.
[2013-03-10 15:11:47,521] [INFO] [Mastiff.Plugins.File Information] : Starting execution.
[2013-03-10 15:11:47,602] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Starting execution.
[2013-03-10 15:11:47,602] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Generating fuzzy hash.
[2013-03-10 15:11:47,681] [INFO] [Mastiff.Plugins.Fuzzy Hashing.compare] : Comparing fuzzy hashes.
[2013-03-10 15:11:47,681] [INFO] [Mastiff.Plugins.VirusTotal] : Starting execution.
[2013-03-10 15:11:48,717] [INFO] [Mastiff.Plugins.VirusTotal.submit] : Submission disabled. Not sending file.
[2013-03-10 15:11:48,717] [INFO] [Mastiff.Plugins.yara] : Starting execution.
[2013-03-10 15:11:48,722] [INFO] [Mastiff.Plugins.Resources] : Starting execution.
[2013-03-10 15:11:48,774] [INFO] [Mastiff.Plugins.Single-Byte Strings] : Starting execution.
[2013-03-10 15:11:48,813] [INFO] [Mastiff.Plugins.PE Info] : Starting execution.
[2013-03-10 15:11:48,926] [INFO] [Mastiff.Plugins.Digital Signatures] : Starting execution.
[2013-03-10 15:11:48,975] [INFO] [Mastiff.Plugins.Digital Signatures] : No signature on the file.
[2013-03-10 15:11:48,976] [INFO] [Mastiff.Analysis] : Finished analysis for /opt/mastiff/tests/test.exe.
zwned@malwr:/opt/mastiff$ python mas.py /opt/mastiff/tests/test.pdf
[2013-03-10 15:12:36,299] [INFO] [Mastiff] : Starting analysis on /opt/mastiff/tests/test.pdf
[2013-03-10 15:12:36,299] [INFO] [Mastiff.Init_File] : Analyzing /opt/mastiff/tests/test.pdf.
[2013-03-10 15:12:36,300] [INFO] [Mastiff.Init_File] : Log Directory: ./work/log/3f53a4bf0097f9075ff641b03bb176f5
[2013-03-10 15:12:36,381] [INFO] [Mastiff.DB.Insert] : Adding ['PDF', 'Generic']
[2013-03-10 15:12:36,468] [INFO] [Mastiff.Analysis] : File categories are ['PDF', 'Generic'].
[2013-03-10 15:12:36,469] [INFO] [Mastiff.Plugins.pdf-parser] : Starting execution.
[2013-03-10 15:12:36,470] [INFO] [Mastiff.Plugins.pdf-parser.uncompress] : Uncompressing PDF.
[2013-03-10 15:12:36,563] [INFO] [Mastiff.Plugins.pdf-parser.get_objects] : Extracting interesting objects.
[2013-03-10 15:12:37,532] [INFO] [Mastiff.Plugins.PDF Metadata] : Starting execution.
[2013-03-10 15:12:37,643] [INFO] [Mastiff.Plugins.pdfid] : Starting execution.
[2013-03-10 15:12:37,729] [INFO] [Mastiff.Plugins.Embedded Strings Plugin] : Starting execution.
[2013-03-10 15:12:37,741] [INFO] [Mastiff.Plugins.File Information] : Starting execution.
[2013-03-10 15:12:37,819] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Starting execution.
[2013-03-10 15:12:37,820] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Generating fuzzy hash.
[2013-03-10 15:12:37,909] [INFO] [Mastiff.Plugins.Fuzzy Hashing.compare] : Comparing fuzzy hashes.
[2013-03-10 15:12:37,910] [INFO] [Mastiff.Plugins.VirusTotal] : Starting execution.
[2013-03-10 15:12:38,386] [INFO] [Mastiff.Plugins.VirusTotal.submit] : Submission disabled. Not sending file.
[2013-03-10 15:12:38,386] [INFO] [Mastiff.Plugins.yara] : Starting execution.
[2013-03-10 15:12:38,392] [INFO] [Mastiff.Analysis] : Finished analysis for /opt/mastiff/tests/test.pdf.
zwned@malwr:/opt/mastiff$ python mas.py /opt/mastiff/tests/test.doc
[2013-03-10 15:12:53,882] [INFO] [Mastiff] : Starting analysis on /opt/mastiff/tests/test.doc
[2013-03-10 15:12:53,883] [INFO] [Mastiff.Init_File] : Analyzing /opt/mastiff/tests/test.doc.
[2013-03-10 15:12:53,883] [INFO] [Mastiff.Init_File] : Log Directory: ./work/log/759f7e53f54df03f2ae06fcec25e8ac3
[2013-03-10 15:12:53,973] [INFO] [Mastiff.DB.Insert] : Adding ['Generic', 'Office', 'ZIP']
[2013-03-10 15:12:54,076] [INFO] [Mastiff.Analysis] : File categories are ['Generic', 'Office', 'ZIP'].
[2013-03-10 15:12:54,078] [INFO] [Mastiff.Plugins.Embedded Strings Plugin] : Starting execution.
[2013-03-10 15:12:54,088] [INFO] [Mastiff.Plugins.File Information] : Starting execution.
[2013-03-10 15:12:54,167] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Starting execution.
[2013-03-10 15:12:54,167] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Generating fuzzy hash.
[2013-03-10 15:12:54,234] [INFO] [Mastiff.Plugins.Fuzzy Hashing.compare] : Comparing fuzzy hashes.
[2013-03-10 15:12:54,234] [INFO] [Mastiff.Plugins.VirusTotal] : Starting execution.
[2013-03-10 15:12:55,239] [INFO] [Mastiff.Plugins.yara] : Starting execution.
[2013-03-10 15:12:55,244] [INFO] [Mastiff.Plugins.Office pyOLEScanner] : Starting execution.
[2013-03-10 15:12:57,497] [INFO] [Mastiff.Plugins.Office Metadata] : Starting execution.
[2013-03-10 15:12:57,681] [INFO] [Mastiff.Plugins.ZipInfo] : Starting execution.
[2013-03-10 15:12:57,682] [INFO] [Mastiff.Plugins.ZipExtract] : Starting execution.
[2013-03-10 15:12:57,683] [INFO] [Mastiff.Plugins.ZipExtract] : Password "infected" will be used for this zip.
[2013-03-10 15:12:57,683] [INFO] [Mastiff.Plugins.ZipExtract] : Extracting [Content_Types].xml.
[2013-03-10 15:12:57,683] [INFO] [Mastiff.Plugins.ZipExtract] : Extracting _rels/.rels.
[2013-03-10 15:12:57,684] [INFO] [Mastiff.Plugins.ZipExtract] : Extracting theme/theme/themeManager.xml.
[2013-03-10 15:12:57,684] [INFO] [Mastiff.Plugins.ZipExtract] : Extracting theme/theme/theme1.xml.
[2013-03-10 15:12:57,685] [INFO] [Mastiff.Plugins.ZipExtract] : Extracting theme/theme/_rels/themeManager.xml.rels.
[2013-03-10 15:12:57,685] [INFO] [Mastiff.Analysis] : Finished analysis for /opt/mastiff/tests/test.doc.
zwned@malwr:/opt/mastiff$ python mas.py /opt/mastiff/tests/test.
test.doc  test.exe  test.pdf  test.zip
zwned@malwr:/opt/mastiff$ python mas.py /opt/mastiff/tests/test.zip
[2013-03-10 15:13:22,856] [INFO] [Mastiff] : Starting analysis on /opt/mastiff/tests/test.zip
[2013-03-10 15:13:22,870] [INFO] [Mastiff.Init_File] : Analyzing /opt/mastiff/tests/test.zip.
[2013-03-10 15:13:22,871] [INFO] [Mastiff.Init_File] : Log Directory: ./work/log/033d488bbe65e8aececb2c55bdfbc2fd
[2013-03-10 15:13:23,035] [INFO] [Mastiff.DB.Insert] : Adding ['Generic', 'ZIP']
[2013-03-10 15:13:23,106] [INFO] [Mastiff.Analysis] : File categories are ['Generic', 'ZIP'].
[2013-03-10 15:13:23,107] [INFO] [Mastiff.Plugins.Embedded Strings Plugin] : Starting execution.
[2013-03-10 15:13:23,115] [INFO] [Mastiff.Plugins.File Information] : Starting execution.
[2013-03-10 15:13:23,178] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Starting execution.
[2013-03-10 15:13:23,178] [INFO] [Mastiff.Plugins.Fuzzy Hashing] : Generating fuzzy hash.
[2013-03-10 15:13:23,238] [INFO] [Mastiff.Plugins.Fuzzy Hashing.compare] : Comparing fuzzy hashes.
[2013-03-10 15:13:23,238] [INFO] [Mastiff.Plugins.VirusTotal] : Starting execution.
[2013-03-10 15:13:23,440] [INFO] [Mastiff.Plugins.VirusTotal.submit] : Submission disabled. Not sending file.
[2013-03-10 15:13:23,440] [INFO] [Mastiff.Plugins.yara] : Starting execution.
[2013-03-10 15:13:23,445] [INFO] [Mastiff.Plugins.ZipInfo] : Starting execution.
[2013-03-10 15:13:23,446] [INFO] [Mastiff.Plugins.ZipExtract] : Starting execution.
[2013-03-10 15:13:23,447] [INFO] [Mastiff.Plugins.ZipExtract] : Password "infected" will be used for this zip.
[2013-03-10 15:13:23,447] [INFO] [Mastiff.Plugins.ZipExtract] : Extracting test.bin.
[2013-03-10 15:13:23,447] [INFO] [Mastiff.Plugins.ZipExtract] : Extracting test.txt.
[2013-03-10 15:13:23,448] [INFO] [Mastiff.Analysis] : Finished analysis for /opt/mastiff/tests/test.zip.
If you did not receive any errors / warnings you should be good to go. Now that MASTIFF is up and running we can download MASTIFF2HTML on Github.
wget https://raw.github.com/1aN0rmus/TekDefense/master/MASTIFF2HTML.py
chmod +x MASTIFF2HTML.py
python MASTIFF2HTML.py -f /opt/mastiff/work/log/ -d mastiff.db
cd /opt/mastiff/work/log/www/
python -m SimpleHTTPServer
Now if you browse to you should be seeing the results for your analysis.
 If you run into any issues... please leave a comment so we can address / update as necessary.


I have been spending my nights this week working on a script that will generate a web front end for the results that MASTIFF produces. It has been a blast creating so far, but I would really like to hear from the community what suggestions they have for it.

You can download MASTIFF2HTML on Github.

Here is a video demo of what it looks like right now:

And some pics: