Wireshark? Nope, Network Shell (Part 2)
In my last blog, we developed a script that leverages the Windows Network Shell utility to capture network packets without the need for a program like Wireshark, but we ran into some problems. The first problem we enc…
My quest to find a quick and dirty alternative to Wireshark using base Windows components…or as close to it as I can. This is not a tutorial but more of a blog where I show you my thought process and the interesting encounters I have along the way.
In my last blog, we developed a script that leverages the Windows Network Shell utility to capture network packets without the need for a program like Wireshark, but we ran into some problems. The first problem we encountered was the fact that we couldn’t run a net shell in an asynchronous way, i.e., in a PowerShell job. When we would start the job, Network Shell failed almost instantly, producing some results, but nowhere near what we needed. This would happen without error, and there was no way of solving it, at least with my current knowledge. But after some research, I ran across a blog from Ed Wilson, who used to write Microsoft blogs on PowerShell scripting, and he just happened to write a blog that talked about parsing network logs using a built-in PowerShell module called NetEventPacketCapture. This module would allow us to capture network packets similar to Network Shell, but would be much easier to parse through with built-in functions. From here, we could take that data and display it in a custom GUI or export it to a format like pcap or cap if you’d still prefer to use applications like WireShark.
In this part, we’re going to take the Start-PacketCapture function and rework the network capture logic using the NetEventPacketCapture cmdlets, giving us much more control over our captures, and hopefully allowing us to capture and display the network data asynchronously… or so I thought.
The first cmdlet that we need to use is New-NetEventSession, this is a sort of constructor object that we need to use, and it’s here that we will name our Session. This is important because this object gives us a lot of data, including the file location where the ETL file will be exported to. Yes, the same Event Trace Log file that Network Shell exports as well.
Start-PacketCapture {
#Get Current Date & Time To Be Used To Name Session Capture
$DateStamp = Get-Date -Format "ddMMyyyyHHmmss"
$SessionName = -join("CaptureSession","",${DateStamp})
# Initialize Packet Capture Session
New-NetEventSession -Name $SessionName
}We then need to provide, well, a provider. In our case, we will be using the Microsoft-Windows-TCPIP provider, which, in my case, seemed to be the main networking interface that was reaching the internet. As a note, there are many different providers you can choose from, so in the future, I will add the ability to choose the interface you would like to capture. But for this adventure, I chose Microsoft-Windows-TCPIP. Now to add the provider, we need to use the Add-NetEventPacketCaptureProvider command and pass it the name of our session. So now we have something similar to below.
Start-PacketCapture {
#Get Current Date & Time To Be Used To Name Session Capture
$DateStamp = Get-Date -Format "ddMMyyyyHHmmss"
$SessionName = -join("CaptureSession","",${DateStamp})
# Initialize Packet Capture Session
New-NetEventSession -Name $SessionName
# Adding Provider To Session, Default Should Be Microsoft-Windows-TCPIP But Will Add Option In Future
Add-NetEventProvider -Name “Microsoft-Windows-TCPIP” -SessionName $SessionName
}We’re now ready to start our capture, which is thankfully very simple. But before that, we’ll want to save our session object as a variable for use when parsing logs later. This saves us from having to find the log file deep within System32, or in this location, to be exact: C:\WINDOWS\system32\config\systemprofile\AppData\Local\NetEventTrace.etl. Note that currently, on my machine running Windows 11 22H2, Build 22621.1105, when I try opening that file location, File Explorer crashes. So, let me know if you experience the same.
Moving on, the rest of the logic is similar. I’m using the same if conditional statement. To start our packet capture, we’ll use the Start-NetEventSession command-let and once again pass it the session name. I have added the same sleep function as before, so that it runs for the amount of time we want, and then the capture ends with the Stop-NetEventSession command-let.
Start-PacketCapture {
#Get Current Date & Time To Be Used To Name Session Capture
$DateStamp = Get-Date -Format "ddMMyyyyHHmmss"
$SessionName = -join("CaptureSession","",${DateStamp})
# Initialize Packet Capture Session
New-NetEventSession -Name $SessionName
# Adding Provider To Session, Default Should Be Microsoft-Windows-TCPIP But Will Add Option In Future
Add-NetEventProvider -Name "Microsoft-Windows-TCPIP" -SessionName $SessionName
$time = Read-Host "Packet Capture Duration(Seconds)? "
# If time is set to 0 seconds then the script will run infinitely, well until the file hits 256 MB.
if ($time -eq "0") {
# Notify user that the packet capture is running
Write-Host "Infinite Packet Capture Is WIP"
}
else {
# Notify user that the packet capture is running for specified amount of seconds
Write-Host "Started The Packet Capture In The Background For ${time} Seconds"
# Start Packet Capture Job
Start-NetEventSession -Name $SessionName
# Use Timeout To Time The Capture
Start-Sleep -Seconds $time
# Stop The Packet Capture Job
Stop-NetEventSession -Name $SessionName
}
Remove-NetEventSession -Name $SessionName
}Here is where things get fun. We can now actually view our captured network data. Remember that Session Object we saved from before? We’ll use that, coupled with the Get-WinEvent command-let, to grab the logs and format them as a table. If everything has been done correctly, you will see the shell spew out a whole bunch of network events, in a somewhat human-readable format, similar to below.

Start-PacketCapture {
#Get Current Date & Time To Be Used To Name Session Capture
$DateStamp = Get-Date -Format "ddMMyyyyHHmmss"
$SessionName = -join("CaptureSession","",${DateStamp})
# Initialize Packet Capture Session
New-NetEventSession -Name $SessionName
# Adding Provider To Session, Default Should Be Microsoft-Windows-TCPIP But Will Add Option In Future
Add-NetEventProvider -Name “Microsoft-Windows-TCPIP” -SessionName $SessionName
# Saving Session Object That Contains Information About Where The Log File Is Located
$SessionObject = Get-NetEventSession -Name $SessionName
$time = Read-Host "Packet Capture Duration(Seconds)? "
# If time is set to 0 seconds then the script will run infinitely, well until the file hits 256 MB.
if ($time -eq "0") {
# Notify user that the packet capture is running
Write-Host "Infinite Packet Capture Is WIP"
}
else {
# Notify user that the packet capture is running for specified amount of seconds
Write-Host "Started The Packet Capture In The Background For ${time} Seconds"
# Start Packet Capture Job
Start-NetEventSession -Name $SessionName
# Use Timeout To Time The Capture
Start-Sleep -Seconds $time
# Stop The Packet Capture Job
Stop-NetEventSession -Name $SessionName
# Parse The Logs
$SessionObjectLog = Get-WinEvent -Path $SessionObject.LocalFilePath –Oldest
$SessionObjectLog | ft
}
Remove-NetEventSession -Name $SessionName
}Now, this is fun and all, but wait. If you ran the finalized code that I put above, you saw that it didn’t run “asynchronously,” meaning you didn’t have access to your shell when the scan was running. This is because, again, I ran into some issues. This time it had to do with actually printing out the results to the standard output from a background job. It’s possible to do this by using the Receive-Job command-let, but this only makes the script much more complicated. But it seems like I may not have any other choice, and so it’s something that I have decided will be one of the main focuses of my next blog where I can hopefully resolve this background job issue. Let me know what you guys think and leave any suggestions when it comes to the code. I’m far from being an expert programmer, I’m just a guy who likes computers. Big thanks to Ed Wilson and the article that helped me understand how the NetEventPacketCapture module works and how we can run a simple packet capture.
Catch you guys in the next one.
Discussion
No comments yet