├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Detect-VirtualGHOST.ps1 ├── LICENSE ├── README.md ├── SECURITY.md └── docs └── asset ├── PowerShellCredRequest.png └── cs-logo.png /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | oss-conduct@crowdstrike.com or https://crowdstrike.ethicspoint.com/. 64 | 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series 87 | of actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or 94 | permanent ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within 114 | the community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.0, available at 120 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 121 | 122 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 123 | enforcement ladder](https://github.com/mozilla/diversity). 124 | 125 | [homepage]: https://www.contributor-covenant.org 126 | 127 | For answers to common questions about this code of conduct, see the FAQ at 128 | https://www.contributor-covenant.org/faq. Translations are available at 129 | https://www.contributor-covenant.org/translations. 130 | 131 | 132 | --- -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Welcome! 2 | 3 | Welcome and thank you for your interest in contributing to a CrowdStrike project! We recognize contributing to a project is no small feat! The guidance here aspires to help onboard new community members into how CrowdStrike-led projects tend to operate, and by extension, make the contribution process easier. 4 | 5 | ## How do I make a contribution? 6 | 7 | Never made an open source contribution before? Wondering how contributions work in CrowdStrike projects? Here is a quick rundown! 8 | 9 | 1. Find an issue that you are interested in addressing, or a feature you would like to add. These are often documented in the project repositories themselves, frequently in the `issues` section. 10 | 11 | 2. Fork the repository associated with project to your GitHub account. This means that you will have a copy of the repository under *your-GitHub-username/repository-name*. 12 | 13 | Guidance on how to fork a repository can be found at [https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository). 14 | 15 | 3. Clone the repository to your local machine using ``git clone https://github.com/github-username/repository-name.git``. 16 | 17 | GitHub provides documentation on this process, including screenshots, here: 18 | [https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository#about-cloning-a-repository](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository#about-cloning-a-repository) 19 | 20 | 4. Create a new branch for your changes. This ensures your modifications can be uniquely identified and can help prevent rebasing and history problems. A local development branch can be created by running a command similar to: 21 | 22 | ``git checkout -b BRANCH-NAME-HERE`` 23 | 24 | 5. Make the appropriate changes for the issue you are trying to address or the feature you would like to add. 25 | 26 | 6. Add the file contents of the changed files to the "snapshot" git uses to manage the state of the project (also known as the index). Here is the git command that will add your changes: 27 | 28 | ``git add insert-paths-of-changed-files-here`` 29 | 30 | 7. Use `git commit` to store the contents of the index with a descriptive message. This message should outline what was changed. For example: 31 | 32 | ``git commit -m "Added Dockerfile for Ubuntu-based deployments"`` 33 | 34 | 8. Push your local changes back to your account on github.com: 35 | 36 | ``git push origin BRANCH-NAME-HERE`` 37 | 38 | 9. Submit a pull request to the upstream project. Documentation on this process, including screen shots, can be found at [https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) 39 | 40 | 10. Once submitted, a maintainer will review your pull request. They may ask for additional changes, or clarification, so keep an eye out for communication! GitHub automatically sends an email to your email address whenever someone comments on your pull request. 41 | 42 | 11. While not all pull requests may be merged, celebrate your contribution whether or not your pull request is merged! All changes move the project forward, and we thank you for helping the community! 43 | 44 | ### Rebase Early, Rebase Often! 45 | 46 | Projects tend to move at a fast pace, which means your fork may become behind upstream. Keeping your local fork in sync with upstream is called `rebasing`. This ensures your local copy is frequently refreshed with the latest changes from the community. 47 | 48 | Frequenty rebasing is *strongly* encouraged. If your local copy falls to far behind, you may encounter merge conflicts when submitting pull request. If this happens, you will have to triage (often by hand!) the differences in your local repository versus the changes upstream. 49 | 50 | * Documentation on how to sync/rebase your fork can be found at [https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/syncing-a-fork](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/syncing-a-fork) 51 | 52 | * For handling merge conflicts, refer to [https://opensource.com/article/20/4/git-merge-conflict](https://opensource.com/article/20/4/git-merge-conflict) 53 | 54 | ## Where can I go for help? 55 | 56 | ### Submitting a Ticket 57 | 58 | General questions relating a project should be opened in that projects repository. Examples would be troubleshooting errors, submitting bug reports, or asking a general question/request for clarification. 59 | 60 | If your question is of the broader CrowdStrike community, please [open a community discussion](https://github.com/CrowdStrike/community/discussions/new). 61 | 62 | ### Submitting a New Project Idea 63 | 64 | If you do not see a project, repository, or would like the community to consider working on a specific piece of technology, please [open a community ticket](https://github.com/CrowdStrike/community/issues/new). 65 | 66 | ## What does the Code of Conduct mean for me? 67 | 68 | Our community Code of Conduct helps us establish community norms and how they'll be enforced. Community members are expected to treat each other with respect and courtesy regardless of their identity. 69 | 70 | CrowdStrike open source project maintainers are responsible for enforcing the CrowdStrike Code of Conduct within the project, issues may be raised directly to the maintainer should the need arise. 71 | 72 | ### Escalation Path 73 | 74 | If you do not feel your concern has been addressed, if you are unable to communicate your concern with project maintainers, or if you feel the situation warrants, please escalate to: 75 | 76 | * [oss-conduct@crowdstrike.com](mailto:oss-conduct@crowdstrike.com) 77 | * [Ethics and Compliance Hotline](https://crowdstrike.ethicspoint.com/) -------------------------------------------------------------------------------- /Detect-VirtualGHOST.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | <# 3 | .SYNOPSIS 4 | Identify unregistered VMWare Virtual Machines running on ESXi hypervisors 5 | .DESCRIPTION 6 | PowerShell script to identify unregistered VMWare Virtual Machines (VMs) that are powered on by comparing the list of VMs registered in the inventory (vCenter or ESXi) vs. those that are powered on via PowerCLI. Matching is performed by examining the 128-bit SMBIOS UUID of a virtual machine. Using the identifier should prevent situations where a duplicate VM Displayname is used to blend in. This particular technique has been given the name "VirtualGHOST" since it's a Virtual Machine whose presence is nearly impossible to detect. 7 | .PARAMETER Server 8 | Name/IP of vCenter or ESXi system to connect to with PowerCLI. When connecting to vCenter, the script will automatically loop through each registered hypervisor and perform the comparison. Alternatively, users can connect to a single ESXi system to check just that host. 9 | .PARAMETER Credential 10 | Credential to be used when connecting to vCenter / ESXi - will prompt if not provided separately 11 | .EXAMPLE 12 | PS> .\Detect-VirtualGHOST.ps1 13 | .EXAMPLE 14 | PS> .\Detect-VirtualGHOST.ps1 -Server vCenter.internaldomain.local 15 | .EXAMPLE 16 | PS> .\Detect-VirtualGHOST.ps1 -Server esxi1.internaldomain.local 17 | .NOTES 18 | Credits: CrowdStrike, Inc. (Ian Barton, Brian Pitchford, Jackson Roussin, Dylan Watson) 19 | .LINK 20 | https://github.com/CrowdStrike/VirtualGHOST 21 | .LINK 22 | https://dp-downloads.broadcom.com/api-content/apis/API_VWSA_001/7.0/html/vim.vm.ConfigInfo.html 23 | #> 24 | 25 | Param ( 26 | [Parameter(Mandatory = $true)] 27 | [String]$Server, 28 | [PSCredential]$Credential = (Get-Credential -Message "Input vCenter/ ESXi credentials for PowerCLI") 29 | ); 30 | 31 | 32 | if (-not (Get-Module -ListAvailable -Name VMware.PowerCLI)) { 33 | Write-Error "[!] VMware PowerCLI module is not installed. Please install it to proceed." 34 | exit 1 35 | } else { 36 | # Importing only the Cmdlets that we need in the hopes of this finishing a bit faster (PowerCLI import is notoriously slow) 37 | Write-Output "[+] Importing VMWare PowerCLI module. Please wait as this might take a while..." 38 | $null = Import-Module VMware.PowerCLI -Cmdlet Connect-VIServer, Get-EsxCli, Get-VMHost, Get-VM 39 | } 40 | 41 | function Get-VirtualGHOSTDetails { 42 | <# 43 | .SYNOPSIS 44 | Collect additional information from a VM that's been detected as a VirtualGHOST 45 | .INPUTS 46 | EsxCli object representing a VM 47 | .OUTPUTS 48 | Custom object with the standard VM details as well as network information (if available) 49 | #> 50 | param ( 51 | [Parameter(Mandatory = $true)] 52 | $VM 53 | ) 54 | 55 | try { 56 | # Attempt to get network information for the VM 57 | $VMNetworkInfo = $esxcli_v2.network.vm.list.Invoke() | Where-Object { $_.WorldId -in $VM.WorldID } 58 | $VMNetworkPortInfo = $esxcli_v2.network.vm.port.list.Invoke(@{"worldid" = $VM.worldid}) 59 | } 60 | catch { 61 | Write-Verbose "[-] Error collecting network info for $($VM.DisplayName) on $($vmHost.Name)" 62 | } 63 | $ReturnObject = [PSCustomObject]@{ 64 | Hypervisor = $vmHost.Name 65 | VMName = $VM.DisplayName 66 | VMConfigFile = $VM.ConfigFile 67 | VMWorldID = $VM.WorldID 68 | VMNetworkInfo = $VMNetworkInfo | Select-Object Networks, NumPorts 69 | VMNetworkPortInfo = $VMNetworkPortInfo 70 | } 71 | 72 | return $ReturnObject 73 | } 74 | 75 | # If there are any errors then we will want to bubble them up 76 | $ErrorActionPreference = "Stop" 77 | 78 | try { 79 | Write-Output "[+] Connecting to server: $Server" 80 | $VMWareConnection = Connect-VIServer -Credential $Credential -Server $Server 81 | } 82 | catch { 83 | # Unable to connect to the server 84 | if ($PSBoundParameters.Debug -eq $true) { 85 | $DebugError = "Line: $(($_.ScriptStackTrace -split ",")[1])" 86 | } 87 | $ErrorMsg = @" 88 | 89 | [!] There was an error connecting to the server. 90 | [!] Exception: $($_.FullyQualifiedErrorId) 91 | $DebugError 92 | "@ 93 | Write-Error $ErrorMsg 94 | exit 1 95 | } 96 | # Display message indicating successful connection to the server. Includes version / product information for debugging if necessary 97 | Write-Output "[+] Connected to server: $($VMWareConnection.Name) | Version: $($VMWareConnection.Version) | ProductLine: $($VMWareConnection.ProductLine)" 98 | 99 | $AllvmHosts = Get-VMHost 100 | Write-Output "[+] There are $($AllvmHosts.Length) hypervisor(s) that will be checked for evidence of VirtualGHOST VMs." 101 | 102 | # Instantiate the object which will hold any results 103 | $Results = New-Object System.Collections.Generic.List[System.Object] 104 | 105 | foreach ($vmHost in $AllvmHosts) { 106 | try { 107 | Write-Verbose "[-] Connecting to hypervisor: $($VMHost.Name)" 108 | # Retrieve a PowerShell object that will allow us to execute funtionally equivalent esxcli commands against the host 109 | $esxcli_v2 = Get-EsxCli -VMHost $vmHost -V2 110 | # Collect the list of running VMs per esxcli VM process listing. This will be where a VirtualGHOST VM can be spotted 111 | $VMsFromESXCli = $esxcli_v2.vm.process.list.Invoke() | Select-Object DisplayName, 112 | ConfigFile, 113 | ProcessID, 114 | VMXCartelID, 115 | WorldID, 116 | @{ 117 | Name = "UUID_Comparison"; 118 | Exp = { 119 | # This unique identifier appears to be the 128-bit SMBIOS UUID of a virtual machine represented as a hexadecimal string. We remove the dashes so it can be directly compared with the value we normalize from the VM inventory 120 | $_.UUID.Replace(" ", "").Replace("-", "").ToLower() 121 | } 122 | } 123 | # Collect the list of VMs that are registered and expected to be in the inventory. This could be either from the hypervisor itself (if we connected directly to ESXi) or vCenter 124 | $VMsFromInventory = Get-VM -Location $vmHost | Select-Object Name, 125 | VMHost, 126 | PowerState, 127 | @{ 128 | # This unique identifier appears to be the 128-bit SMBIOS UUID of a virtual machine represented as a hexadecimal string. We remove the dashes so it can be directly compared with the UUID_Comparison value we normalized from 'esxcli vm process list' 129 | Name = "UUID_Comparison"; 130 | Exp = { 131 | ($_.ExtensionData.Config.Uuid).Replace("-", "").ToLower() 132 | } 133 | } 134 | 135 | $GhostVMs = $VMsFromESXCli | Where-Object { 136 | # This is where we compare the inventory with the running VMs to see if we have any VirtualGHOSTs 137 | $_.UUID_Comparison -notin $VMsFromInventory.UUID_Comparison 138 | } 139 | 140 | if ($null -ne $GhostVMs) { 141 | Write-Warning "[!] ====Unregistered VM Detected on $($VMHost.Name)====" 142 | foreach ($ThisGhostVM in $GhostVMs) { 143 | $VMInfo = Get-VirtualGHOSTDetails -VM $ThisGhostVM 144 | 145 | # Display to user immediately as well as at the conclusion of the script 146 | $VMInfo | Format-Table Hypervisor, VMName, VMConfigFile, VMWorldID | Out-String | Write-Warning 147 | 148 | # Display network information 149 | if ($null -ne $VMInfo.VMNetworkInfo) { 150 | Write-Warning "This VM appears to be connected to the network(s): $($VMInfo.VMNetworkInfo.Networks -join ', ')" 151 | } 152 | if ($null -ne $VMInfo.VMNetworkPortInfo) { 153 | $VMInfo.VMNetworkPortInfo | Format-Table * | Out-String | Write-Warning 154 | } 155 | 156 | # Add this result to the full tally 157 | $Results.Add($VMInfo) 158 | } 159 | } 160 | } 161 | catch { 162 | Write-Warning "[!] Failed to process $($vmHost.Name): $_" 163 | } 164 | } 165 | 166 | if ($Results.Count -ne 0) { 167 | Write-Warning @" 168 | [!] Unregistered VMs detected on at least one hypervisor. Please refer to the output above. There may be some false positives due to standard system lifecycles, but any results should be investigated further. 169 | "@ 170 | } 171 | else { 172 | Write-Output "[+] No unregistered VMs detected." 173 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 CrowdStrike 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![CrowdStrike Logo](./docs/asset/cs-logo.png) 2 | 3 | [![Twitter URL](https://img.shields.io/twitter/url?label=Follow%20%40CrowdStrike&style=social&url=https%3A%2F%2Ftwitter.com%2FCrowdStrike)](https://twitter.com/CrowdStrike)
4 | 5 | # VirtualGHOST 6 | 7 | This repository contains a PowerShell script leveraging [VMWare PowerCLI](https://developer.broadcom.com/tools/vmware-powercli/latest) to identify unregistered VMWare Virtual Machines (VMs) that are powered on by comparing the list of VMs registered in the inventory (vCenter or ESXi) vs. those that are powered on. 8 | 9 | ## What is a VirtualGHOST? 10 | 11 | A "VirtualGHOST" is a VMWare Virtual Machine on an ESXi host that has been powered on manually from the command line. CrowdStrike decided to call this particular technique VirtualGHOST since it's a Virtual Machine whose presence is nearly impossible to detect. 12 | 13 | ## Usage 14 | 15 | `Detect-VirtualGHOST.ps1` is the PowerShell script that contains the detection logic. It expects two parameters: 16 | - Server (IP/DNS for vCenter or ESXi) 17 | - Credential (PowerShell credential object representing username/password with privileges to access VMWare management APIs) 18 | 19 | If either of these parameters are not provided, the script will prompt for them. E.g. 20 | 21 | ``` 22 | .\Detect-VirtualGHOST.ps1 23 | 24 | cmdlet Detect-VirtualGHOST.ps1 at command pipeline position 1 25 | Supply values for the following parameters: 26 | Server: 27 | ``` 28 | 29 | ![PowerShell Credential Prompt](./docs/asset/PowerShellCredRequest.png) 30 | 31 | ### Passed Credential Object 32 | 33 | ```powershell 34 | $Credential = Get-Credential 35 | .\Detect-VirtualGHOST.ps1 -Credential $Credential 36 | ``` 37 | 38 | ## Tested VMWare Versions 39 | 40 | - vCenter 41 | - 8.0.2 42 | - ESXi 43 | - 6.5.0 44 | - 7.0.3 45 | - 8.0.0 46 | 47 | ## Sample Output 48 | 49 | ### Positive Result Requiring Further Investigation 50 | 51 | ``` 52 | .\Detect-VirtualGHOST.ps1 -Server 192.168.122.20 -Credential $Credential 53 | [+] Importing VMWare PowerCLI module. Please wait as this might take a while... 54 | [+] Connecting to Server: 192.168.122.20 55 | [+] Connected to server: 192.168.122.20 56 | [+] There are 2 hypervisors that will be checked for evidence of VirtualGHOST VMs. 57 | WARNING: [!] ====Unregistered VM Detected on 192.168.122.52==== 58 | WARNING: 59 | Hypervisor VMName VMConfigFile VMWorldID 60 | ---------- ------ ------------ --------- 61 | 192.168.122.52 OpenWrt4 /vmfs/volumes/663a5dbf-a8d1533e-7af4-000c29d0e331/OpenWrt4/OpenWrt4.vmx 265959 62 | 63 | 64 | WARNING: [!] ====Unregistered VM Detected on 192.168.122.53==== 65 | WARNING: 66 | Hypervisor VMName VMConfigFile VMWorldID 67 | ---------- ------ ------------ --------- 68 | 192.168.122.53 OpenWrt2 /vmfs/volumes/663a5daa-3740eb00-3ac0-000c296d56a6/OpenWrt2/OpenWrt2.vmx 265222 69 | 70 | 71 | WARNING: This VM appears to be connected to the network(s): VM Network 72 | WARNING: 73 | ActiveFilters DVPortID IPAddress MACAddress PortID Portgroup TeamUplink UplinkPortID vSwitch 74 | ------------- -------- --------- ---------- ------ --------- ---------- ------------ ------- 75 | 0.0.0.0 00:00:00:00:00:00 134217741 VM Network void 0 vSwitch0 76 | 77 | 78 | WARNING: 79 | Hypervisor VMName VMConfigFile VMWorldID 80 | ---------- ------ ------------ --------- 81 | 192.168.122.53 OpenWrt5 /vmfs/volumes/663a5daa-3740eb00-3ac0-000c296d56a6/OpenWrt5/OpenWrt5.vmx 266726 82 | 83 | 84 | WARNING: This VM appears to be connected to the network(s): dvportgroup-20 85 | WARNING: 86 | ActiveFilters DVPortID IPAddress MACAddress PortID Portgroup TeamUplink UplinkPortID vSwitch 87 | ------------- -------- --------- ---------- ------ --------- ---------- ------------ ------- 88 | 1 0.0.0.0 00:50:56:98:6f:04 100663310 dvportgroup-20 vmnic1 2248146951 SwitchNetwork 89 | 90 | 91 | WARNING: [!] Unregistered VMs detected on at least one hypervisor. Please refer to the output above. There may be some false positives due to standard system lifecycles, but any results should be investigated further. 92 | ``` 93 | 94 | ### Negative Result - No Potential VirtualGHOST VMs Detected 95 | 96 | ``` 97 | .\Detect-VirtualGHOST.ps1 -Server 192.168.122.20 -Credential $Credential 98 | [+] Importing VMWare PowerCLI module. Please wait as this might take a while... 99 | [+] Connecting to server: 192.168.122.20 100 | [+] Connected to server: 192.168.122.20 | Version: 8.0.2 | ProductLine: vpx 101 | [+] There are 2 hypervisors that will be checked for evidence of VirtualGHOST VMs. 102 | [+] No unregistered VMs detected. 103 | ``` 104 | 105 | ## Next Steps 106 | 107 | ### Imaging / Investigation 108 | Because the VirtualGHOST is not in the VM inventory, it cannot be managed by standard VMWare processes like vCenter or the ESXi web UI. To collect a forensic image and VM log files, follow these steps: 109 | 110 | - Enable SSH on the ESXi host with the VirtualGHOST VM (this is required because the Datastore browser may not allow you to copy all of the files related to the VirtualGHOST as some of them will be locked) 111 | - Connect to the ESXi host over SSH 112 | - Copy all files in the VirtualGHOST's directory to a different location (understanding that some files will be locked) 113 | - Typically there is only one Virtual Machine definition (`.vmx`) file per directory - so navigate to the parent directory of the `VMConfigFile` returned by the detection script 114 | - Register VM in ESXi UI using standard Create/Register VM interface ([Documentation Link](https://knowledge.broadcom.com/external/article?legacyId=1006160)) 115 | - Open newly registered VM in ESXi web UI 116 | - Expand all VM menus and capture screenshots for investigative purposes (this can make the job of mapping back specific VM configurations easier) 117 | - Suspend newly registered VM via ESXi web UI 118 | - Copy all files in VM directory to a separate location (noting that this was after registration) 119 | 120 | :bulb: The `vmware*.log` files stored in the VM directory will be **extremely** valuable for your investigation, so don't forget to grab/review them! 121 | 122 | ## Support 123 | 124 | As free, as-is tool this software is not officially supported by CrowdStrike. As such we ask that you please refrain from sending inquiries to the CrowdStrike support team. The project maintainers will be working with active community contributors to address bugs and supply new features. If you have identified a bug please [submit an issue through GitHub](https://github.com/CrowdStrike/VirtualGHOST/issues/new). -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | This document outlines the security policy and procedures for projects under the CrowdStrike organization. 4 | 5 | ## Supported Versions 6 | 7 | For each project, we aim to release security vulnerability patches for the most recent version at an accelerated cadence. Please refer to the specific project repository for details on supported versions. 8 | 9 | ## Reporting a Potential Security Vulnerability 10 | 11 | We encourage the reporting of security-related vulnerabilities. To report a suspected vulnerability in any CrowdStrike project, please use one of the following methods: 12 | 13 | + Submitting an __issue__ to the relevant project repository. 14 | + Submitting a __pull request__ with a potential fix to the relevant project repository. 15 | + Sending an email to __oss-security@crowdstrike.com__. 16 | 17 | ## Disclosure and Mitigation Process 18 | 19 | Upon receiving a security bug report, the issue will be triaged and assigned to a project maintainer. The maintainer will coordinate the fix and release process, typically involving: 20 | 21 | + Initial communication with the reporter to acknowledge receipt and provide status updates. 22 | + Confirmation of the issue and determination of affected versions. 23 | + Codebase audit to identify similar potential vulnerabilities. 24 | + Preparation of patches for all supported versions. 25 | + Patches will be submitted through pull requests, flagged as security fixes. 26 | + After merging and successful post-merge testing, patches will be released accordingly. 27 | 28 | ## Comments and Suggestions 29 | 30 | We welcome suggestions for improving this process. Please share your ideas by creating an issue in the relevant project repository. -------------------------------------------------------------------------------- /docs/asset/PowerShellCredRequest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrowdStrike/VirtualGHOST/5cf2de09246964febb6d759104326adc90dc6637/docs/asset/PowerShellCredRequest.png -------------------------------------------------------------------------------- /docs/asset/cs-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrowdStrike/VirtualGHOST/5cf2de09246964febb6d759104326adc90dc6637/docs/asset/cs-logo.png --------------------------------------------------------------------------------