Malware Analysis Lab Set-up

Build a Malware Analysis Lab.

Introduction

You will need two virtual machines to perform proper malware analysis. The first machine will be Windows 11 Enterprise Evaluation to collect host-based artifacts. We’ll install FlareVM by Mandiant on top of the Windows installation. The second machine will be REMNux to collect network-based indicators. Both machines run on an internal network adapter, allowing inter-VM communication while protecting your host network from malware detonation. This guide uses VirtualBox.

Purpose of this lab: Hands-on malware analysis requires isolated, controlled environments. This lab provides a safe sandbox for detonating samples, analyzing behavior, and capturing network/host artifacts without risking production systems or alerting C2 servers.

This guide does NOT include VirtualBox installation. Please refer to Oracle documentation.


Links

https://academy.tcm-sec.com/p/practical-malware-analysis-triage
https://www.virtualbox.org/wiki/Downloads
https://www.microsoft.com/en-us/evalcenter/evaluate-windows-11-enterprise
https://docs.remnux.org/install-distro/get-virtual-appliance


Process

Windows 11 Enterprise

Note: Steps may vary based on host machine


Download a copy of the Windows 11 Enterprise Evaluation Edition from the Microsoft website.


Fill out the form with information. They don’t verify the information.


Choose the appropriate ISO version and save it to your system.


Click New at the top of the Virtualbox interface.


Choose a machine name with flare or some other identifiable name. Choose the Windows 11 ISO that was just downloaded. De-select unattended installation. Click Next.


Set the memory to 4GB and keep the CPUs to 2. Set the Disk to a size greater that 60GB or the FlareVM installer will complain. I like to use 128GB.


Click Finish to end the set-up process.


Boot up the virtual machine that was just created.


Click Next on the Windows set-up screen.


Click Install Now to start the intallation process.


Accept the license terms and then click Next.


Click to choose the Custom install option.


Click the New and then click the Apply button.


Choose your Region.


Select the Keyboard. Skip the second layout.


Choose a username and click Next.


Choose a password. Click Next. Re-enter the password.


Choose three security questions and their answers.


Turn off all the tracking type of options. Select Not Now for the Cortana option.


Wait for it to finish installing and repeat the network option from above to turn the networking back on. For the pop-up box click on all the continues and Coninue Without Data until it goes away.


Create an image of the base install as starting point if anything goes wrong.


Install Google Chrome. This is optional.

https://www.google.com/intl/en_au/chrome/


Insert the Guest Additions cd into the virtual machine.


Double-click on the amd64 version of the tools. Follow all of the prompts and restart the machine.


Research the FlareVM GitHub. This will have the procedures for pre-installation and installation.

https://github.com/mandiant/flare-vm


Disable in Tamper Protection in Windows Security. Disable all of the other security protections.

https://www.maketecheasier.com/permanently-disable-windows-defender-windows-10/


Disable Windows Defenders in the Group Policy Objects (GPO) so it is permanently disabled.

  1. Open `gpedit.msc` in the run box.
  2. Navigate to `Computer Configuration > Administrative Templates > Windows Components > Microsoft Defender AntiVirus`.
  3. Enable the `Turn off Microsoft Defender Antivirus` option.
  4. Navigate to `Computer Configuration > Administrative Templates > Network > Windows Defender Firewall > Domain Profile`.
  5. Disable the `Windows Defender Firewall: Protect all network connections` option.
  6. Navigate to `Computer Configuration > Administrative Templates > Network > Windows Defender Firewall > Standard Profile`.
  7. Disable the `Windows Defender Firewall: Protect all network connections` option.


Create another snapshot. This will give a restore point incase anything goes wrong during the FlareVM installation.


Follow the steps listed in the GitHub FLARE-VM installation.

  • Open a PowerShell terminal. Choose Run as Administrator.
  • Download the installer.ps1 installation script to the Desktop.
  • PowerShell
    
    (New-Object net.webclient).DownloadFile('https://raw.githubusercontent.com/mandiant/flare-vm/main/install.ps1',"$([Environment]::GetFolderPath("Desktop"))\install.ps1")
    
      
  • Ublock the script. Microsoft has security regarding ransomly downloaded scripts.
  • PowerShell
    
    Unblock-File .\install.ps1
    
      
  • Set the execution policy to unrestricted to enable script execution.
  • PowerShell
    
    .\install.ps1
    
      
  • Execute the install script. Pass a config file if you have one.
  • PowerShell
    
    .\install.ps1 -customConfig "https://raw.githubusercontent.com/mandiant/flare-vm/main/config.xml"
    
      


Check the options and click Continue.


Enter the user password.


Check the install folders and click Continue.


Check the program install programs. Click Install.


Eventually, the installation will complete and produce a summary text. Feel free to review it.


Sysinternals might also need to be downloaded. Feel free to download it if you need it.

https://learn.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite


Process Hacker 2/System Informer might also need to be download. Feel free to download it if you need it.

https://sourceforge.net/projects/processhacker/


Create a post install snapshot.


Power down the virtual machine. Time to set-up REMNux.


REMNux Linux

Download a copy of the ISO from the REMNux Official Website.


Choose Import on the Virtualbox interface.


Choose the REMNux .ova file that was just downloaded. Click Finish.


Boot up the new virtual machine.


Create a base install snapshot.


Power down both machines and prepare to fix the networking.


Networking


Open the settings menu. From the settings menu switch to the Network tab. Check all of the Adapter tabs — there should only be one adapter enabled. For the enabled adapter, change the “Attached to:” drop-down to Internal Network. Change the “Name:” to the same name for both machines. Expand the Advanced section. Update the “Promiscuous Mode:.” For the purposes of this lab, choose Allow VMs.


The choice between “Allow VMs” and “Allow All” depends on your analysis needs:

Setting When it works When you need more
Allow VMs Basic lab exercises, communication between Windows → REMnux Cannot see unsolicited frames, raw scanning, or C2 attempts outside the lab VM IPs
Allow All Full visibility of all traffic on the internal network Complete malware network analysis, IDS-style capture, forensic lab work


REMNux

Boot up the machine. Update the 01-netcfg.yaml file to specify the ip address.

bash

remnux@remnux:~$ cat /etc/netplan/01-netcfg.yaml 
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      addresses:
        - 10.0.0.3/24

  


Apply the new netplan.

bash

remnux@remnux:~$ sudo netplan apply

  


Check the IP address to see if we can see the new IP address.

bash

remnux@remnux:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:cf:20:be brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.3/24 brd 10.0.0.255 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fecf:20be/64 scope link 
       valid_lft forever preferred_lft forever

  

Windows

Open View network connections in the control panel so we can set up the DNS properties to reach out to the REMNux machine.


Right-click the Ethernet connection and click Properties.


Highlight IPv4 and click Properties.


Choose the radio button for Use the following IP address:. Set the IP address and subnet mask. Set the Default gateway: to the REMNux IP address. Select the radio button for Use the following DNS server addresses:. Set the preferred DNS to the REMNux box.

Test Network Connections

From the REMNux box, ping the IP address for the Windows machine. This should succeed. Ping Google and 8.8.8.8. This should fail to ensure that we are fully isolated.

bash

remnux@remnux:~$ ping -c 1 10.0.0.4
PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.
64 bytes from 10.0.0.4: icmp_seq=1 ttl=128 time=0.360 ms

--- 10.0.0.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.360/0.360/0.360/0.000 ms
remnux@remnux:~$ ping -c 1 www.google.com
ping: www.google.com: Temporary failure in name resolution
remnux@remnux:~$ ping -c 1 8.8.8.8
ping: connect: Network is unreachable

  


From the Windows box, ping the IP address for the REMNux machine. This should succeed. Ping Google and 8.8.8.8. This should fail to ensure that we are fully isolated.

cmder

C:\Users\win
λ ping -n 1 10.0.0.3

Pinging 10.0.0.3 with 32 bytes of data:
Reply from 10.0.0.3: bytes=32 time<1ms TTL=64

Ping statistics for 10.0.0.3:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

C:\Users\win
λ ping -n 1 www.google.com
Ping request could not find host www.google.com. Please check the name and try again.

C:\Users\win
λ ping -n 1 8.8.8.8

Pinging 8.8.8.8 with 32 bytes of data:
Request timed out.

Ping statistics for 8.8.8.8:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

  

INETSim

On the REMNux machine, make a copy of inetsim.conf in case anything goes wrong.

bash

remnux@remnux:~$ sudo cp /etc/inetsim/inetsim.conf /etc/inetsim/inetsim.conf.orig

  


In the config file, uncomment the start_service dns option so the machine can act as DNS.

bash

# ident, syslog, dummy_tcp, dummy_udp, smtps, pop3s,
# ftps, irc, https
#
start_service dns
start_service http
start_service https
start_service smtp
start_service smtps
start_service pop3
start_service pop3s
start_service ftp
start_service ftps

  


Uncomment the service_bind_address and set the IP address to accept any connection with 0.0.0.0.

bash

#########################################
# service_bind_address
#
# IP address to bind services to
#
# Syntax: service_bind_address <IP address>
#
# Default: 127.0.0.1
#
service_bind_address    0.0.0.0

  


Uncomment the dns_default_ip and set the IP address of the REMNux.

bash

#########################################
# dns_default_ip
#
# Default IP address to return with DNS replies
#
# Syntax: dns_default_ip <IP address>
#
# Default: 127.0.0.1
#
dns_default_ip          10.0.0.3

  


Try to run INetSim. Notice there is something already running on port 53. Run lsof to identify services running on port 53.

bash

remnux@remnux:~$ sudo inetsim
INetSim 1.3.2 (2020-05-19) by Matthias Eckert & Thomas Hungenberg
Using log directory:      /var/log/inetsim/
Using data directory:     /var/lib/inetsim/
Using report directory:   /var/log/inetsim/report/
Using configuration file: /etc/inetsim/inetsim.conf
Parsing configuration file.
Configuration file parsed successfully.
=== INetSim main process started (PID 1824) ===
Session ID:     1824
Listening on:   0.0.0.0
Real Date/Time: 2026-01-01 11:42:37
Fake Date/Time: 2026-01-01 11:42:37 (Delta: 0 seconds)
 Forking services...
Couldn't create UDP socket: Address already in use at /usr/share/perl5/INetSim/DNS.pm line 36.
  * dns_53_tcp_udp - started (PID 1828)
  * pop3s_995_tcp - started (PID 1834)
  * ftp_21_tcp - started (PID 1835)
  * pop3_110_tcp - started (PID 1833)
  * smtps_465_tcp - started (PID 1832)
  * ftps_990_tcp - started (PID 1836)
  * smtp_25_tcp - started (PID 1831)
  * http_80_tcp - started (PID 1829)
  * https_443_tcp - started (PID 1830)
 done.
Simulation running.
^C  * ftps_990_tcp - stopped (PID 1836)
  * ftp_21_tcp - stopped (PID 1835)
  * pop3s_995_tcp - stopped (PID 1834)
  * pop3_110_tcp - stopped (PID 1833)
  * smtps_465_tcp - stopped (PID 1832)
  * smtp_25_tcp - stopped (PID 1831)
  * https_443_tcp - stopped (PID 1830)
  * http_80_tcp - stopped (PID 1829)
  * dns_53_tcp_udp - stopped (PID 1828)
Simulation stopped.
=== INetSim main process stopped (PID 1824) ===
.
remnux@remnux:~$ sudo lsof -i :53
COMMAND   PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd-r 347 systemd-resolve   12u  IPv4  16686      0t0  UDP localhost:domain 
systemd-r 347 systemd-resolve   13u  IPv4  16687      0t0  TCP localhost:domain (LISTEN)

  


Ubuntu’s systemd-resolved service runs a DNS stub resolver on port 53, which conflicts with INetSim’s DNS simulation. Stop and disable it.

bash

remnux@remnux:~$ sudo systemctl disable systemd-resolve^C
remnux@remnux:~$ sudo systemctl stop systemd-resolved
remnux@remnux:~$ sudo systemctl disable systemd-resolved
Removed /etc/systemd/system/dbus-org.freedesktop.resolve1.service.
Removed /etc/systemd/system/multi-user.target.wants/systemd-resolved.service.

  


Run INETSim.

bash

remnux@remnux:~$ sudo inetsim
INetSim 1.3.2 (2020-05-19) by Matthias Eckert & Thomas Hungenberg
Using log directory:      /var/log/inetsim/
Using data directory:     /var/lib/inetsim/
Using report directory:   /var/log/inetsim/report/
Using configuration file: /etc/inetsim/inetsim.conf
Parsing configuration file.
Configuration file parsed successfully.
=== INetSim main process started (PID 1905) ===
Session ID:     1905
Listening on:   0.0.0.0
Real Date/Time: 2026-01-01 11:49:58
Fake Date/Time: 2026-01-01 11:49:58 (Delta: 0 seconds)
 Forking services...
  * dns_53_tcp_udp - started (PID 1909)
  * smtps_465_tcp - started (PID 1913)
  * https_443_tcp - started (PID 1911)
  * smtp_25_tcp - started (PID 1912)
  * pop3s_995_tcp - started (PID 1915)
  * ftp_21_tcp - started (PID 1916)
  * ftps_990_tcp - started (PID 1917)
  * pop3_110_tcp - started (PID 1914)
  * http_80_tcp - started (PID 1910)
 done.
Simulation running.

  


On the Windows machine, check the INETSim to ensure that it is serving.


On the Windows machine, create one more predetonation snapshot.


Now, let’s get this party started with Bang!