New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot enable monitor mode on an interface #1234

Open
ManiAm opened this Issue Jun 8, 2018 · 11 comments

Comments

Projects
None yet
5 participants
@ManiAm

ManiAm commented Jun 8, 2018

I purchased 6 different wifi adapters and connect them all to my computer through a USB hub. They all get recognized by the windows 10. I installed Npcap with 'support raw 802.11 traffic ...' checked and then use the wlanhelper to check how many of the wifi adapters support monitor mode (I do not enable monitor mode in wlanhelper).

Then I opened the wireshark:

2018-06-08_1-01-05

Those wifi interfaces that support monitor mode have a square box, but when I click on any of them, the check disappears after a couple of seconds.

Here are the WiFi USB adapters I am using.

2018-06-08_0-13-38

Here is the diag report. I am using windows 10 x64 and npcap 0.99-r5 with wireshark 2.6.1.

DiagReport-20180608-010421.txt

NPFInstall.log

install.log

@dmiller-nmap

This comment has been minimized.

dmiller-nmap commented Jun 13, 2018

I noticed this today as well. Npcap 0.99-r6 probably has the same issue. I was able to force it to work by using WlanHelper.exe (installed with Npcap):

  1. As an administrator run C:\Windows\System32\Npcap\WlanHelper.exe Wi-Fi mode monitor, where "Wi-Fi" is the name of the adapter in the Wireshark dialog.
  2. Start Wireshark. The adapter will be in monitor mode, without needing to check the monitor mode box.

When the capture is done, you can restore the adapter to "managed" mode using WlanHelper.exe also.

I'll be checking on this to see if we can fix it.

@ManiAm

This comment has been minimized.

ManiAm commented Jun 13, 2018

I followed your instruction, but the monitor box is still unchecked.

2018-06-12_22-37-25

2018-06-12_22-37-36

@dmiller-nmap

This comment has been minimized.

dmiller-nmap commented Jun 15, 2018

I'm working on this: the problem is between Npcap and Wireshark, but the adapter is really in monitor mode. You can verify this by running WlanHelper "Wi-Fi 7" mode and seeing that it prints "monitor". Obviously this is not ideal, and we'll be working to fix it, but I hope this is a suitable workaround for now.

@dmiller-nmap

This comment has been minimized.

dmiller-nmap commented Jun 15, 2018

@guyharris Can you help me find the relevant code in Wireshark for the monitor mode box? Where is it talking to Npcap (i.e. calls to libpcap or Packet.dll functions) after the box is checked that would cause it to uncheck the box? When it works correctly, it also changes the Link-layer Header column.

@guyharris

This comment has been minimized.

guyharris commented Jun 17, 2018

It's

        else if ( col == IFTREE_COL_MONITOR_MODE )
        {
            return device->monitor_mode_enabled ? Qt::Checked : Qt::Unchecked;
        }

in ui/qt/models/interface_tree_model.cpp in the current master branch.

But that's obviously not the relevant code. The monitor_mode_enabled member is set in a number of places, most of which either appear to set or clear it based on whether the user had checked it or clear it if it can't be determined whether the device supports setting monitor mode.

The latter determination is made by running dumpcap and reading its output. In the master branch, dumpcap is run with the arguments -i interface -L --list-time-stamp-types -I -M; if the first line is "0", monitor mode isn't supported, and if it's "1", monitor mode is supported, e.g.:

$ dumpcap -i en0 -L --list-time-stamp-types -I -M
1
127     IEEE802_11_RADIO        802.11 plus radiotap header
192     PPI     Per-Packet Information
105     IEEE802_11      802.11
163     IEEE802_11_RADIO_AVS    802.11 plus AVS radio information header
12      RAW     Raw IP

(that's macOS, running on the Wi-Fi interface on my MacBook Pro; it supports monitor mode, and can return any of the header types in question).

The routine get_if_capabilities() in caputils/capture-pcap-util.c is the routine that actually gets the interface's capabilities. In the 2.6 Windows version of Wireshark, that, and routines it calls, will:

  • call pcap_create() to try to open the device, and fail if the device can't be opened;
  • check whether the device is a Linux bonding device, which will never be the case on Windows, and if it's not, will call pcap_can_set_rfmon() to determine whether the device supports monitor mode, and fail if that call reports an error (rather than "yes" or "no");
  • if the device supports monitor mode, and get_if_capabilities() was told to determine the capabilities when in monitor mode, turn on monitor mode;
  • call pcap_activate() and fail if that fails;
  • get the default data link type by calling pcap_datalink();
  • call pcap_list_datalinks() to get the list of data link layers supported, and fail if that fails;
  • call pcap_close() and return.
@dmiller-nmap

This comment has been minimized.

dmiller-nmap commented Jul 13, 2018

Wireshark (or rather dumpcap.exe) uses the PacketSetMonitorMode function from Packet.dll for this, which in turn uses the WlanSetInterface function from wlanapi.dll, the Native Wifi API. This function requires administrator privileges to call, per Microsoft's documentation, Native Wifi API Permissions. WlanHelper instead uses OID requests passed through the Npcap driver down the NDIS stack to the WiFi card driver.

I'm not sure what the best approach will be, but for now you may be able to set monitor mode using WlanHelper.exe or by installing Npcap in Admin-only mode, which uses a helper program to request elevation to Administrator. Unfortunately, this requires a UAC prompt for each invocation of dumpcap.exe, which is a big hassle since Wireshark calls that a lot.

We'll be thinking and researching on this more.

@guyharris

This comment has been minimized.

guyharris commented Jul 13, 2018

Wireshark (or rather dumpcap.exe) uses the PacketSetMonitorMode function from Packet.dll for this,

Wireshark (or rather dumpcap.exe) uses the pcap_set_rfmon() function from libpcap/WinPcap/Npcap for this, and then calls pcap_activate() to open the capture device. Perhaps the activate routine in Npcap uses PacketSetMonitorMode() to turn on monitor mode if it has been requested with a pcap_set_rfmon() call.

WlanHelper instead uses OID requests passed through the Npcap driver down the NDIS stack to the WiFi card driver.

If you can put the adapter in monitor mode without requiring administrator privileges using OID requests, perhaps that's what the Npcap activate routine, or some routine in packet.dll, should be doing.

@dmiller-nmap

This comment has been minimized.

dmiller-nmap commented Jul 16, 2018

I need to correct a statement I made earlier: WlanHelper does not use a different method to set monitor mode. It was working for me because I was calling it in an Administrator command shell.

I am going to investigate possibly using the Npcap driver to set monitor mode, since that runs as privileged kernel code. The Packet.dll API would not need to change; this would be an implementation detail behind the scenes.

Remaining question to investigate: how well does Wireshark (or more specifically libpcap/wpcap) handle an interface that has already been put into monitor mode by e.g. WlanHelper?

@guyharris

This comment has been minimized.

guyharris commented Jul 16, 2018

Remaining question to investigate: how well does Wireshark (or more specifically libpcap/wpcap) handle an interface that has already been put into monitor mode by e.g. WlanHelper?

The way monitor mode is implemented is platform-dependent, so how well libpcap/Npcap handles putting into monitor mode an interface that's already in monitor mode is platform-dependent. (WinPcap doesn't handle monitor mode at all, so it's libpcap/Npcap).

On macOS, at the user-kernel boundary, the way you put an interface into monitor mode is to set the link-layer header type for the BPF device used for the interface to be one that provides 802.11 headers. The AirPort code appears to keep a count of the number of BPF devices that have requested it, with the adapter being in monitor mode if and only if the count is non-zero. libpcap implements this underneath the standard libpcap API for monitor mode.

On Linux, at the user-kernel boundary, if your adapter supports all the mac80211 stuff, the way you capture in monitor mode is that you arrange that there's a "virtual access point" (VAP) for the interface with an NL80211_ATTR_IFTYPE value of NL80211_IFTYPE_MONITOR, and bind that device to a PF_PACKET socket (the type of socket used for raw packet capture). As I remember, as long as there's at least one such VAP, the interface is in monitor mode. If libpcap is build with libnl (which it isn't, on most distributions), it will attempt to find a VAP of that type and use it and, if not, try creating one; if the pcap_t is closed, it'll delete the VAP if it created it. What it probably should do is have a daemon to create, destroy, and keep track of the VAPs, with a UNIX-domain socket between the daemon and libpcap, and with the client side of the UNIX-domain socket closed when the pcap_t is closed; that would also be closed if the process using libpcap terminated without closing the pcap_t, so the daemon would be able to detect that. This is on a long TODO list.

For *BSD, it currently turns monitor mode on if it's not already on, and, when the pcap_t is closed, turns it off if it had turned it on. This has issues, e.g. if the first process to turn monitor mode on closes its pcap_t before the second process to turn it on finishes with its pcap_t, monitor mode is turned off out from under the second process. Newer versions of FreeBSD appear to have a similar notion of "virtual access points" to Linux, and the code probably needs to be updated to handle them. This all probably needs the same type of daemon as Linux requires.

For Npcap, it works similarly to *BSD, using PacketGetMonitorMode() to determine whether the interface is in monitor mode and, if not, using PacketSetMonitorMode() to turn monitor mode on.

If the Npcap driver and packet.dll were to be changed, having the driver keep a count of the number of open instances that have requested monitor mode, ensuring that monitor mode remains on as long as the count is non-zero, and turning monitor mode off if the count goes to zero, would be quite useful, as it'd obviate the need for something in userland to keep track of such a count and wouldn't rely on userland not crashing before it has a chance to clean up. (The latter issue is at least one reason why the daemon in question might be appropriate on Linux and *BSD; the fact that the AirPort code in the kernel keeps such a count on macOS is why there isn't such an issue on macOS.)

@dmiller-nmap

This comment has been minimized.

dmiller-nmap commented Jul 16, 2018

In my testing, putting the adapter into monitor mode with WlanHelper.exe (run as Administrator) works well to capture with Wireshark. It's an unfortunately clumsy workflow, but at least it's there as a workaround.

@guyharris Thanks for the background! We did add per-instance tracking of hardware packet filters in 0.99-r6, so doing a similar thing with monitor mode would be reasonable.

@DarkwinX

This comment has been minimized.

DarkwinX commented Aug 16, 2018

I am currently testing with Windows 1803 172134.228
npcap 0.99-r7
Netgear A6210 with 1.0.0.39
Wireshark 2.6.2
However I am unable to get Wireshark to display anything when the adapter is set to monitor mode through wlanhelper (in admin mode). I don't think I have missed anything from your posts above. Also tested with driver/npcap versions as mentioned on the wiki as working.
image
DiagReport-20180816-205717.txt
install.log
NPFInstall.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment