Description:
Cuckoo is a malware analysis project written in Python, compatible only with Python 2.7. Cuckoo uses virtualization to create a sandbox environment, with Windows 7 typically being used because Windows is widely targeted, and Windows 7 has low hardware requirements. However, Cuckoo is also compatible with Windows 10 and 11, although the necessary specifications may vary based on your preferences
Cuckoo spins up a virtual Windows instance as a sandbox. When you submit potential malware, Cuckoo installs it into the sandbox and executes it. Cuckoo installs its agent in the sandbox to collect diagnostics, which are then sent back to the Cuckoo server, where you can view telemetry data on the malware, including:
-
Network activity
-
Process activity
-
Registry changes
-
Behavioral data
These telemetry details help in thoroughly analyzing the malware and identifying services and data affected
In this guide, we will implement Cuckoo on an Ubuntu virtual machine. My host machine is running Windows
Specifications of my machine:
- OS - Windows 11 Home 64bit
- CPU - i5-13420H (8 Cores)
- RAM - 16.0 GB
- SSD - 512 GB
- GPU - RTX4050 4GB
Pre-requisites:
- Virutalization software of your choice (I prefer VMware)
- An Ubuntu 18.04 ISO, which can be downloaded from release.ubuntu.com, This version supports Python 2.7 by default, so there’s no need to install it separately
- Check if your processor supports virtualization. Search for your processor by its full name and model on AMD/Intel websites, and refer to the virtualization support section, which should indicate Yes for virtualization to work on your machine
- If your processor supports virtualization, enable VT-x for Intel or AMD-V for AMD in your BIOS settings
- For Windows 11, disable the hypervisor, Virtual Machine Platform, and Windows Hypervisor Platform
- To disable these features, go to Control Panel -> Programs -> Turn Windows Features On or Off, then uncheck them and save
- Don’t restart immediately, as you’ll also need to disable Core Isolation
- Search for “Core Isolation” in Windows settings, disable Memory Integrity, and restart your system
- Turn off Memory Integrity temporarily, as it may interfere with Cuckoo by disabling VT-x/AMD-V
- Once this is done, proceed to the installation steps
Installation
-
Install Ubuntu 18.04 using your virtualization software (I’m using VMware)
a. Specs:
i. CPU - 6 cores
ii. RAM - 12 GB (12288MB)
iii. Hard Disk - 80GB
iv. NAT(Vmware)/Bridged adapter(VirtualBox)
v. Enable virtualize Intel VT-x/EPT or AMD-V/RVI(VMware)/ Nested VT-x/AMD-v(virtualbox)
b. Start the installation tick the skip unattended installation box, during the installation do no install 3rd party updates and do not install any updates beforehand
-
After successfull installation of Ubuntu 18.04 follow these steps:
a. sudo apt update
b. sudo apt upgrade
c. sudo apt install nettools
d. sudo reboot
-
Installing updated python2.7:
a. sudo apt install python2.7 python-pip
b. sudo apt-get install python python-pip python-dev libffi-dev libssl-dev -y
c. sudo apt-get install python-virtualenv python-setuptools -y
-
Installing supporting libraries and packages:
a. sudo apt-get install libjpeg-dev zlib1g-dev swig -y
b. sudo apt-get install mongodb -y
c. sudo apt-get install postgresql libpq-dev -y
-
Installing VirtualBox5.2 (compatible with the cuckoo):
a. sudo apt install software-properties-common
b. wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
c. sudo add-apt-repository “deb [arch=amd64] http://download.virtualbox.org/virtualbox/debian bionic contrib”
d. sudo apt update
e. sudo apt install virtualbox-5.2
f. check version - virtualbox –version
-
Initialization:
a. sudo apt-get install tcpdump apparmor-utils -y
b. sudo groupadd pcap
c. sudo usermod -a -G pcap
//adding your user to group pcap (for using packetcapture) d. sudo chgrp pcap /usr/sbin/tcpdump
e. sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
f. getcap /usr/sbin/tcpdump
g. sudo aa-disable /usr/sbin/tcpdump
h. sudo apt-get install swig
i. sudo -H pip2 install m2crypto==0.31.0 //This is the specific version supported by python2.7
j. sudo usermod -a -G vboxusers
//adding your user to group vboxuser (to enable your user to use virutalization technology) -
Script to initialize the python virtual environment for installing cuckoo:
#!/usr/bin/env bash # NOTES: Run this script as: sudo -u <USERNAME> cuckoo-setup-virtualenv.sh # install virtualenv sudo apt-get update && sudo apt-get -y install virtualenv # install virtualenvwrapper sudo apt-get -y install virtualenvwrapper echo "source /usr/share/virtualenvwrapper/virtualenvwrapper.sh" >> ~/.bashrc # install pip for python3 sudo apt-get -y install python3-pip # turn on bash auto-complete for pip pip3 completion --bash >> ~/.bashrc # avoid installing with root pip3 install --user virtualenvwrapper echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc echo "source ~/.local/bin/virtualenvwrapper.sh" >> ~/.bashrc export WORKON_HOME=~/.virtualenvs echo "export WORKON_HOME=~/.virtualenvs" >> ~/.bashrc echo "export PIP_VIRTUALENV_BASE=~/.virtualenvs" >> ~/.bashrc
a. sudo chmod +x cuckoo-setup-virtualenv.sh
b. Run using the following command - “sudo -u
./cuckoo-setup-virtualenv.sh” c. source ~/.bashrc
d. mkvirtualenv -p python2.7 cuckoo-test //creates a virtual environment name cuckoo-test in python2.7
e. The following will not work if you are not working in a python venv
f. pip install -U pip setuptools
g. pip install -U cuckoo
-
Virtual machine setup: I downloaded a Windows 7 ISO for the sandbox VM due to its low resource requirements. You can opt for Windows 10 if desired and adjust specifications accordingly
The Windows ISO should be in the directory where you’ll perform the following operations
I have created a directory, opt and downloaded windows7 iso in it Once you have downloaded it in the respective directory. Follow the instructions given below, make modifications as per your need like changing win7 to win10 if using windows10:
a. sudo mkdir /mnt/win7
b. sudo chown
: /mnt/win7/ c. sudo mount -o ro,loop win7ultimate.iso /mnt/win7
d. sudo apt-get -y install build-essential libssl-dev libffi-dev python-dev genisoimage
e. sudo apt-get -y install zlib1g-dev libjpeg-dev
f. sudo apt-get -y install python-pip python-virtualenv python-setuptools swig
g. pip install -U vmcloak
h. vmcloak-vboxnet0
i. vmcloak init –verbose –win7x64 win7x64base –cpus 2 –ramsize 2048
j. vmcloak clone win7x64base win7x64cuckoo
k. vmcloak list deps
l. vmcloak install win7x64cuckoo ie11
m. vmcloak snapshot –count 1 win7x64cuckoo 192.168.56.101
n. vmcloak list vms
NOTE - Some steps may take a while – take a coffee break
-
Initializing and starting cuckoo:
a. cuckoo init
b. cuckoo community
c. sudo sysctl -w net.ipv4.conf.vboxnet0.forwarding=1
d. sudo sysctl -w net.ipv4.conf.your interface name.forwarding=1
e. sudo iptables -t nat -A POSTROUTING -o your interface name -s 192.168.56.0/24 -j MASQUERADE
f. sudo iptables -P FORWARD DROP
g. sudo iptables -A FORWARD -m state –state RELATED,ESTABLISHED -j ACCEPT
h. sudo iptables -A FORWARD -s 192.168.56.0/24 -j ACCEPT
i. while read -r vm ip; do cuckoo machine –add $vm $ip; done < <(vmcloak list vms)
-
modifications in conf (cd ~/.cuckoo/conf):
a. reporting.conf:
# Enable or disable the available reporting modules [on/off]. # If you add a custom reporting module to your Cuckoo setup, you have to add # a dedicated entry in this file, or it won't be executed. # You can also add additional options under the section of your module and # they will be available in your Python class. [feedback] # Automatically report errors that occurred during an analysis. Requires the # Cuckoo Feedback settings in cuckoo.conf to have been filled out properly. enabled = no [jsondump] enabled = yes indent = 4 calls = yes [singlefile] # Enable creation of report.html and/or report.pdf? enabled = no # Enable creation of report.html? html = no # Enable creation of report.pdf? pdf = no [misp] enabled = no url = apikey = # The various modes describe which information should be submitted to MISP, # separated by whitespace. Available modes: maldoc ipaddr hashes url. mode = maldoc ipaddr hashes url distribution = 0 analysis = 0 threat_level = 4 # The minimum Cuckoo score for a MISP event to be created min_malscore = 0 tag = Cuckoo upload_sample = no [mongodb] enabled = yes host = 127.0.0.1 port = 27017 db = cuckoo store_memdump = yes paginate = 100 # MongoDB authentication (optional). username = password = [elasticsearch] enabled = no # Comma-separated list of ElasticSearch hosts. Format is IP:PORT, if port is # missing the default port is used. # Example: hosts = 127.0.0.1:9200, 192.168.1.1:80 hosts = 127.0.0.1 # Increase default timeout from 10 seconds, required when indexing larger # analysis documents. timeout = 300 # Set to yes if we want to be able to search every API call instead of just # through the behavioral summary. calls = no # Index of this Cuckoo instance. If multiple Cuckoo instances connect to the # same ElasticSearch host then this index (in Moloch called "instance") should # be unique for each Cuckoo instance. index = cuckoo # Logging time pattern. This sets how elasticsearch creates indexes # by default it is yearly in most instances this will be sufficient # valid options: yearly, monthly, daily index_time_pattern = yearly # Cuckoo node name in Elasticsearch to identify reporting host. Can be useful # for automation and while referring back to correct Cuckoo host. cuckoo_node = [moloch] enabled = no # If the Moloch web interface is hosted on a different IP address than the # Cuckoo Web Interface then you'll want to override the IP address here. host = # If you wish to run Moloch in http (insecure) versus https (secure) mode, # set insecure to yes. insecure = no # Following are various configurable settings. When in use of a recent version # of Moloch there is no need to change any of the following settings as they # represent the defaults. moloch_capture = /data/moloch/bin/moloch-capture conf = /data/moloch/etc/config.ini instance = cuckoo [notification] # Notification module to inform external systems that analysis is finished. # You should consider keeping this as very last reporting module. enabled = no # External service URL where info will be POSTed. # example : https://my.example.host/some/destination/url url = # Cuckoo host identifier - can be hostname. # for example : my.cuckoo.host identifier = [mattermost] enabled = no # Mattermost webhook URL. # example : https://my.mattermost.host/hooks/yourveryrandomkey url = # Cuckoo host URL to make analysis ID clickable. # example : https://my.cuckoo.host/ myurl = # Username to show when posting message username = cuckoo # What kind of data to show apart from default. # Show virustotal hits. show_virustotal = no # Show matched cuckoo signatures. show_signatures = no # Show collected URL-s by signature "network_http". show_urls = no # Hide filename and create hash of it hash_filename = no # Hide URL and create hash of it hash_url = no
b. virtualbox.conf:
[virtualbox]
# Specify which VirtualBox mode you want to run your machines on.
# Can be "gui" or "headless". Please refer to VirtualBox's official
# documentation to understand the differences.
mode = headless
# Path to the local installation of the VBoxManage utility.
path = /usr/bin/VBoxManage
# If you are running Cuckoo on Mac OS X you have to change the path as follows:
# path = /Applications/VirtualBox.app/Contents/MacOS/VBoxManage
# Default network interface.
interface = vboxnet0
# Specify a comma-separated list of available machines to be used. For each
# specified ID you have to define a dedicated section containing the details
# on the respective machine. (E.g. cuckoo1,cuckoo2,cuckoo3)
machines = 192.168.56.1011
# If remote control is enabled in cuckoo.conf, specify a port range to use.
# Virtualbox will bind the VRDP interface to the first available port.
controlports = 5000-5000
[192.168.56.1011]
# Specify the label name of the current machine as specified in your
# VirtualBox configuration.
label = 192.168.56.1011
# Specify the operating system platform used by current machine
# [windows/darwin/linux].
platform = windows
# Specify the IP address of the current virtual machine. Make sure that the
# IP address is valid and that the host machine is able to reach it. If not,
# the analysis will fail.
ip = 192.168.56.101
# (Optional) Specify the snapshot name to use. If you do not specify a snapshot
# name, the VirtualBox MachineManager will use the current snapshot.
# Example (Snapshot1 is the snapshot name):
snapshot =
# (Optional) Specify the name of the network interface that should be used
# when dumping network traffic from this machine with tcpdump. If specified,
# overrides the default interface specified in auxiliary.conf
# Example (vboxnet0 is the interface name):
interface =
# (Optional) Specify the IP of the Result Server, as your virtual machine sees it.
# The Result Server will always bind to the address and port specified in cuckoo.conf,
# however you could set up your virtual network to use NAT/PAT, so you can specify here
# the IP address for the Result Server as your machine sees it. If you don't specify an
# address here, the machine will use the default value from cuckoo.conf.
# NOTE: if you set this option you have to set result server IP to 0.0.0.0 in cuckoo.conf.
# Example:
resultserver_ip = 192.168.56.1
# (Optional) Specify the port for the Result Server, as your virtual machine sees it.
# The Result Server will always bind to the address and port specified in cuckoo.conf,
# however you could set up your virtual network to use NAT/PAT, so you can specify here
# the port for the Result Server as your machine sees it. If you don't specify a port
# here, the machine will use the default value from cuckoo.conf.
# Example:
resultserver_port = 0
# (Optional) Set your own tags. These are comma separated and help to identify
# specific VMs. You can run samples on VMs with tag you require.
tags =
# Mostly unused for now. Please don't fill it out.
options =
# (Optional) Specify the OS profile to be used by volatility for this
# virtual machine. This will override the guest_profile variable in
# memory.conf which solves the problem of having multiple types of VMs
# and properly determining which profile to use.
osprofile =
[honeyd]
# For more information on this VM please refer to the "services" section of
# the conf/auxiliary.conf configuration file. This machine is a bit special
# in the way that its used as an additional VM for an analysis.
# *NOTE* that if this functionality is used, the VM should be registered in
# the "machines" list in the beginning of this file.
label = honeyd
platform = linux
ip = 192.168.56.102
# The tags should at least contain "service" and the name of this service.
# This way the services auxiliary module knows how to find this particular VM.
tags = service, honeyd
# Not all services actually have a Cuckoo Agent running in the VM, for those
# services one can specify the "noagent" option so Cuckoo will just wait until
# the end of the analysis instead of trying to connect to the non-existing
# Cuckoo Agent. We can't really intercept any inter-VM communication from the
# host / gateway so in order to dump traffic between VMs we have to use a
# different network dumping approach. For this machine we use the "nictrace"
# functionality from VirtualBox (which is basically their internal tcpdump)
# and thus properly dumps inter-VM traffic.
c. routing.conf: command to find you network interface for eth0:
ip a show eth0
or
ifconfig show eth0
or
ifconfig eth0
[routing]
# Default network routing mode if none is specified by the user.
# In none mode we don't do any special routing - the VM doesn't have any
# network access (this has been the default actually for quite a while) aside
# from the subnet it exists in.
# In internet mode by default all the VMs will be routed through the network
# interface configured below (the "dirty line").
# And in VPN mode by default the VMs will be routed through the VPN identified
# by the given name of the VPN (as per the VPNs listed in the vpn section).
# Note that just like enabling VPN configuration setting this option to
# anything other than "none" requires one to run utils/rooter.py as root next
# to the Cuckoo instance (as it's required for setting up the routing).
route = none
# Network interface that allows a VM to connect to the entire internet, the
# "dirty line" so to say. Note that, just like with the VPNs, this will allow
# malicious traffic through your network. So think twice before enabling it.
# (For example, to use eth0 as dirty line: "internet = eth0").
internet = ens33 #this interface should match with your network interface
# Routing table name/id for "dirty line" interface. If "dirty line" is
# also default gateway in the system you can leave "main" value. Otherwise add
# new routing table by adding "<id> <name>" line to /etc/iproute2/rt_tables
# (e.g., "200 eth0"). ID and name must be unique across the system (refer to
# /etc/iproute2/rt_tables for existing names and IDs).
rt_table = main
# To route traffic through multiple network interfaces Cuckoo uses
# Policy Routing with separate routing table for each output interface
# (VPN or "dirty line"). If this option is enabled Cuckoo on start will try
# to automatically initialise routing tables by copying routing entries from
# main routing table to the new routing tables. Depending on your network/vpn
# configuration this might not be sufficient. In such case you would need to
# initialise routing tables manually. Note that enabling this option won't
# affect main routing table.
auto_rt = yes
# The drop route basically drops any outgoing network (except for Cuckoo
# traffic) whereas the regular none route still allows a VM to access its own
# subnet (e.g., 192.168.56.1/24). It is disabled by default as it does require
# the optional rooter to run (unlike the none route, where literally nothing
# happens). One can either explicitly enable the drop route or if the rooter
# is enabled anyway, it is automatically enabled.
drop = no
[inetsim]
# Route a VM to your local InetSim setup (could in theory also be any other
# type of web service / etc).
enabled = no
server = 192.168.56.1
# Redirect TCP ports (should we also support UDP?). If specified, this should
# represent whitespace-separated src:dst pairs. E.g., "80:8080 443:8080" will
# redirect all 80/443 traffic to 8080 on the specified InetSim host.
ports =
[tor]
# Route a VM through Tor, requires a local setup of Tor (please refer to our
# documentation).
enabled = no
dnsport = 5353
proxyport = 9040
[vpn]
# Are VPNs enabled?
enabled = no
# Comma-separated list of the available VPNs.
vpns = vpn0
[vpn0]
# Name of this VPN. The name is represented by the filepath to the
# configuration file, e.g., cuckoo would represent /etc/openvpn/cuckoo.conf
# Note that you can't assign the names "none" and "internet" as those would
# conflict with the routing section in cuckoo.conf.
name = vpn0
# The description of this VPN which will be displayed in the web interface.
# Can be used to for example describe the country where this VPN ends up.
description = Spain, Europe
# The tun device hardcoded for this VPN. Each VPN *must* be configured to use
# a hardcoded/persistent tun device by explicitly adding the line "dev tunX"
# to its configuration (e.g., /etc/openvpn/vpn1.conf) where X in tunX is a
# unique number between 0 and your lucky number of choice.
interface = tun0
# Routing table name/id for this VPN. If table name is used it *must* be
# added to /etc/iproute2/rt_tables as "<id> <name>" line (e.g., "201 tun0").
# ID and name must be unique across the system (refer /etc/iproute2/rt_tables
# for existing names and IDs).
rt_table = tun0
-
Now that everything is initialized, the final step is to run Cuckoo. Ensure you are in the Python virtual environment (venv) named cuckoo-test:
a. Open 3 terminals and type “workon cuckoo-test” in each terminal to activate the venv
b. Once all three terminals are in venv, enter the following commands:
-
terminal 1 - cuckoo rooter –sudo –group
-
terminal 2 - cuckoo
-
terminal 3 -cuckoo web –host 127.0.0.1 –port 8080
-
After visiting the address on the specific port, you should be able to access cuckoo web interface
Now, you can submit hashes and malware samples for analysis