-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOrchestrator_VMware.ps1
More file actions
167 lines (133 loc) · 5.65 KB
/
Orchestrator_VMware.ps1
File metadata and controls
167 lines (133 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
$vmxPath = "C:\VMs\FlareVM\FlareVM.vmx" # Path to the .vmx file of the VM
$snapshotName = "baseline"
$shareRoot = "C:\LabShare"
$malwareDir = Join-Path $shareRoot "Malware"
$reportsDir = Join-Path $shareRoot "Reports"
$vmrun = "C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe"
# User credentials for guest OS
$guestUser = "FlareVM"
$guestPass = "password"
# Initial checks
if (-not (Test-Path $vmrun)) {
Write-Error "[INFO] vmrun not found at: $vmrun"
exit 1
}
if (-not (Test-Path $vmxPath)) {
Write-Error "[INFO] VMX file not found at: $vmxPath"
exit 1
}
if (-not (Test-Path $malwareDir)) {
Write-Error "[INFO] Malware folder does not exist: $malwareDir"
exit 1
}
if (-not (Test-Path $reportsDir)) {
New-Item -ItemType Directory -Path $reportsDir | Out-Null
}
Write-Host "[INFO] Starting analysis loop (VMware)..."
while ($true) {
$pending = Get-ChildItem -Path $malwareDir -File
if ($pending.Count -eq 0) {
Write-Host "[INFO] No samples left in $malwareDir. Experiment finished."
break
}
Write-Host "[INFO] $($pending.Count) samples pending."
# Check if the VM is currently running
$runningList = & $vmrun list
$isRunning = $runningList -match [regex]::Escape($vmxPath)
if ($isRunning) {
Write-Host "[INFO] VM is running, powering off..."
& $vmrun stop $vmxPath hard
Start-Sleep -Seconds 5
}
Write-Host "[INFO] VM is powered off. Proceeding with snapshot restore."
# 1) Restore snapshot
Write-Host "[INFO] Restoring snapshot '$snapshotName'..."
& $vmrun revertToSnapshot $vmxPath $snapshotName
# 2) Start the VM (nogui = headless mode)
Write-Host "[INFO] Starting the VM..."
& $vmrun start $vmxPath nogui
# 3) Wait for the guest OS to boot fully (VMware Tools must be running)
Write-Host "[INFO] Waiting for guest OS to fully boot (VMware Tools)..."
$bootTimeout = 300
$bootElapsed = 0
do {
Start-Sleep -Seconds 5
$bootElapsed += 5
# Try to check if VMware Tools is responding by listing processes
$toolsReady = $false
try {
$procCheck = & $vmrun listProcessesInGuest $vmxPath -gu $guestUser -gp $guestPass 2>&1
if ($procCheck -notmatch "Error" -and $procCheck -notmatch "error") {
$toolsReady = $true
}
} catch {
$toolsReady = $false
}
} while (-not $toolsReady -and $bootElapsed -lt $bootTimeout)
if (-not $toolsReady) {
Write-Warning "[INFO] VMware Tools did not respond after $bootTimeout seconds. Skipping this iteration."
& $vmrun stop $vmxPath hard
Start-Sleep -Seconds 5
continue
}
Write-Host "[INFO] Guest OS is fully booted."
# 4) Record existing report folders before launching analysis
$beforeReportNames = @(Get-ChildItem -Path $reportsDir -Directory | Select-Object -ExpandProperty Name)
# 5) Run Analyzer.ps1 inside the VM via vmrun runProgramInGuest (non-blocking)
# Launched with -noWait to avoid hanging when child processes keep running.
# The shared folder is mapped as Z:\ inside the guest (configure in VMware VM settings)
$psExe = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$remoteScript = "Z:\\Analyzer.ps1"
Write-Host "[INFO] Launching Analyzer.ps1 inside the VM..."
& $vmrun runProgramInGuest $vmxPath -gu $guestUser -gp $guestPass -activeWindow -noWait $psExe "-ExecutionPolicy Bypass -File $remoteScript"
Write-Host "[INFO] Analyzer launched. Waiting for report..."
# 6) Wait for a new report folder to appear
$timeoutSec = 600
$elapsed = 0
$pollInterval = 10
$newReportName = $null
do {
Start-Sleep -Seconds $pollInterval
$elapsed += $pollInterval
$currentReportNames = @(Get-ChildItem -Path $reportsDir -Directory | Select-Object -ExpandProperty Name)
$newFolders = $currentReportNames | Where-Object { $_ -notin $beforeReportNames }
if ($newFolders) {
$newReportName = $newFolders | Select-Object -First 1
}
} while (-not $newReportName -and $elapsed -lt $timeoutSec)
if (-not $newReportName) {
Write-Warning "[INFO] No new report detected after $timeoutSec seconds."
} else {
Write-Host "[INFO] New report detected: $newReportName"
}
# 7) Shut down the VM
Write-Host "[INFO] Shutting down the VM..."
& $vmrun stop $vmxPath hard
# Wait for the VM to fully power off
$shutdownTimeout = 60
$shutdownElapsed = 0
do {
Start-Sleep -Seconds 5
$shutdownElapsed += 5
$runningList = & $vmrun list
$isRunning = $runningList -match [regex]::Escape($vmxPath)
} while ($isRunning -and $shutdownElapsed -lt $shutdownTimeout)
Write-Host "[INFO] VM is powered off. Preparing next sample..."
# 8) Delete the sample that was actually analyzed
# The Analyzer names the report folder after the sample's BaseName,
# so we match it back to the file in Malware.
if ($newReportName) {
$analyzedSample = $pending | Where-Object { $_.BaseName -eq $newReportName } | Select-Object -First 1
if ($analyzedSample) {
Write-Host "[INFO] Deleting analyzed sample: $($analyzedSample.FullName)"
Remove-Item -Path $analyzedSample.FullName -Force
}
else {
Write-Warning "[INFO] Could not find sample matching report '$newReportName'. Skipping deletion."
}
}
else {
Write-Warning "[INFO] No report was generated. Skipping sample deletion."
}
}
Write-Host "[INFO] All binaries processed. Reports are in: $reportsDir"