Sniffing the Parent Partitions Network Traffic in a Hyper-V Virtual Machine

This article discusses a situation whereby you want to monitor/mirror/sniff network port traffic on a Hyper-V Parent Partition inside on of its own child VM’s.

Why would you need to do this?

Under a traditional architecture you have the flexibility to tell your switch to mirror all traffic into or out of Port 6 onto Port 21. You then connect a laptop to Port 21 and promiscuously monitor the traffic coming into that port. Under a modern Converged/Software Defined Network architecture, this will not work.

In a modern Converged Fabric design, physical NICs are teamed. The parent partition on the hypervisor no-longer uses the physical NICs, but logically uses its own synthetic NICs for data transfers.

  1. Link Aggregation/LCAP/EtherChannel will split the traffic at the switch
  2. Teaming/LBFO will split the traffic at the hypervisor
  3. Data security will fire a red flag as you will be monitoring too much unrelated traffic
  4. If you combine them, you will overload the monitoring Port with aggregated traffic, causing performance issues and packet loss
  5. You may impact the performance of tenant VM’s and mission critical services

Fortunately the Parent Partitions own Virtual NICs are identical to the vNICs in any Hyper-V virtual machine. Consequently, you can use the same Hyper-V functionality on the Parent Partition as you would any VM.

 

Requirements

In order to sniff traffic on the Parent Partition you must ensure the following:

  1. The Parent Partition and the VM must be connected to the same Virtual Switch
  2. The “Microsoft NDIS Capture” extension must be enabled on the Virtual Switch (this is enabled by default)
    Enable the Microsoft NDIS Capture Extensions
  3. The monitoring VM should have 2 vNICs. The vNIC used to monitor traffic should be configured onto the same VLAN as the vNIC on the Parent Partition. The monitoring NIC should have all of its service and protocol bindings disabled to ensure that only port mirrored traffic is appearing in the WireShark logs
    Disabling service and protocol bindings on the vNIC
  4. Wireshark, Microsoft NetMonitor or another promiscuous network traffic monitor
  5. If you are in a corporate environment, ensure that you have approvals from your Information Security team. In some jurisdictions port sniffing can be considered an offence

 

Enabling Port Sniffing

You cannot enable Port Sniffing on the Parent Partition using the Hyper-V Manager GUI. Open PowerShell on/to the Parent Partition

Execute Get-NetAdapter

Identify the name of vNIC that you will sniff traffic to/from e.g. vEthernet (Management)

Taking only the value inside the parenthesis "Management" enter the following command

Get-VMNetworkAdapter -ManagementOS 'Management' | Set-VMNetworkAdapter -PortMirroring Source

Substituting WireSharkVm for the name of your monitoring VM. Execute Get-VMNetworkAdapter 'WireSharkVm'

Identify the MAC Address of the vNIC’s that you will use to receive the Port Mirror from the Hyper-V host and enable it as the recipient for the mirror

Get-VMNetworkAdapter 'WireSharkVm' | ?{$_.MacAddress -eq '001512AB34CD'} | Set-VMNetworkAdapter -PortMirroring Destination

If the Parent Partition and VM vNICs are in the same VLAN. You should now be able to sniff traffic inbound to / outbound from the Parent Partition.

 

Disabling Port Sniffing

When using Port Mirroring, remember that it consumes CPU time and network resources on the hypervisor. To disable the port mirror, repeat the above commands substituting ‘None’ as the key-word for the PortMirroring parameter e.g.

Get-VMNetworkAdapter -ManagementOS 'Management' | Set-VMNetworkAdapter -PortMirroring None
Get-VMNetworkAdapter 'WireSharkVm' | ?{$_.MacAddress -eq '001512AB34CD'} | Set-VMNetworkAdapter -PortMirroring None

Removing phantom “ms-resource:AppName/Text” apps from the Start Menu

This article discusses a method of eliminating phantom “ms-resource:AppName/Text” entries on the Windows 10 Start Menu. You may see these after upgrading Windows 10 to version 1903 in an “other” group at the bottom of the Start Menu.

 

What are “ms-resource:AppName/Text” entries?

A database is used to store information on user-available ModernApps and its contents merged with traditional apps (.lnk files) when the start menu is opened by a user.

The “ms-resource:AppName/Text” reveals a corrupt/orphaned entry in the database. As part of this, lookups are performed to C:\Users\<username>\AppData\Local\Packages and/or C:\Windows\SystemApps to load the app’s manifest.xml file. The manifest file is used to query for the Icon, life tile instructions and the multilingual label used on the start menu.

If the database record exists, but the application itself no longer does – due to a crash during uninstall or the user being offline when an administrator removed the app. “ms-resource:AppName/Text” will appear until such time that Windows validates the contents of the database. This usually during the next update to the “Start Menu” app itself, or an OS upgrade.

 

Ensure App Uninstallation

A common reason for this occurring is:

  1. The user has never run the app to install it into their user profile
  2. The app is removed from AppxProvisionedPackages in C:\Windows\SystemApps by an administrator. This prevents self-repair
  3. The app is removed from ‘All Users’ on the system, however the database entry remains in one or more local user profiles

If there are remnants of the app in Get-AppxPackage or Get-AppxPackage -AllUsers, you must remove the entries first. This is because the entry will be re-written to the Start Menu database after it is reset.

Once the app has been removed from the local user account, ‘all users’ and the provisioned apps repository. You can reset the database.

 

Reset the Start Menu database

There are several ways to do this. This fix runs in the local user context and uses a “bludgeoning” approach to solving the problem.

Paste the following code into a PowerShell window. It will error, it will not be pretty but it will remove the phantom entry – provided that you have genuinely uninstalled the app.

Stop-process -Name 'explorer'; Remove-Item "$env:LocalAppData\Packages\$($(Get-AppxPackage | ?{$_.name -like '*startmenue*'}).PackageFamilyName)\TempState\" -Recurse -Force -Confirm:$false; Stop-process -Name 'explorer'; Remove-Item "$env:LocalAppData\Packages\$($(Get-AppxPackage | ?{$_.name -like '*startmenue*'}).PackageFamilyName)\TempState\" -Recurse -Force -Confirm:$false; Stop-process -Name 'explorer'; Remove-Item "$env:LocalAppData\Packages\$($(Get-AppxPackage | ?{$_.name -like '*startmenue*'}).PackageFamilyName)\TempState\" -Recurse -Force -Confirm:$false; Stop-process -Name 'explorer'; Remove-Item "$env:LocalAppData\Packages\$($(Get-AppxPackage | ?{$_.name -like '*startmenue*'}).PackageFamilyName)\TempState\" -Recurse -Force -Confirm:$false; Start-Process 'c:\windows\explorer.exe';

If you are paying attention, yes, the above is repeating itself several times. This is intentional.

 

What does it do?

Very simply the above PowerShell sample:

  1. Crashes the Windows Shell (Windows Explorer)
  2. Looks up the version number of the Windows 10 Start Menu app (“Microsoft.Windows.StartMenuExperienceHost”)
  3. Uses the version number to construct the path to the location of the Start Menu database
  4. Deletes the database
  5. Return to 1
  6. Repeat…
  7. Start Windows Explorer

The code repetition prevents explorer.exe from being auto-recovered by the WinLogon watchdog. If explorer.exe is running, it will fail to delete the database. By repeatedly running, it will eventually brute-force explorer.exe closed, perform the deletion and restart explorer.exe on its own.

Explorer.exe re-scans the local system/user to inventory apps when it starts and a new database created without the phantom app.

Redesigning the Hardware for the Virtual TV Streaming Server

This article discusses a hardware design change to the Virtual TV Streaming Server discussed in Creating a Virtual TV Streaming Server.

If you are not familiar with the previous setup. The design revolved around an array of TV tuners connected to a 7-port USB 3.0 hub. In turn, this connected to a USB 3.0 controller which was passed through Discrete Device Assignment (DDA) through to a Windows 10 Virtual Machine. This run DVBLogic TV Mosaic, the IP TV streaming software.

 

Virtual TV Streaming Server Meltdown

The solution has run extremely well. There have been no crashes from TV Mosaic, the VM or the Hypervisor. Until last week.

The system missed last Saturdays recording schedules and on Sunday afternoon, wouldn’t initiate playback. On inspection of the VM, one of the Tuners was showing as “unknown” on the TV Mosaic console. The others were all fine. Once this phantom tuner was removed from the console, everything started working again.

Initially thinking that it was related to a coincidental BIOS update on the server, it turned out that the tuner was simply dead. I RMA’d it with DVBLogic – who didn’t challenge my diagnostic or offer any resistance – but I did have to ship it Internationally at my own expense.

A week later, I came to use the system again and, once more, it was dead. A trip to the attic later and the was dead. A multimeter confirmed that the power supply had died, and I begun an RMA process with StarTech this morning.

 

Analysis

If the power supply on the StarTech was defective, it could potentially have caused the fault with the TV Butler tuner. Although this is speculative and unprovable. My main suspicion is that the problems were caused by heat. The attic roof space is uninsulated, and the UK is in the summer period. With temperature in the attic space certainly to have ranged into the 40c’s.

Unlike with the physical TV server that this setup replaced – which had fans. This setup doesn’t. PCIe TV Tuners are intrinsically designed to withstand higher thermal variances than USB ones. The StarTech and TV Butler products are quite simply basic consumer devices. It is possible that this factor led to both of their demises.

There was a power outage mid-week last week, and the StarTech itself was not sitting on the server UPS – but it was on a surge protector. It is my belief that this did not contribute to the issue.

 

Hardware Redesign

The brief for the redesign is simple

  1. Remove essential electrical components from the attic
  2. Minimise space use
  3. Minimise electrical consumption (as everything will now be powered through the UPS)
  4. Do not clutter up the backplane of the server with dongles

 

Power

To accommodate #1, #2 and #3 the USB Hub is going to be eliminated from the design. The TV Tuners will now connect directly to the DDA USB controller. In order to do this, the dual port controller will need to be replaced.

After deliberating on whether to get an externally powered or bus powered 4-port controller, I chose a , bus powered card. A risk, given my previous experience here. The DG-PCIE-04B reviewed better than a similarly priced externally powered one. The decider was that it uses a NEC chipset and not a RealTek/SiS (i.e. cheap) chip. Finally, the fact that each of the ports had its own voltage management and fuse circuit is a valuable quality safeguard.

 

Patch Panel TV

To satisfy design brief #4, the USB TV Tuners will need to be mounted away from the server. To achieve this, I am going to mount the Tuners in the patch panel.

Using a set of keystone jacks. A USB lead will run between the USB controller and the Patch panel; simply mounting to the TV Tuners held in the patch panel.
TNP USB 3.0 Keystone Jack Image

The patch panel happens to be near the ceiling, directly above the TV aerial distributor for the house. Using 4m coaxial cable, the aerial feed can route through the existing ceiling cable run and clip neatly into the TV Tuners.

The Amazon order consisted of

  • 1x
  • 1x Pack of 5
  • 4x Rankie USB 3.0 Type A Male to Male Data Cable, 3m (Server – Patch Panel)
  • 3x Ex-Pro White Coax F Plug Type – to – Male M Coax plug Connection Cable Lead – 4m (Aerial distributor – TV Tuners)

 

Installation

The installation was extremely simple.

  1. Replace the existing 2 port USB controller with the 4 port one
  2. Clip the USB 3.0 keystones into the patch panel
  3. Run cables between the USB controller and the front profile (base) of the USB keystones
  4. Passing the USB controller through to Hyper-V
    1. Shutdown the Virtual Streaming TV Server VM
    2. Get the Device Instance Path from the Details tab > Device instance path section in Device Manager e.g.
      PCI\VEN_1912&DEV_0014&SUBSYS_00000000&REV_03\4&1B96500D&0&0010
    3. Use PowerShell to dismount the USB Controller from the Hypervisor and attach it to the VM
$vmName = 'TvServer'
$pnpdevs = Get-PnpDevice -PresentOnly | Where-Object {$_.InstanceId -eq 'PCI\VEN_1912&DEV_0014&SUBSYS_00000000&REV_03\4&1B96500D&0&0010'}
$instanceId = $pnpdev.InstanceId
$locationPath = ($pnpdevs[0] | get-pnpdeviceproperty DEVPKEY_Device_LocationPaths).data[0]
Write-Host "    Instance ID: $instanceId"
Write-Host "    Location Path: $locationpath"

# Disable the Device on the Host Hypervisor
Disable-PnpDevice -InstanceId $instanceId -Confirm:$false

# Wait for the dismount to complete
Start-Sleep -s 15

# Dismount the Device from the Host Hypervisor
Dismount-VmHostAssignableDevice -locationpath $locationPath -Force

# Attach the PCIe Device to the Virtual Machine
Add-VMAssignableDevice -LocationPath $locationpath -VMName $vmName

# Note: You may need to reboot the Hypervisor hosts at this point.
# If the VM's device manager informs you that it can see the controller, but is  unable to initialise
# the controllers USB Root Hub. A reboot should fix it.
  1. Clip the DVBLogic TV Butler TV Tuners into the patch panel USB keystone jacks using the inside (top) port on the keystones
  2. Start the TV Server VM
Photograph of USB Tuners mounted in patch panel
The patch panel now has three USB ports – the left-most TV Butler is missing as the RMA replacement has not yet arrived.

Photograph of USB Tuners mounted in patch panel Photograph of USB Tuners mounted in patch panel

The Virtualised Windows 10 Streaming TV Server came back online and there hasn’t been any instability caused by the bus-powered USB controller. The TV Butler’s are warm to the touch, have plenty of air-flow and the ambient temperature can be monitored via existing sensors in the room.

The completed assembly in the Patch Panel

With any luck, I will not need to revisit this project for quite some time!

VBScript Timer() function precision

This article explores the numeric precision of the ASP and VBScript Timer() function, outlining that it may be more accurate than it initially appears.

 

Timer()

Prior to the arrival of PowerShell. The VBScript Timer() function wass the closest thing that script creators had for undertaking high precision timings in the Windows Scripting Host (WSH) environment.

The Timer() function returns a VBSingle – aka a Single Prevision floating point number or a “Real” – value as a representation of the systems real time clock. As a Single precision value, the permitted range is -3.402823E38 to -1.401298E-45 for negative values; 1.401298E-45 to 3.402823E38 for positive values. If you print out the value of Timer() in ASP/VBScript

WScript.Echo Timer()

You will get a value like

52191.62

This value is a representation of the number of seconds that have elapsed on the local executing system since the local system click last hit midnight. Consequently, evaluating Timer() against a DateDiff() evaluation of the number of seconds since Midnight will result in the same answer (save for the decimal point).

WScript.Echo Timer()
WScript.Echo DateDiff("s", #2019-07-01#, Now())

Which results in

52191.62
52191

 

The hidden detail

Masked in the 2 decimal places default printout. Timer() is significantly more detailed than just two decimal points. Depending on the precision of your systems Real Time Clock (RTC) the precision may be up to 7 decimal places. You can view your systems capability by subtracting the Integer from the timer value:

WScript.Echo Timer() - Int(Timer())

Which may result in a value such as

0.6171875

At 7 decimal places, the precision of Timer() is – floating point number inaccuracy side – considerably better than that of VBDateTime. Under VBDateTime, the second is the atomic value, offering no more precision.

0         - Second
0.6       - Decisecond  / 1 tenth
0.61      - Centisecond / 1 hundredth
0.617     - Millisecond / 1 thousandth
0.6171    -               1 ten thousandth
0.61718   -               1 hundred thousandth
0.617187  - Microsecond / 1 millionth
0.6171875 -               1 ten millionth

This demonstrates that there is flexibility in VBScript for more precise clock operations. But is the resolution high enough?

 

Fidelity

The resolution and fidelity of the Timer() function is what makes it valuable (or not) to a programmer. On a modern system, with a High Precision Event Timer (HPET), the update interrupt will only fire so many times to update the clock.

Running an imprecise test as follows:

for i = 0 to 999
  WScript.Echo Timer() - Int(Timer())
next

The output value only changed between 10 and 31 cycles (reflective of the CPU scheduler performing other tasks during execution. The counter incrementation was consistent, updating 48 times with an increment of between 0.0117187 and 0.0195313 seconds. Once every 20.8 cycles on average.

0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.0195313
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.015625
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187
0.0117187

In practice this means that the viable, comparable resolution of Timer() is not much better than once aver 0.2 seconds. Over a longer time period, Timer() can offer higher accuracy: provided you aren’t polling for an update more than every 0.2 of a second.