virtualabs / cc2531-killerbee-fw

Killerbee compatible ZigBee sniffer/injector firmware for TI CC2531 USB dongles
MIT License
39 stars 17 forks source link

Failed RX-TX transmission using Bumblebee with Killerbee #4

Closed wang70880 closed 3 years ago

wang70880 commented 3 years ago

Problem Description

When using KillerBee to make state transitions from sniffer mode to transmission mode, the bumblebee will crash and disconnect with KillerBee. A small piece of test codes is given as follows.

kb = KillerBee();
kb.set_channel(25);
kb.sniffer_on();
kb.sniffer_off();
while True:
  pkt = create_packet(); // Any packet you want. One can also use create_beacon() in zbfakebeacon to create beacon packets to test
  kb.inject(pkt);

Running the above test codes, Bumblebee can send packets for the first time. However, for the second time, exceptions are triggered.

  File "/usr/local/lib/python3.8/dist-packages/killerbee-3.0.0b0-py3.8-linux-aarch64.egg/EGG-INFO/scripts/zbfakebeacon", line 94, in <module>
    kb.inject(pkt)
  File "/usr/local/lib/python3.8/dist-packages/killerbee-3.0.0b0-py3.8-linux-aarch64.egg/killerbee/__init__.py", line 358, in inject
    return self.driver.inject(packet, channel, count, delay, page)
  File "/usr/local/lib/python3.8/dist-packages/killerbee-3.0.0b0-py3.8-linux-aarch64.egg/killerbee/dev_bumblebee.py", line 389, in inject
    self.send_packet(packet)
  File "/usr/local/lib/python3.8/dist-packages/killerbee-3.0.0b0-py3.8-linux-aarch64.egg/killerbee/dev_bumblebee.py", line 180, in send_packet
    self.send_message(
  File "/usr/local/lib/python3.8/dist-packages/killerbee-3.0.0b0-py3.8-linux-aarch64.egg/killerbee/dev_bumblebee.py", line 169, in send_message
    sent += self.dev.write(Bumblebee.EP_OUT, buf[i*64:(i+1)*64])
  File "/usr/lib/python3/dist-packages/usb/core.py", line 943, in write
    return fn(
  File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 819, in bulk_write
    return self.__write(self.lib.libusb_bulk_transfer,
  File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 920, in __write
    _check(retval)
  File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 595, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 19] No such device (it may have been disconnected)

Solution

In PROCESS cc2531_rf_sniffer, before calling radio_got_packet(), first check the sniffer state of the radio, i.e., g_radio_state in radio.c. radio_got_packet() is called only if g_radio_state.sniffer_enabled == SNIFFER ON

A fixed version is implemented in the latest commit of my repo . Please have a look first.

virtualabs commented 3 years ago

I'm afraid, I cannot reproduce this bug with the provided proof of concept. However, I agree with the fact the radio state must be checked before reading a packet. Still, I don't clearly understand the root cause of this bug.

virtualabs commented 3 years ago

Okay, I guess I know what's happening here. It looks like the radio stack is shut down when sniffer_off() is called, causing some issues when you need to send packets in the code after that. The radio must be on at all time, and as you suggested the sniffer must only notify receive packets when sniffer is on. It must discard them when sniffer is off, and fetch received packets to empty the RX buffer.

I also found some issues with the python code handling the device in Killerbee and will update my repo and send a PR to riverloopsec's repo.

Stay tuned, things will work better soon ;)

wang70880 commented 3 years ago

Great news. :)

I am sorry that previously I was too busy and didn't focus on this thread. I forgot to mention that if one commented the line kb.sniffer_off(), the above issue would disappear, which means that the issue lies in the calling of sniffer_off(). Now we have made agreements, and I am happy this issue is solved. I will close this thread. :-)