DEV Community

Cover image for VM Safety Configuration: A Developer's Guide
Rita Kairu
Rita Kairu

Posted on

VM Safety Configuration: A Developer's Guide

Virtual machines are essential tools for testing untrusted code, analyzing malware, or experimenting with potentially dangerous software. However, a VM is only as safe as its configuration. This guide provides practical examples for hardening your VM setup across popular platforms.

Why VM Safety Matters

A misconfigured VM can compromise your host system through:

  • Shared resources (folders, clipboard) that create data bridges
  • Network connections that allow lateral movement
  • VM escape vulnerabilities in shared services
  • Accidental credential exposure through auto-login features

1. Disable Shared Folders

Shared folders create a direct bridge between your host and guest systems. Disabling them prevents malware from accessing your real files.

VirtualBox

Via GUI:

1. Select VM → Settings → Shared Folders
2. Remove all shared folder entries
3. Uncheck "Auto-mount" if present
Enter fullscreen mode Exit fullscreen mode

Via Command Line:

# List all shared folders
VBoxManage showvminfo "YourVMName" | grep "Shared folders"

# Remove a specific shared folder
VBoxManage sharedfolder remove "YourVMName" --name "SharedFolderName"

# Remove all shared folders (run for each listed folder)
VBoxManage sharedfolder remove "YourVMName" --name "folder1"
VBoxManage sharedfolder remove "YourVMName" --name "folder2"
Enter fullscreen mode Exit fullscreen mode

VMware Workstation/Fusion

Via GUI:

1. VM → Settings → Options → Shared Folders
2. Select "Disabled"
Enter fullscreen mode Exit fullscreen mode

Via .vmx Configuration File:

# Locate your VM's .vmx file and add/modify:
isolation.tools.hgfs.disable = "TRUE"
sharedFolder.maxNum = "0"
Enter fullscreen mode Exit fullscreen mode

Hyper-V

Via PowerShell:

# Disable all shared folders for a VM
Get-VMIntegrationService -VMName "YourVMName" -Name "Guest Service Interface" | Disable-VMIntegrationService

# Verify it's disabled
Get-VMIntegrationService -VMName "YourVMName" | Select Name, Enabled
Enter fullscreen mode Exit fullscreen mode

2. Disable Clipboard Sharing

The clipboard can leak sensitive data between host and guest, including passwords from password managers.

VirtualBox

Via GUI:

Settings → General → Advanced
- Shared Clipboard: Disabled
- Drag'n'Drop: Disabled
Enter fullscreen mode Exit fullscreen mode

Via Command Line:

VBoxManage modifyvm "YourVMName" --clipboard-mode disabled
VBoxManage modifyvm "YourVMName" --draganddrop disabled
Enter fullscreen mode Exit fullscreen mode

VMware

Via .vmx File:

isolation.tools.copy.disable = "TRUE"
isolation.tools.paste.disable = "TRUE"
isolation.tools.dnd.disable = "TRUE"
Enter fullscreen mode Exit fullscreen mode

Verify Settings:

# On Linux/Mac
grep -i "isolation.tools" /path/to/your-vm.vmx

# On Windows PowerShell
Select-String -Path "C:\path\to\your-vm.vmx" -Pattern "isolation.tools"
Enter fullscreen mode Exit fullscreen mode

Hyper-V

# Disable clipboard integration
Disable-VMIntegrationService -VMName "YourVMName" -Name "Guest Service Interface"
Enter fullscreen mode Exit fullscreen mode

3. Network Isolation

Disconnecting the VM from the internet prevents malware from communicating with command-and-control servers or exfiltrating data.

VirtualBox - Host-Only Network

Setup Script:

#!/bin/bash
VM_NAME="SafetyVM"

# Create host-only network if it doesn't exist
VBoxManage hostonlyif create

# Configure the host-only adapter (usually vboxnet0)
VBoxManage hostonlyif ipconfig vboxnet0 --ip 192.168.56.1 --netmask 255.255.255.0

# Attach VM to host-only network
VBoxManage modifyvm "$VM_NAME" --nic1 hostonly
VBoxManage modifyvm "$VM_NAME" --hostonlyadapter1 vboxnet0

# Disable DHCP server on the host-only network (optional)
VBoxManage dhcpserver modify --netname HostInterfaceNetworking-vboxnet0 --disable

echo "VM configured for host-only networking"
Enter fullscreen mode Exit fullscreen mode

Complete Disconnect:

# Disable all network adapters
VBoxManage modifyvm "YourVMName" --nic1 none
VBoxManage modifyvm "YourVMName" --nic2 none
Enter fullscreen mode Exit fullscreen mode

VMware - Custom Network

Via GUI:

1. VM → Settings → Network Adapter
2. Select "Host-only" or "Custom" (then choose a host-only network)
Enter fullscreen mode Exit fullscreen mode

Via .vmx File:

ethernet0.connectionType = "hostonly"
# Or completely disable:
ethernet0.present = "FALSE"
Enter fullscreen mode Exit fullscreen mode

PowerShell Script for VMware:

# Set to host-only
& "C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" `
  -T ws setNetworkAdapter "C:\path\to\vm.vmx" 0 hostonly

# Or disable entirely
& "C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" `
  -T ws deleteNetworkAdapter "C:\path\to\vm.vmx" 0
Enter fullscreen mode Exit fullscreen mode

Hyper-V - Internal Network

PowerShell Configuration:

# Create an internal switch (isolated from host)
New-VMSwitch -Name "IsolatedSwitch" -SwitchType Internal

# Connect VM to isolated switch
Get-VM "YourVMName" | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName "IsolatedSwitch"

# Or completely disconnect
Get-VM "YourVMName" | Get-VMNetworkAdapter | Disconnect-VMNetworkAdapter
Enter fullscreen mode Exit fullscreen mode

4. Snapshot Management

Snapshots allow you to instantly restore a clean state, critical when testing potentially harmful software.

VirtualBox

Create Baseline Snapshot:

#!/bin/bash
VM_NAME="SafetyVM"
SNAPSHOT_NAME="Clean_Baseline_$(date +%Y%m%d)"

# Ensure VM is powered off
VBoxManage controlvm "$VM_NAME" poweroff 2>/dev/null
sleep 5

# Create snapshot
VBoxManage snapshot "$VM_NAME" take "$SNAPSHOT_NAME" \
  --description "Clean state before testing - $(date)"

echo "Snapshot created: $SNAPSHOT_NAME"

# List all snapshots
VBoxManage snapshot "$VM_NAME" list
Enter fullscreen mode Exit fullscreen mode

Restore Snapshot:

#!/bin/bash
VM_NAME="SafetyVM"
SNAPSHOT_NAME="Clean_Baseline_20240101"

# Power off VM
VBoxManage controlvm "$VM_NAME" poweroff 2>/dev/null
sleep 5

# Restore snapshot
VBoxManage snapshot "$VM_NAME" restore "$SNAPSHOT_NAME"

echo "VM restored to: $SNAPSHOT_NAME"
Enter fullscreen mode Exit fullscreen mode

Automated Test Cycle:

#!/bin/bash
VM_NAME="SafetyVM"
CLEAN_SNAPSHOT="Clean_Baseline"

function test_sample() {
    # Restore clean state
    VBoxManage controlvm "$VM_NAME" poweroff 2>/dev/null
    sleep 3
    VBoxManage snapshot "$VM_NAME" restore "$CLEAN_SNAPSHOT"

    # Start VM
    VBoxManage startvm "$VM_NAME" --type headless
    sleep 30

    # Your testing logic here
    # ...

    # Power off and restore again
    VBoxManage controlvm "$VM_NAME" poweroff
    sleep 3
    VBoxManage snapshot "$VM_NAME" restore "$CLEAN_SNAPSHOT"
}

# Test multiple samples
for sample in /path/to/samples/*; do
    echo "Testing: $sample"
    test_sample
done
Enter fullscreen mode Exit fullscreen mode

VMware

PowerShell Script:

param(
    [string]$VMXPath = "C:\VMs\SafetyVM\SafetyVM.vmx",
    [string]$SnapshotName = "Clean_Baseline"
)

$vmrun = "C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe"

# Create snapshot
& $vmrun -T ws snapshot $VMXPath $SnapshotName

# Restore snapshot
& $vmrun -T ws revertToSnapshot $VMXPath $SnapshotName

# List snapshots
& $vmrun -T ws listSnapshots $VMXPath
Enter fullscreen mode Exit fullscreen mode

Hyper-V

Checkpoint Management:

# Create checkpoint
$VMName = "SafetyVM"
$CheckpointName = "Clean_Baseline_$(Get-Date -Format 'yyyyMMdd_HHmmss')"

Checkpoint-VM -Name $VMName -SnapshotName $CheckpointName

# Restore checkpoint
Restore-VMCheckpoint -Name $CheckpointName -VMName $VMName -Confirm:$false

# List checkpoints
Get-VMCheckpoint -VMName $VMName | Select-Object Name, CreationTime

# Automated testing function
function Test-InVM {
    param(
        [string]$VMName,
        [string]$CleanCheckpoint
    )

    # Restore clean state
    Stop-VM -Name $VMName -Force -ErrorAction SilentlyContinue
    Start-Sleep -Seconds 5
    Restore-VMCheckpoint -Name $CleanCheckpoint -VMName $VMName -Confirm:$false

    # Start VM
    Start-VM -Name $VMName
    Start-Sleep -Seconds 30

    # Your testing here

    # Restore again
    Stop-VM -Name $VMName -Force
    Restore-VMCheckpoint -Name $CleanCheckpoint -VMName $VMName -Confirm:$false
}
Enter fullscreen mode Exit fullscreen mode

5. Keep Personal Data Out

Prevent credential leakage through configuration and monitoring.

Disable Credential Managers

Windows VM:

# Disable Windows Credential Manager
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" /v "AllowDefCredentialsWhenNTLMOnly" /t REG_DWORD /d 0 /f

# Disable saved passwords in browsers (example for Chrome)
reg add "HKCU\Software\Policies\Google\Chrome" /v "PasswordManagerEnabled" /t REG_DWORD /d 0 /f

# Clear stored credentials
cmdkey /list | findstr "Target" | for /f "tokens=2 delims= " %i in ('more') do cmdkey /delete:%i
Enter fullscreen mode Exit fullscreen mode

Linux VM:

#!/bin/bash
# Remove saved credentials
rm -rf ~/.gnome2/keyrings/*
rm -rf ~/.local/share/keyrings/*

# Clear browser profiles
rm -rf ~/.mozilla/firefox/*.default*/key*.db
rm -rf ~/.config/google-chrome/Default/Login\ Data

# Clear bash history
history -c
cat /dev/null > ~/.bash_history
Enter fullscreen mode Exit fullscreen mode

Browser Configuration Script

Python Script for Fresh Browser:

#!/usr/bin/env python3
import os
import shutil
import platform

def sanitize_browsers():
    """Remove browser profiles and credentials"""

    system = platform.system()
    home = os.path.expanduser("~")

    paths_to_clear = []

    if system == "Windows":
        paths_to_clear = [
            os.path.join(os.getenv("APPDATA"), "Mozilla", "Firefox", "Profiles"),
            os.path.join(os.getenv("LOCALAPPDATA"), "Google", "Chrome", "User Data"),
            os.path.join(os.getenv("LOCALAPPDATA"), "Microsoft", "Edge", "User Data"),
        ]
    elif system == "Linux":
        paths_to_clear = [
            os.path.join(home, ".mozilla", "firefox"),
            os.path.join(home, ".config", "google-chrome"),
            os.path.join(home, ".config", "chromium"),
        ]

    for path in paths_to_clear:
        if os.path.exists(path):
            try:
                shutil.rmtree(path)
                print(f"Cleared: {path}")
            except Exception as e:
                print(f"Could not clear {path}: {e}")

if __name__ == "__main__":
    response = input("This will delete browser profiles. Continue? (yes/no): ")
    if response.lower() == "yes":
        sanitize_browsers()
        print("Browser data cleared. Fresh profiles will be created on next launch.")
Enter fullscreen mode Exit fullscreen mode

Network Monitoring

Simple Traffic Monitor:

#!/usr/bin/env python3
"""
Monitor for suspicious outbound connections from VM
Run on host machine
"""
import subprocess
import re
from datetime import datetime

VM_IP_RANGE = "192.168.56.0/24"  # Adjust for your host-only network

def monitor_connections():
    """Watch for any internet-bound traffic from VM"""

    print(f"Monitoring VM network range: {VM_IP_RANGE}")
    print("Press Ctrl+C to stop\n")

    try:
        # Linux/Mac
        cmd = f"tcpdump -n 'src net {VM_IP_RANGE} and not dst net {VM_IP_RANGE}'"
        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, 
                                   stderr=subprocess.PIPE, text=True)

        for line in process.stdout:
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            print(f"[{timestamp}] ALERT: {line.strip()}")

    except KeyboardInterrupt:
        print("\nMonitoring stopped")
    except Exception as e:
        print(f"Error: {e}")
        print("Note: This script requires tcpdump and root privileges")

if __name__ == "__main__":
    monitor_connections()
Enter fullscreen mode Exit fullscreen mode

Complete VM Setup Script

All-in-One VirtualBox Configuration:

#!/bin/bash
# Complete VM safety setup for VirtualBox

VM_NAME="SafetyVM"
SNAPSHOT_NAME="Clean_Baseline"

echo "=== VM Safety Configuration ==="
echo "VM Name: $VM_NAME"
echo

# 1. Disable sharing
echo "[1/5] Disabling shared folders and clipboard..."
VBoxManage modifyvm "$VM_NAME" --clipboard-mode disabled
VBoxManage modifyvm "$VM_NAME" --draganddrop disabled

# Remove all shared folders
for folder in $(VBoxManage showvminfo "$VM_NAME" --machinereadable | grep SharedFolderName | cut -d'"' -f2); do
    VBoxManage sharedfolder remove "$VM_NAME" --name "$folder"
done

# 2. Isolate network
echo "[2/5] Configuring network isolation..."
VBoxManage modifyvm "$VM_NAME" --nic1 hostonly
VBoxManage modifyvm "$VM_NAME" --hostonlyadapter1 vboxnet0

# 3. Disable unnecessary features
echo "[3/5] Disabling unnecessary features..."
VBoxManage modifyvm "$VM_NAME" --usb off
VBoxManage modifyvm "$VM_NAME" --audio none

# 4. Create snapshot
echo "[4/5] Creating clean snapshot..."
VBoxManage controlvm "$VM_NAME" poweroff 2>/dev/null
sleep 5
VBoxManage snapshot "$VM_NAME" take "$SNAPSHOT_NAME" --description "Safe baseline configuration"

# 5. Verify configuration
echo "[5/5] Verifying configuration..."
echo
echo "=== Configuration Summary ==="
VBoxManage showvminfo "$VM_NAME" --machinereadable | grep -E "(clipboard|draganddrop|nic1|SharedFolder)" 
echo
echo "Snapshots:"
VBoxManage snapshot "$VM_NAME" list
echo
echo "✓ VM safety configuration complete"
echo "⚠ Remember: Never log into real accounts inside this VM"
Enter fullscreen mode Exit fullscreen mode

Best Practices Checklist

Before testing any untrusted code:

  • [ ] All shared folders removed
  • [ ] Clipboard sharing disabled
  • [ ] Network set to host-only or disconnected
  • [ ] Clean snapshot created
  • [ ] Browser profiles cleared
  • [ ] No personal accounts logged in
  • [ ] Password managers disabled
  • [ ] VM host system is up-to-date
  • [ ] Antivirus on host is active
  • [ ] Backup of important host data exists

Conclusion

VM safety is about defense in depth. Each configuration layer adds protection against malware escaping the sandbox or stealing your data. Always assume the code you're testing is hostile, and never let convenience compromise security.

The few minutes spent configuring these settings properly can prevent hours of incident response—or worse, permanent data loss.

Top comments (0)