aboutsummaryrefslogtreecommitdiff
path: root/unix/virt/dos.sh
diff options
context:
space:
mode:
Diffstat (limited to 'unix/virt/dos.sh')
-rwxr-xr-xunix/virt/dos.sh998
1 files changed, 0 insertions, 998 deletions
diff --git a/unix/virt/dos.sh b/unix/virt/dos.sh
deleted file mode 100755
index 0b50c4b..0000000
--- a/unix/virt/dos.sh
+++ /dev/null
@@ -1,998 +0,0 @@
-#!/usr/bin/env bash
-
-# Set variables
-HOST_DIR="virt"
-VM_NAME="dos"
-VM_SIZE="80G" # Disk size in GB
-VM_RAM="8G" # RAM size
-VM_CPU="6" # Number of virtual CPUs
-CORES=$((VM_CPU / 2))
-THREADS_PER_CORE=2
-SOCKETS=1
-
-VM_DIR="$HOST_DIR/machines"
-IMAGE_DIR="$HOST_DIR/images"
-WIN_ISO_DIR="${IMAGE_DIR}/${VM_NAME}" # Directory for Windows ISO
-VM_DIR="$WIN_ISO_DIR"
-SOCKET_DIR="$VM_DIR"
-SHARED_DIR="${HOST_DIR}/shared"
-FIRMWARE_DIR="${HOST_DIR}/firmware"
-TPM_DIR="$WIN_ISO_DIR"
-TPM_SOCKET="${WIN_ISO_DIR}/${VM_NAME}.swtpm-sock"
-GUEST_PORT=22
-QCOW2_FILE="${VM_DIR}/${VM_NAME}.qcow2"
-RAW_FILE="${VM_DIR}/${VM_NAME}.raw"
-
-# Anti-detection: Generate realistic hardware identifiers
-REAL_MAC="00:1A:2B:3C:4D:5E" # Example Dell MAC - replace with your choice
-REAL_SERIAL="$(openssl rand -hex 8 | tr '[:lower:]' '[:upper:]')"
-REAL_UUID="$(uuidgen)"
-REAL_VENDOR="Dell Inc."
-REAL_PRODUCT="OptiPlex 7090"
-REAL_VERSION="01"
-REAL_FAMILY="OptiPlex"
-
-# Try to find an available host port starting from 22220
-HOST_PORT_START=22220
-HOST_PORT_END=22300
-
-for ((port = HOST_PORT_START; port <= HOST_PORT_END; port++)); do
- if ! ss -tuln | grep -q ":$port\b"; then
- HOST_PORT=$port
- echo "Using available port: $HOST_PORT"
- break
- fi
-done
-
-if [[ $port -gt $HOST_PORT_END ]]; then
- echo "Error: No available ports found between $HOST_PORT_START and $HOST_PORT_END" >&2
- exit 1
-fi
-
-# Set SMP configuration
-SMP_CONFIG="cores=$CORES,threads=$THREADS_PER_CORE,sockets=$SOCKETS"
-
-# Create necessary directories
-mkdir -p "${HOME}/${HOST_DIR}"
-mkdir -p "$IMAGE_DIR" "$SHARED_DIR" "$FIRMWARE_DIR"
-mkdir -p "$WIN_ISO_DIR" "$VM_DIR"
-mkdir -p "${WIN_ISO_DIR}/unattended"
-
-# Define ISO paths and URLs
-ISO_VIRTIO="${WIN_ISO_DIR}/virtio-win.iso"
-ISO_UNATTENDED="${WIN_ISO_DIR}/unattended.iso"
-
-# Find Windows ISO with flexible pattern matching
-find_windows_iso() {
- # Check if directory exists
- if [[ ! -d "$WIN_ISO_DIR" ]]; then
- mkdir -p "$WIN_ISO_DIR"
- fi
-
- # Try to find any Windows ISO using case-insensitive patterns
- local found_iso
- found_iso=$(find "$WIN_ISO_DIR" -maxdepth 1 -type f \( \
- -iname "*win11*.iso" -o \
- -iname "*win*11*.iso" -o \
- -iname "Win*.iso" -o \
- -iname "Win11*.iso" -o \
- -iname "Win*11*.iso" -o \
- -iname "*windows*11*.iso" -o \
- -iname "*windows11*.iso" \
- \) -exec stat --format="%Y %n" {} \; | sort -n | tail -n 1 | cut -d' ' -f2-)
-
- if [[ -n "$found_iso" && -f "$found_iso" ]]; then
- echo "$found_iso"
- return 0
- fi
-
- return 1
-}
-
-# Define download URLs
-VIRTIO_ISO_URL="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso"
-
-# Print colored messages
-print_info() { echo -e "\033[1;34m[INFO]\033[0m $1" >&2; }
-print_success() { echo -e "\033[1;32m[SUCCESS]\033[0m $1" >&2; }
-print_warning() { echo -e "\033[1;33m[WARNING]\033[0m $1" >&2; }
-print_error() { echo -e "\033[1;31m[ERROR]\033[0m $1" >&2; }
-
-# Helper: verify file integrity
-verify_file() {
- local file="$1"
- local expected_sha256="$2"
-
- if [[ ! -f "$file" ]]; then
- return 1
- fi
-
- if [[ -n "$expected_sha256" ]]; then
- local actual_sha256
- actual_sha256=$(sha256sum "$file" | cut -d' ' -f1)
- if [[ "$actual_sha256" != "$expected_sha256" ]]; then
- print_error "File integrity check failed for $file"
- return 1
- fi
- fi
-
- return 0
-}
-
-# Helper: download file with verification
-download_file() {
- local url="$1"
- local dest="$2"
- local expected_sha256="$3"
- local allow_failure="$4"
-
- # Check if file exists and is valid
- if [[ -f "$dest" ]]; then
- if verify_file "$dest" "$expected_sha256"; then
- print_info "File $dest already exists and verified."
- return 0
- else
- print_warning "File $dest exists but failed verification. Redownloading..."
- rm -f "$dest"
- fi
- fi
-
- print_info "Downloading $url..."
- if ! curl -fL --progress-bar -o "$dest" "$url"; then
- print_error "Failed to download $url."
- if [[ "$allow_failure" != "true" ]]; then
- return 1
- fi
- else
- # Verify downloaded file
- if ! verify_file "$dest" "$expected_sha256"; then
- print_error "Downloaded file failed verification"
- rm -f "$dest"
- return 1
- fi
- print_success "Successfully downloaded and verified $dest"
- fi
-
- return 0
-}
-
-# Handle curl errors
-handle_curl_error() {
- local exit_code=$1
- case $exit_code in
- 6) print_error "Couldn't resolve host" ;;
- 7) print_error "Failed to connect to host" ;;
- 22) print_error "HTTP page not retrieved (404, etc.)" ;;
- 28) print_error "Operation timeout" ;;
- *) print_error "Curl failed with exit code $exit_code" ;;
- esac
-}
-
-# Download Windows 11 ISO using Microsoft's API
-download_windows_iso() {
- local windows_version="11" # Default to Windows 11
- local language="English (United States)" # Default language
-
- # Parse arguments if provided
- if [[ -n "$1" ]]; then
- windows_version="$1"
- fi
-
- print_info "Attempting to download Windows $windows_version ISO from Microsoft..."
-
- # Set required variables
- local user_agent="Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0"
- local session_id="$(uuidgen)"
- local profile="606624d44113"
- local url="https://www.microsoft.com/en-us/software-download/windows$windows_version"
-
- # Add ISO to URL for Windows 10
- case "$windows_version" in
- 10) url="${url}ISO" ;;
- esac
-
- # Step 1: Get download page HTML
- print_info "Fetching download page: $url"
- local iso_download_page_html
- iso_download_page_html="$(curl --disable --silent --user-agent "$user_agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url")" || {
- handle_curl_error $?
- print_error "Failed to fetch the download page. Please download Windows $windows_version ISO manually from $url"
- return 1
- }
-
- # Step 2: Extract Product Edition ID
- print_info "Getting Product Edition ID..."
- local product_edition_id
- product_edition_id="$(echo "$iso_download_page_html" | grep -Eo '<option value="[0-9]+">Windows' | cut -d '"' -f 2 | head -n 1 | tr -cd '0-9' | head -c 16)"
-
- if [[ -z "$product_edition_id" ]]; then
- print_error "Failed to extract product edition ID."
- print_error "Please download Windows $windows_version ISO manually from $url"
- return 1
- fi
-
- print_success "Product Edition ID: $product_edition_id"
-
- # Step 3: Register session ID
- print_info "Registering session ID: $session_id"
- curl --disable --silent --output /dev/null --user-agent "$user_agent" \
- --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 \
- --http1.1 -- "https://vlscppe.microsoft.com/tags?org_id=y6jn8c31&session_id=$session_id" || {
- print_error "Failed to register session ID."
- return 1
- }
-
- # Step 4: Get language SKU ID
- print_info "Getting language SKU ID..."
- local language_skuid_table_json
- language_skuid_table_json="$(curl --disable -s --fail --max-filesize 100K --proto =https --tlsv1.2 --http1.1 \
- "https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=${profile}&ProductEditionId=${product_edition_id}&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=${session_id}")" || {
- handle_curl_error $?
- print_error "Failed to get language SKU information."
- return 1
- }
-
- # Extract SKU ID for selected language
- local sku_id
-
- # Try with jq if available (more reliable)
- if command -v jq >/dev/null 2>&1; then
- sku_id="$(echo "$language_skuid_table_json" | jq -r '.Skus[] | select(.LocalizedLanguage=="'"$language"'" or .Language=="'"$language"'").Id')"
- else
- # Fallback to grep/cut if jq not available
- sku_id="$(echo "$language_skuid_table_json" | grep -o '"Id":"[^"]*","Language":"'"$language"'"' | cut -d'"' -f4)"
-
- if [[ -z "$sku_id" ]]; then
- # Try alternative extraction method
- sku_id="$(echo "$language_skuid_table_json" | grep -o '"LocalizedLanguage":"'"$language"'","Id":"[^"]*"' | cut -d'"' -f6)"
- fi
- fi
-
- if [[ -z "$sku_id" ]]; then
- print_error "Failed to extract SKU ID for $language."
- return 1
- fi
-
- print_success "SKU ID: $sku_id"
-
- # Step 5: Get ISO download link
- print_info "Getting ISO download link..."
- local iso_download_link_json
- iso_download_link_json="$(curl --disable -s --fail --referer "$url" \
- "https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=${profile}&productEditionId=undefined&SKU=${sku_id}&friendlyFileName=undefined&Locale=en-US&sessionID=${session_id}")"
-
- local failed=0
-
- if [[ -z "$iso_download_link_json" ]]; then
- print_error "Microsoft servers gave an empty response to the download request."
- failed=1
- fi
-
- if echo "$iso_download_link_json" | grep -q "Sentinel marked this request as rejected."; then
- print_error "Microsoft blocked the automated download request based on your IP address."
- failed=1
- fi
-
- if [[ "$failed" -eq 1 ]]; then
- print_warning "Please manually download the Windows $windows_version ISO using a web browser from: $url"
- print_warning "Save the downloaded ISO to: $WIN_ISO_DIR"
- return 1
- fi
-
- # Extract 64-bit ISO download URL
- local iso_download_link
-
- # Try with jq if available
- if command -v jq >/dev/null 2>&1; then
- iso_download_link="$(echo "$iso_download_link_json" | jq -r '.ProductDownloadOptions[].Uri' | grep x64 | head -n 1)"
- else
- # Fallback to grep/cut if jq not available
- iso_download_link="$(echo "$iso_download_link_json" | grep -o '"Uri":"[^"]*x64[^"]*"' | cut -d'"' -f4 | head -n 1)"
- fi
-
- if [[ -z "$iso_download_link" ]]; then
- print_error "Failed to extract the download link from Microsoft's response."
- print_warning "Manually download the Windows $windows_version ISO using a web browser from: $url"
- return 1
- fi
-
- print_success "Got download link: ${iso_download_link%%\?*}"
-
- # Extract filename from URL
- local file_name="$(echo "$iso_download_link" | cut -d'?' -f1 | rev | cut -d'/' -f1 | rev)"
-
- # If filename couldn't be extracted, use default
- if [[ -z "$file_name" || "$file_name" == "$iso_download_link" ]]; then
- file_name="windows-$windows_version.iso"
- fi
-
- # Step 6: Download the ISO
- print_info "Downloading Windows $windows_version ISO to $WIN_ISO_DIR/$file_name. This may take a while..."
-
- # Direct curl download
- curl --disable --progress-bar --fail --location --proto '=https' --tlsv1.2 --http1.1 \
- --retry 3 --retry-delay 3 --connect-timeout 30 \
- --output "$WIN_ISO_DIR/$file_name" "$iso_download_link" || {
- handle_curl_error $?
- return 1
- }
-
- if [[ $? -ne 0 ]]; then
- print_error "Failed to download the Windows $windows_version ISO."
- return 1
- fi
-
- print_success "Successfully downloaded Windows $windows_version ISO to $WIN_ISO_DIR/$file_name"
-
- # Return the downloaded filename so calling code can use it
- echo "$file_name"
- return 0
-}
-
-# Create unattended installation ISO with proper Windows 11 bypass
-create_unattended_iso() {
- print_info "Creating unattended installation ISO..."
-
- # Create enhanced autounattend.xml with Windows 11 TPM/Secure Boot bypass
- if [ ! -f "$WIN_ISO_DIR/unattended/autounattend.xml" ]; then
- print_info "Creating enhanced autounattend.xml with Windows 11 bypass..."
- mkdir -p "$WIN_ISO_DIR/unattended"
- cat >"$WIN_ISO_DIR/unattended/autounattend.xml" <<'EOF'
-<?xml version="1.0" encoding="utf-8"?>
-<unattend xmlns="urn:schemas-microsoft-com:unattend">
- <settings pass="windowsPE">
- <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <SetupUILanguage>
- <UILanguage>en-US</UILanguage>
- </SetupUILanguage>
- <InputLocale>en-US</InputLocale>
- <SystemLocale>en-US</SystemLocale>
- <UILanguage>en-US</UILanguage>
- <UILanguageFallback>en-US</UILanguageFallback>
- <UserLocale>en-US</UserLocale>
- </component>
- <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <DiskConfiguration>
- <Disk wcm:action="add">
- <CreatePartitions>
- <CreatePartition wcm:action="add">
- <Order>1</Order>
- <Type>Primary</Type>
- <Size>100</Size>
- </CreatePartition>
- <CreatePartition wcm:action="add">
- <Order>2</Order>
- <Type>EFI</Type>
- <Size>100</Size>
- </CreatePartition>
- <CreatePartition wcm:action="add">
- <Order>3</Order>
- <Type>MSR</Type>
- <Size>16</Size>
- </CreatePartition>
- <CreatePartition wcm:action="add">
- <Order>4</Order>
- <Type>Primary</Type>
- <Extend>true</Extend>
- </CreatePartition>
- </CreatePartitions>
- <ModifyPartitions>
- <ModifyPartition wcm:action="add">
- <Order>1</Order>
- <PartitionID>1</PartitionID>
- <Label>WINRE</Label>
- <Format>NTFS</Format>
- <TypeID>DE94BBA4-06D1-4D40-A16A-BFD50179D6AC</TypeID>
- </ModifyPartition>
- <ModifyPartition wcm:action="add">
- <Order>2</Order>
- <PartitionID>2</PartitionID>
- <Label>System</Label>
- <Format>FAT32</Format>
- </ModifyPartition>
- <ModifyPartition wcm:action="add">
- <Order>3</Order>
- <PartitionID>3</PartitionID>
- </ModifyPartition>
- <ModifyPartition wcm:action="add">
- <Order>4</Order>
- <PartitionID>4</PartitionID>
- <Label>Windows</Label>
- <Format>NTFS</Format>
- </ModifyPartition>
- </ModifyPartitions>
- <DiskID>0</DiskID>
- <WillWipeDisk>true</WillWipeDisk>
- </Disk>
- </DiskConfiguration>
- <ImageInstall>
- <OSImage>
- <InstallTo>
- <DiskID>0</DiskID>
- <PartitionID>4</PartitionID>
- </InstallTo>
- <InstallToAvailablePartition>false</InstallToAvailablePartition>
- <WillShowUI>OnError</WillShowUI>
- <InstallFrom>
- <MetaData wcm:action="add">
- <Key>/IMAGE/INDEX</Key>
- <Value>6</Value>
- </MetaData>
- </InstallFrom>
- </OSImage>
- </ImageInstall>
- <UserData>
- <AcceptEula>true</AcceptEula>
- <FullName>Windows User</FullName>
- <Organization>Windows</Organization>
- <ProductKey>
- <WillShowUI>Never</WillShowUI>
- </ProductKey>
- </UserData>
- <!-- Windows 11 Requirements Bypass -->
- <RunSynchronous>
- <RunSynchronousCommand wcm:action="add">
- <Order>1</Order>
- <Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1 /f</Path>
- </RunSynchronousCommand>
- <RunSynchronousCommand wcm:action="add">
- <Order>2</Order>
- <Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1 /f</Path>
- </RunSynchronousCommand>
- <RunSynchronousCommand wcm:action="add">
- <Order>3</Order>
- <Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassRAMCheck /t REG_DWORD /d 1 /f</Path>
- </RunSynchronousCommand>
- <RunSynchronousCommand wcm:action="add">
- <Order>4</Order>
- <Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassStorageCheck /t REG_DWORD /d 1 /f</Path>
- </RunSynchronousCommand>
- <RunSynchronousCommand wcm:action="add">
- <Order>5</Order>
- <Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassCPUCheck /t REG_DWORD /d 1 /f</Path>
- </RunSynchronousCommand>
- </RunSynchronous>
- <EnableFirewall>false</EnableFirewall>
- <EnableNetwork>true</EnableNetwork>
- </component>
- </settings>
- <settings pass="specialize">
- <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <InputLocale>en-US</InputLocale>
- <SystemLocale>en-US</SystemLocale>
- <UILanguage>en-US</UILanguage>
- <UILanguageFallback>en-US</UILanguageFallback>
- <UserLocale>en-US</UserLocale>
- </component>
- <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <ComputerName>DESKTOP-PC</ComputerName>
- <TimeZone>UTC</TimeZone>
- </component>
- <component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <SkipAutoActivation>true</SkipAutoActivation>
- </component>
- </settings>
- <settings pass="oobeSystem">
- <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <AutoLogon>
- <Password>
- <Value>password</Value>
- <PlainText>true</PlainText>
- </Password>
- <LogonCount>1</LogonCount>
- <Username>Administrator</Username>
- <Enabled>true</Enabled>
- </AutoLogon>
- <OOBE>
- <HideEULAPage>true</HideEULAPage>
- <HideLocalAccountScreen>true</HideLocalAccountScreen>
- <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
- <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
- <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
- <NetworkLocation>Home</NetworkLocation>
- <ProtectYourPC>1</ProtectYourPC>
- <SkipMachineOOBE>true</SkipMachineOOBE>
- <SkipUserOOBE>true</SkipUserOOBE>
- </OOBE>
- <UserAccounts>
- <AdministratorPassword>
- <Value>password</Value>
- <PlainText>true</PlainText>
- </AdministratorPassword>
- <LocalAccounts>
- <LocalAccount wcm:action="add">
- <Password>
- <Value>password</Value>
- <PlainText>true</PlainText>
- </Password>
- <Name>User</Name>
- <Group>Administrators</Group>
- <DisplayName>User</DisplayName>
- </LocalAccount>
- </LocalAccounts>
- </UserAccounts>
- <!-- Additional Windows 11 bypass commands -->
- <FirstLogonCommands>
- <SynchronousCommand wcm:action="add">
- <Order>1</Order>
- <CommandLine>reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU /v NoAutoUpdate /t REG_DWORD /d 1 /f</CommandLine>
- </SynchronousCommand>
- <SynchronousCommand wcm:action="add">
- <Order>2</Order>
- <CommandLine>reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f</CommandLine>
- </SynchronousCommand>
- <SynchronousCommand wcm:action="add">
- <Order>3</Order>
- <CommandLine>powershell -Command "Set-ExecutionPolicy Unrestricted -Force"</CommandLine>
- </SynchronousCommand>
- </FirstLogonCommands>
- </component>
- </settings>
-</unattend>
-EOF
- fi
-
- # Create the unattended ISO
- if command -v genisoimage >/dev/null 2>&1; then
- print_info "Creating unattended ISO using genisoimage..."
- genisoimage -J -r -o "$WIN_ISO_DIR/unattended.iso" "$WIN_ISO_DIR/unattended" 2>/dev/null
- return $?
- elif command -v mkisofs >/dev/null 2>&1; then
- print_info "Creating unattended ISO using mkisofs..."
- mkisofs -J -r -o "$WIN_ISO_DIR/unattended.iso" "$WIN_ISO_DIR/unattended" 2>/dev/null
- return $?
- elif command -v xorriso >/dev/null 2>&1; then
- print_info "Creating unattended ISO using xorriso..."
- xorriso -as genisoimage -J -r -o "$WIN_ISO_DIR/unattended.iso" "$WIN_ISO_DIR/unattended" 2>/dev/null
- return $?
- else
- print_warning "No ISO creation tool found (genisoimage, mkisofs, or xorriso)"
- print_warning "Installing genisoimage..."
- if command -v apt-get >/dev/null 2>&1; then
- sudo apt-get update && sudo apt-get install -y genisoimage
- elif command -v yum >/dev/null 2>&1; then
- sudo yum install -y genisoimage
- elif command -v pacman >/dev/null 2>&1; then
- sudo pacman -S --noconfirm cdrtools
- fi
-
- # Try again after installation
- if command -v genisoimage >/dev/null 2>&1; then
- print_info "Creating unattended ISO using newly installed genisoimage..."
- genisoimage -J -r -o "$WIN_ISO_DIR/unattended.iso" "$WIN_ISO_DIR/unattended" 2>/dev/null
- return $?
- else
- print_error "Failed to install ISO creation tools"
- return 1
- fi
- fi
-}
-
-# Download or locate essential files
-prepare_files() {
- # Find Windows ISO
- WINDOWS_ISO_PATH=$(find_windows_iso | tail -n 1 | xargs)
- local iso_found=false
-
- # Check if we found a valid ISO
- if [[ -n "$WINDOWS_ISO_PATH" && -f "$WINDOWS_ISO_PATH" ]]; then
- print_success "Using Windows ISO: $WINDOWS_ISO_PATH"
- iso_found=true
- else
- print_warning "Windows ISO not found, attempting to download..."
- if download_windows_iso; then
- # Check again after download attempt
- WINDOWS_ISO_PATH=$(find_windows_iso | tail -n 1 | xargs)
- if [[ -n "$WINDOWS_ISO_PATH" && -f "$WINDOWS_ISO_PATH" ]]; then
- print_success "Using downloaded Windows ISO: $WINDOWS_ISO_PATH"
- iso_found=true
- fi
- fi
- fi
-
- # If we still don't have an ISO, exit
- if [[ "$iso_found" != "true" ]]; then
- print_error "Could not find or download Windows ISO"
- print_info "Please place your Windows ISO file in: $WIN_ISO_DIR"
- exit 1
- fi
-
- # Download VirtIO drivers if missing (optional for stealth mode)
- if [[ ! -f "$ISO_VIRTIO" ]]; then
- print_info "VirtIO drivers ISO not found, downloading (for fallback)..."
- download_file "$VIRTIO_ISO_URL" "$ISO_VIRTIO" "" "true"
- else
- print_success "VirtIO drivers ISO already exists: $ISO_VIRTIO"
- fi
-
- # Create unattended ISO if it doesn't exist
- if [[ ! -f "$ISO_UNATTENDED" ]]; then
- create_unattended_iso
- if [[ $? -eq 0 ]]; then
- print_success "Created unattended ISO: $ISO_UNATTENDED"
- else
- print_error "Failed to create unattended ISO"
- exit 1
- fi
- else
- print_success "Unattended ISO already exists: $ISO_UNATTENDED"
- fi
-}
-
-# Locate OVMF firmware files
-locate_ovmf() {
- OVMF_DIRS=(
- "/usr/share/OVMF"
- "/usr/share/qemu"
- "/usr/lib/qemu"
- "/usr/share/edk2"
- "/usr/lib/edk2"
- "/usr/share/edk2/ovmf"
- "/usr/share/edk2-ovmf"
- "/usr/share/qemu/edk2-x86_64-code.fd"
- )
-
- OVMF_CODE=""
- OVMF_VARS=""
-
- for dir in "${OVMF_DIRS[@]}"; do
- if [[ -f "$dir" ]]; then
- # Handle direct file paths
- if [[ "$dir" == *"code.fd" ]]; then
- OVMF_CODE="$dir"
- OVMF_VARS="$(dirname "$dir")/edk2-x86_64-vars.fd"
- fi
- elif [[ -d "$dir" ]]; then
- # Handle directories
- [[ -z "$OVMF_CODE" ]] && OVMF_CODE=$(find "$dir" -type f -name "OVMF_CODE.fd" -o -name "edk2-x86_64-code.fd" 2>/dev/null | head -n 1)
- [[ -z "$OVMF_VARS" ]] && OVMF_VARS=$(find "$dir" -type f -name "OVMF_VARS.fd" -o -name "edk2-x86_64-vars.fd" 2>/dev/null | head -n 1)
- fi
- [[ -n "$OVMF_CODE" && -n "$OVMF_VARS" ]] && break
- done
-
- # Try package-specific locations
- if [[ -z "$OVMF_CODE" || -z "$OVMF_VARS" ]]; then
- # Ubuntu/Debian locations
- [[ -z "$OVMF_CODE" ]] && OVMF_CODE="/usr/share/OVMF/OVMF_CODE_4M.fd"
- [[ -z "$OVMF_VARS" && -f "/usr/share/OVMF/OVMF_VARS_4M.fd" ]] && OVMF_VARS="/usr/share/OVMF/OVMF_VARS_4M.fd"
-
- # Arch Linux locations
- [[ -z "$OVMF_CODE" ]] && OVMF_CODE="/usr/share/edk2-ovmf/x64/OVMF_CODE.fd"
- [[ -z "$OVMF_VARS" && -f "/usr/share/edk2-ovmf/x64/OVMF_VARS.fd" ]] && OVMF_VARS="/usr/share/edk2-ovmf/x64/OVMF_VARS.fd"
- fi
-
- # Ensure a writable copy of OVMF_VARS.fd
- local original_ovmf_vars="$OVMF_VARS"
- OVMF_VARS="$FIRMWARE_DIR/OVMF_VARS.fd"
-
- if [[ ! -f "$OVMF_VARS" && -f "$original_ovmf_vars" ]]; then
- print_info "Copying OVMF_VARS.fd to $OVMF_VARS"
- cp "$original_ovmf_vars" "$OVMF_VARS" 2>/dev/null || {
- print_error "Failed to copy OVMF_VARS.fd!"
- print_info "Trying to install OVMF firmware..."
-
- # Try to install OVMF
- if command -v apt-get >/dev/null 2>&1; then
- sudo apt-get update && sudo apt-get install -y ovmf
- elif command -v yum >/dev/null 2>&1; then
- sudo yum install -y edk2-ovmf
- elif command -v pacman >/dev/null 2>&1; then
- sudo pacman -S --noconfirm edk2-ovmf
- fi
-
- # Try to locate again after installation
- locate_ovmf
- return
- }
- fi
-
- # Check if required files exist
- if [[ -z "$OVMF_CODE" || ! -f "$OVMF_CODE" ]]; then
- print_error "OVMF_CODE.fd not found!"
- print_info "Please install OVMF firmware package:"
- print_info " Ubuntu/Debian: sudo apt install ovmf"
- print_info " RHEL/CentOS: sudo yum install edk2-ovmf"
- print_info " Arch: sudo pacman -S edk2-ovmf"
- exit 1
- fi
- if [[ ! -f "$OVMF_VARS" ]]; then
- print_error "OVMF_VARS.fd not found or could not be copied!"
- exit 1
- fi
-
- print_success "Found OVMF firmware: $OVMF_CODE"
- print_success "Using OVMF vars: $OVMF_VARS"
-}
-
-# Create VM disk image
-create_disk() {
- # Check if the qcow2 image file exists; if not, create it
- if [[ ! -f "$QCOW2_FILE" ]]; then
- print_info "Creating $QCOW2_FILE with a size of $VM_SIZE"
- qemu-img create -f qcow2 "$QCOW2_FILE" "$VM_SIZE" || {
- print_error "Failed to create qcow2 image!"
- exit 1
- }
- print_success "Created VM disk image: $QCOW2_FILE"
- else
- print_success "VM disk image already exists: $QCOW2_FILE"
- fi
-}
-
-# Helper function to convert QCOW2 to RAW for stealth
-convert_to_raw() {
- if [[ -f "$QCOW2_FILE" && ! -f "$RAW_FILE" ]]; then
- print_info "Converting QCOW2 to RAW format for stealth..."
- qemu-img convert -f qcow2 -O raw "$QCOW2_FILE" "$RAW_FILE" || {
- print_error "Failed to convert to RAW format"
- exit 1
- }
- print_success "Successfully converted to RAW format: $RAW_FILE"
- elif [[ ! -f "$RAW_FILE" ]]; then
- print_info "Creating RAW disk image..."
- qemu-img create -f raw "$RAW_FILE" "$VM_SIZE" || {
- print_error "Failed to create RAW disk image"
- exit 1
- }
- print_success "Created RAW disk image: $RAW_FILE"
- else
- print_success "RAW disk image already exists: $RAW_FILE"
- fi
-}
-
-# Check dependencies
-check_dependencies() {
- local missing_deps=()
-
- # Check for essential tools
- command -v qemu-system-x86_64 >/dev/null 2>&1 || missing_deps+=("qemu-system-x86_64")
- command -v swtpm >/dev/null 2>&1 || missing_deps+=("swtpm")
- command -v curl >/dev/null 2>&1 || missing_deps+=("curl")
- command -v uuidgen >/dev/null 2>&1 || missing_deps+=("uuidgen")
- command -v openssl >/dev/null 2>&1 || missing_deps+=("openssl")
-
- if [[ ${#missing_deps[@]} -gt 0 ]]; then
- print_error "Missing required dependencies: ${missing_deps[*]}"
- print_info "Please install them using your package manager:"
- print_info " Ubuntu/Debian: sudo apt install qemu-system-x86 swtpm curl uuid-runtime openssl"
- print_info " RHEL/CentOS: sudo yum install qemu-kvm swtpm curl util-linux openssl"
- print_info " Arch: sudo pacman -S qemu swtpm curl util-linux openssl"
- exit 1
- fi
-}
-
-start_vm() {
- # Verify that we have a Windows ISO
- if [[ -z "$WINDOWS_ISO_PATH" || ! -f "$WINDOWS_ISO_PATH" ]]; then
- print_error "Windows ISO file not found. Cannot start VM."
- print_info "Please download Windows 11 ISO and save it to: $WIN_ISO_DIR"
- exit 1
- fi
-
- # Anti-detection: Generate realistic hardware identifiers
- REAL_MAC="00:1A:79:$(openssl rand -hex 3 | sed 's/../&:/g; s/:$//')" # Dell OUI
- REAL_SERIAL="$(openssl rand -hex 8 | tr '[:lower:]' '[:upper:]')"
- REAL_UUID="$(uuidgen)"
- REAL_VENDOR="Dell Inc."
- REAL_PRODUCT="OptiPlex 7090"
- REAL_VERSION="01"
- REAL_FAMILY="OptiPlex"
-
- # Stop any existing swtpm process for this VM
- if [[ -f "$TPM_SOCKET" ]]; then
- print_info "Cleaning up existing TPM socket..."
- rm -f "$TPM_SOCKET"
- fi
-
- # Start swtpm (TPM emulator)
- print_info "Starting TPM emulator..."
- /sbin/swtpm socket \
- --ctrl type=unixio,path="$TPM_SOCKET" \
- --terminate \
- --tpmstate dir="$TPM_DIR" \
- --tpm2 &
-
- # Give swtpm a moment to create the socket
- sleep 1
-
- # Verify TPM socket exists
- if [[ ! -S "$TPM_SOCKET" ]]; then
- print_error "TPM socket not created: $TPM_SOCKET"
- exit 1
- fi
-
- print_info "Starting stealth Windows 11 VM..."
- print_info "Using Windows ISO: $WINDOWS_ISO_PATH"
- print_info "VM will boot from unattended installation ISO"
- print_info "Default login: Username=User, Password=password"
- print_info "Anti-detection measures enabled"
-
- # Build qemu arguments in an array for safety and readability
- QEMU_ARGS=(
- # Basic VM configuration
- -name "$REAL_PRODUCT",process="$VM_NAME"
- -machine q35,hpet=off,smm=on,vmport=off,accel=kvm
-
- # Global optimizations
- -global kvm-pit.lost_tick_policy=discard
- -global ICH9-LPC.disable_s3=1
-
- # CPU configuration (stealth)
- -cpu host,-hypervisor,+invtsc,+ssse3,l3-cache=on,migratable=no
- -smp "$SMP_CONFIG"
- -m "$VM_RAM"
-
- # SMBIOS spoofing for anti-detection
- -smbios type=0,vendor="$REAL_VENDOR",version="$REAL_VERSION",date="03/15/2023"
- -smbios type=1,manufacturer="$REAL_VENDOR",product="$REAL_PRODUCT",version="$REAL_VERSION",serial="$REAL_SERIAL",uuid="$REAL_UUID",family="$REAL_FAMILY"
- -smbios type=2,manufacturer="$REAL_VENDOR",product="0NK70N",version="A00",serial="$REAL_SERIAL"
- -smbios type=3,manufacturer="$REAL_VENDOR",version="$REAL_VERSION",serial="$REAL_SERIAL"
- -smbios type=4,manufacturer="Intel(R) Corporation",version="11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz"
-
- # Process management
- -pidfile "$VM_DIR/$VM_NAME.pid"
- -rtc base=localtime,clock=host,driftfix=slew
-
- # Display and graphics
- -vga qxl
- -display sdl
-
- # Boot configuration
- -boot menu=on,splash-time=0,order=d,reboot-timeout=5000
-
- # Random number generator
- -object rng-random,id=rng0,filename=/dev/urandom
- -device i82801b11-bridge,id=pci.1
-
- # usb
- -device usb-ehci,id=usb
- -device usb-kbd,bus=usb.0
- -device usb-tablet,bus=usb.0
- -k en-us
-
- # audio (pipewire)
- -audiodev pipewire,id=audio0
- -device AC97,audiodev=audio0
-
- # Network (realistic NIC with stealth MAC)
- -device rtl8139,netdev=nic,mac="$REAL_MAC"
- -netdev user,hostname="$VM_NAME",hostfwd=tcp::"$HOST_PORT"-:"$GUEST_PORT",smb="$SHARED_DIR",id=nic
-
- # UEFI firmware
- -global driver=cfi.pflash01,property=secure,value=on
- -drive if=pflash,format=raw,unit=0,file="$OVMF_CODE",readonly=on
- -drive if=pflash,format=raw,unit=1,file="$OVMF_VARS"
-
- # Main storage (AHCI for compatibility)
- -device ahci,id=ahci
- -drive if=none,id=disk0,format=raw,file="$RAW_FILE",cache=writeback
- -device ide-hd,bus=ahci.0,drive=disk0
-
- # CD-ROM drives (Windows ISO + Unattended)
- -drive media=cdrom,index=0,file="$WINDOWS_ISO_PATH",if=ide
- -drive media=cdrom,index=1,file="$ISO_UNATTENDED",if=ide
-
- # TPM 2.0
- -chardev socket,id=chrtpm,path="$TPM_SOCKET"
- -tpmdev emulator,id=tpm0,chardev=chrtpm
- -device tpm-tis,tpmdev=tpm0
-
- # Monitoring and management sockets
- -monitor unix:"$SOCKET_DIR/$VM_NAME-monitor.socket",server,nowait
- -serial unix:"$SOCKET_DIR/$VM_NAME-serial.socket",server,nowait
- )
-
- # Add VirtIO ISO if it exists (as fallback)
- if [[ -f "$ISO_VIRTIO" ]]; then
- QEMU_ARGS+=(-drive media=cdrom,index=2,file="$ISO_VIRTIO",if=ide,readonly=on)
- fi
-
- print_info "Starting QEMU with stealth configuration..."
- print_info "Monitor socket: $SOCKET_DIR/$VM_NAME-monitor.socket"
- print_info "Serial socket: $SOCKET_DIR/$VM_NAME-serial.socket"
- print_info "SSH port forwarding: localhost:$HOST_PORT -> VM:$GUEST_PORT"
-
- # Execute qemu
- exec qemu-system-x86_64 "${QEMU_ARGS[@]}"
-
-}
-
-# Helper function to convert QCOW2 to RAW for stealth
-convert_to_raw() {
- if [[ -f "$QCOW2_FILE" && ! -f "$RAW_FILE" ]]; then
- print_info "Converting QCOW2 to RAW format for stealth..."
- qemu-img convert -f qcow2 -O raw "$QCOW2_FILE" "$RAW_FILE"
- if [[ $? -eq 0 ]]; then
- print_success "Successfully converted to RAW format"
- else
- print_error "Failed to convert to RAW format"
- exit 1
- fi
- elif [[ ! -f "$RAW_FILE" ]]; then
- print_info "Creating RAW disk image..."
- qemu-img create -f raw "$RAW_FILE" "$VM_SIZE"
- fi
-}
-
-# Anti-detection validation commands
-show_validation_commands() {
- cat << 'EOF'
-=== VM DETECTION VALIDATION COMMANDS ===
-
-Run these commands inside Windows to verify stealth:
-
-# PowerShell - Check hardware info:
-Get-WmiObject -Class Win32_ComputerSystem | Select-Object Manufacturer, Model, TotalPhysicalMemory
-Get-WmiObject -Class Win32_BIOS | Select-Object Manufacturer, Version, SerialNumber
-Get-WmiObject -Class Win32_BaseBoard | Select-Object Manufacturer, Product, SerialNumber
-Get-WmiObject -Class Win32_Processor | Select-Object Name, Manufacturer, MaxClockSpeed
-
-# Check for hypervisor presence:
-Get-WmiObject -Class Win32_ComputerSystem | Select-Object HypervisorPresent
-bcdedit /enum | findstr hypervisorlaunchtype
-
-# Registry checks for VM artifacts:
-reg query "HKLM\HARDWARE\DESCRIPTION\System" /v SystemBiosVersion
-reg query "HKLM\HARDWARE\DESCRIPTION\System\BIOS" /v SystemManufacturer
-reg query "HKLM\SYSTEM\CurrentControlSet\Services" | findstr -i "vbox\|vmware\|qemu\|virtio"
-
-# Check network adapter:
-Get-WmiObject -Class Win32_NetworkAdapter | Where-Object {$_.NetConnectionStatus -eq 2} | Select-Object Name, MACAddress, Manufacturer
-
-# Check PCI devices for VM signatures:
-Get-WmiObject -Class Win32_PnPEntity | Where-Object {$_.Name -match "VirtIO|QEMU|VMware|VirtualBox|Hyper-V"} | Select-Object Name, DeviceID
-
-# Check running services:
-Get-Service | Where-Object {$_.Name -match "vbox|vmware|qemu|virtio|spice"}
-
-# Check for VM-specific processes:
-Get-Process | Where-Object {$_.ProcessName -match "vbox|vmware|qemu|virtio"}
-
-# Additional checks:
-systeminfo | findstr /C:"System Manufacturer" /C:"System Model" /C:"BIOS Version"
-wmic computersystem get manufacturer,model,name,systemtype
-
-EOF
-}
-
-# Cleanup function
-cleanup() {
- print_info "Cleaning up..."
-
- # Kill swtpm if running
- if [[ -f "$TPM_SOCKET" ]]; then
- pkill -f "swtpm.*$TPM_SOCKET" 2>/dev/null || true
- rm -f "$TPM_SOCKET" 2>/dev/null || true
- fi
-
- # Remove PID file
- if [[ -f "$VM_DIR/$VM_NAME.pid" ]]; then
- rm -f "$VM_DIR/$VM_NAME.pid" 2>/dev/null || true
- fi
-}
-
-# Trap cleanup on exit
-trap cleanup EXIT
-
-# Main execution function
-main() {
- print_info "=== Windows 11 Stealth VM Setup ==="
- print_info "VM Name: $VM_NAME"
- print_info "VM Size: $VM_SIZE"
- print_info "VM RAM: $VM_RAM"
- print_info "VM CPUs: $VM_CPU"
- print_info "Host Port: $HOST_PORT"
-
- check_dependencies
- prepare_files
- locate_ovmf
- create_disk
- convert_to_raw
- show_validation_commands
-
- print_success "Setup complete! Starting VM..."
- start_vm
-}
-
-# Run main function
-main "$@"