RCayre / mirage

Mirage is a powerful and modular framework dedicated to the security analysis of wireless communications.
https://homepages.laas.fr/rcayre/mirage-documentation
MIT License
245 stars 42 forks source link

"File descriptor in bad state" by high frequency sending of packages #11

Open dennisarmbruster95 opened 3 years ago

dennisarmbruster95 commented 3 years ago

Hey @RCayre i discovered during my work with Mirage that "too fast" sending overloaded Scapy's supersocket and put it in an invalid state. For explanation and demonstration, here is a scenario for the ble_mitm module, which sends 100 BLEHandleValueNotification at the push of a button:

from mirage.core import scenario
from mirage.libs import io,ble,esb,utils

package = ble.BLEHandleValueNotification(handle=43, value=bytes.fromhex("00000000000000"))
class SpamNotification(scenario.Scenario):

def onStart(self):
    return True

def onEnd(self):
    return True

def onKey(self,key):
    if self.module.a2mEmitter is not None:
        io.info("SpamNotification is sending...")
        packages = [package for x in range(100)]
        self.module.a2mEmitter.sendp(*packages)
    return True

The traceback follows, the exception provoked by the scenario:

Traceback (most recent call last): File ".../mirage/mirage/libs/wireless_utils/packetQueue.py", line 19, in run self._target(*(self._args)) File ".../mirage/mirage/libs/wireless.py", line 88, in _task self._send(data) File ".../mirage/mirage/libs/wireless.py", line 52, in _send self.device.send(data) File ".../mirage/mirage/libs/bt.py", line 99, in send self.socket.send(data) File ".../mirage/venv/lib/python3.8/site-packages/scapy/supersocket.py", line 49, in send sent = self.outs.send(sx) OSError: [Errno 77] File descriptor in bad state

This error happens regularly when the scenario is executed by pressing a key, as declared in the function onKey. The send function from scapy/supersocket.py throws the exception and occurs for the first time in mirage/libs/bt.py within mirage. The send function used there passes the packet to scapy's supersocket without checking its state. Checking the state of the supersocket is a possible idea if scapy allows it. An alternative suggestion is to adjust the processing speed of the queue within libs/wireless_utils/packetQueue.py.

Best regards,

@da84