Golang and Windows Network Interfaces

I have been working on Windows and needed to connect to a Network Interface (NIC). I ran into problems, here is what I learned and hope it saves the same trouble I had in troubleshooting.

TL;DR: Do not use friendly names (Ethernet/eth0) for Windows NICs. Prepend "\Device\NPF_ to the interface GUID found from getmac.

Why Connect to a Windows NIC?

Creating TCP sockets or web sockets does not involve connecting to a network interface specifically. It involves listening or dialing with an IP address and a port. Such as:

1
2
3
4
5
6
	CONNECT := "192.168.1.1:9999"
	c, err := net.Dial("tcp", CONNECT)
	if err != nil {
		fmt.Println(err)
		return
	}

But if you wanted to use the Gopacket package and create your own packets, or read packets from the network, connecting to a Windows NIC is needed. This is where some code connecting to a NIC is needed:

1
2
 device       string = "eth0"
 handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)

A great breakdown of the gopacket package can be found here It covers:

  • Finding devices
  • Opening devices (Does not work on Windows, hence this post)
  • Writing a Pcap File
  • Reading and Writing packets
  • and more

The Issue with a Windows NIC

In Linux as shown above, the name eth0 or equivalent can be used to connect to the NIC.

In short:

  • The ifconfig output in Linux is also the name
    • This is not the case in Windows

The ipconfig output on Windows is not the name to be used within Gopacket.

If you add the Windows NIC name from that output, you will receive the following error:

  • No such device exists

This is a known issue:

Fixing the issue

Running getmac in the Windows command-line will show the name that can be appended:

So the full line would become:

  • \\Device\\NPF_{6DXXX78X-2267-4XX9-938F-1243F92XXX64}
    • X’s for redaction
    • Double back slash for escaping in Go

In Go format it would look like:

1
2
3
4
5
6
7
8
9
10
var (
	device       string = "\\Device\\NPF_{6DXXX78X-2267-4XX9-938F-1243F92XXX64}"
	snapshot_len int32  = 1024
	promiscuous  bool   = false
	err          error
	timeout      time.Duration = 30 * time.Second
	handle       *pcap.Handle
	buffer       gopacket.SerializeBuffer
	// options      gopacket.SerializeOptions
)

Once fixed the code should use the Windows NIC:

Getting The Correct NIC Name in Go

Within Gopacket the pcap.FindalDevs() Will get the correct name.

So Go code such as the below, will print out the correct names needed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
	"fmt"
	"log"

	"github.com/google/gopacket/pcap"
)

func main() {
	// Find all devices
	devices, err := pcap.FindAllDevs()
	if err != nil {
		log.Fatal(err)
	}

	// Print device information
	fmt.Println(devices)
	fmt.Println("Devices found:")
	for _, device := range devices {
		fmt.Println("\nName: ", device.Name)
	}

}

Adding device.Description and printing the IP address will help in better identification:

1
2
3
4
5
6
7
	fmt.Println("Devices found:")
	for _, device := range devices {
		fmt.Println("\nName: ", device.Name)
		fmt.Println("Description: ", device.Description)
		for _, address := range device.Addresses {
			fmt.Println("- IP address: ", address.IP)
		}

Where as using net.Interfaces() will get the ‘friendly name’. This is NOT usable for connecting to a Windows NIC with gopacket.

Which will look like:

1
2
3
4
5
6
7
func main() {

	infs, _ := net.Interfaces()
	for _, f := range infs {
		fmt.Println(f.Name)
	}
}

This will print the friendly names:

Reasoning For The Issue:

Reading the links that I had found had identified the issue and that a correct interface name was in the format of \Device\NPF_{GUID}

GUID stands for a globally unique identifier which is used by system drives and other components for identification.

\Device\NPF_ is the device volume name. Windows uses its own underlying non-username, indicating the devices PCI bus address.

This article explains that the GUID can be found in the registry such as HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}.

  • Please note: Looking in my registry my interface GUIDs from getmac didn’t match what was in the registry.

The article also explains that “NPF is a driver which stands for NetGroup Packet Filter Driver. It turns out NPF is a vital part of the Windows Packet Capture (WinPcap) process”.

This helps explain why simply using ipconfig to grab a Windows NIC name will not work.

2021

Connect to Splunk with Python

This post will cover the following: Connecting to Splunk with the Python SDK, executing a search and receiving the results Connecting to Splunk without ...

Back to Top ↑

2020

Winlogbeat & ELK

TL;DR: Create Logstash conf.d file to allow Winlogbeat to be ingested into Logstash. Change Winlogbeat config file to use Logstash instead of Elasticsearch.

Golang and Windows Network Interfaces

I have been working on Windows and needed to connect to a Network Interface (NIC). I ran into problems, here is what I learned and hope it saves the same tro...

Tcpdump Notes

I have been using tcpdump recently and wanted to note down some of the commands Y’know, for future reference.

Pivoting with SSH

Today I was trouble shooting a machine at work. I did not have access via RDP or VNC, so I used SSH to forward my traffic to the host so I could access a URL.

GitHub Actions

I participated in a DevSecOps type workshop on Saturday (May 9th) in which we created some GitHub Actions. This is a post to solidify the learning and be a c...

Threat Defense Workshop

On April 25th I was fortunate enough to participate in the Trend Micro Threat Defense workshop.

Incident Handling Certification

Since I blogged about my experience at OpenSoc, I wanted to expand on the value I found in my eLearnSecuirty Incident Response course. What you will find bel...

OpenSoc Experience

So Thursday (April 9th) I participated in an online blue team defense simulation event, known as OpenSOC.

Golang Parsing Strings

I have been working with Golang strings and how to manipulate them. Working from other blogs posts I’ve found. When I sit down to code, I seem to forget ever...

Welcome to Jekyll!

You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different wa...

Back to Top ↑