RoganDawes / LOGITacker

Enumerate and test Logitech wireless input devices for vulnerabilities with a nRF52840 radio dongle.
GNU General Public License v3.0
657 stars 117 forks source link

Logitech unifying compatible keyboard with NRF24 #55

Closed bilogic closed 4 years ago

bilogic commented 4 years ago

Hi,

While I understand LOGITacker to be a sniffer tool, I was wondering if the expertise here can be re-purposed to create a logitech unifying compatible keyboard using the NRF24 via a Arduino/ESP8266/32.

I need info on the unifying RF protocol, especially on pairing and transmission of data. So far, I have some success with https://github.com/ronangaillard/logitech-mouse. Do also let me know if there is a better place to discuss this.

Thank you.

RoganDawes commented 4 years ago

Logitacker includes all the logic required to pair, as well as sending keystrokes, as far as I understand it. So this is a pretty reasonable place to discuss it if you want to.

On Sat, Apr 11, 2020, 13:03 bilogic notifications@github.com wrote:

Hi,

While I understand LOGITacker to be a sniffer tool, I was wondering if the expertise here can be re-purposed to create a logitech unifying compatible keyboard using the NRF24 via a Arduino/ESP8266/32.

I need info on the unifying RF protocol, especially on pairing and transmission of data. So far, I have some success with https://github.com/ronangaillard/logitech-mouse. Do also let me know if there is a better place to discuss this.

Thank you.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/RoganDawes/LOGITacker/issues/55, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABHBC34HZIN72IMXSLL3EDRMBFBBANCNFSM4MF6SY2Q .

bilogic commented 4 years ago

Cool, perhaps you can help point me in the right direction?

The code at https://github.com/ronangaillard/logitech-mouse managed to pair with the receiver, but as a keyboard instead of mouse. Furthermore, after pairing, the mouse does not move like documented. I'm thinking to get that sorted out before going to encrypted keyboard stuff.

There are some payload definitions for pairing at https://github.com/ronangaillard/logitech-mouse/blob/f29452d2ca9783224597d9dee1050bd4a14cfda5/logitech-mouse.h#L39, do you know where can I find the relevant material in this repo?

Thank you.

bilogic commented 4 years ago

I made some progress, but still 2 fundamental problems:

  1. Able to connect as a mouse now and it shows up in Logitech Unifying Software, however, sending mouse movement packets still cannot move the mouse

  2. Unable to reconnect, the code from logitech-mouse basically sends the same 4 pairing packets to reconnect, the 1st packet went through fine with a response 0:10:41:0:12:0:0:0:0:9D:9D:9D:9D:9D:9D:9D:9D:9D:9D:9D:9D:9D, however the 2nd packet does not get a response and timeout. Is sending the same 4 pairing packet the correct procedure to perform a re-connection for an already paired device?

After the timeout, my code restarts itself and on every 4th attempt, the response becomes 0:10:41:0:12:3F:13:0:0:4B:4B:4B:4B:4B:4B:4B:4B:4B:4B:4B:4B:4B for pairing packet 1.

Thank you.

bilogic commented 4 years ago

I fixed up the code, pairs as a mouse, reconnects and able to move cursor now. Also managed to pair as a keyboard, however, sending plain keystroke packets are not generating key presses on my PC.

Logitech Unifying Software is showing the orange badge on my device, i.e. packets are being received.

Any idea which devices accepts the following plain keystroke packets? I already set device type during pairing to be 0x4 (unifying compatible, no encryption).

The plain keystrokes packets I'm sending as follows:

uint8_t key_down[] = {0x0, 0xC1, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x22};
uint8_t key_up[] = {0x0, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F};

Thank you.

RoganDawes commented 4 years ago

You can send unencrypted keystrokes to the same endpoint as the mouse. If you want to send encrypted keystrokes, send to the keyboard endpoint.

On Sun, 12 Apr 2020 at 13:45 bilogic notifications@github.com wrote:

I fixed up the code, pairs as a mouse, reconnects and able to move cursor now. Also managed to pair as a keyboard, however, sending plain keystroke packets are not generating key presses on my PC.

Logitech Unifying Software is showing the orange badge on my device, i.e. packets are being received.

Any idea which devices accepts the following plain keystroke packets? I already set device type during pairing to be 0x4 (unifying compatible, no encryption).

The plain keystrokes packets I'm sending as follows:

uint8_t key_down[] = {0x0, 0xC1, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x22}; uint8_t key_up[] = {0x0, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F};

Thank you.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/RoganDawes/LOGITacker/issues/55#issuecomment-612602100, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABHBC76JPU2Z4ILH6UIO6DRMGSWBANCNFSM4MF6SY2Q .

bilogic commented 4 years ago

I paired as a mouse, it was able to move, but nothing happens when sending the key_down and key_up packets. Any idea where I should start looking?

bilogic commented 4 years ago

Based on the jargon of LOGITacker, my logs of REQ1, 2, 3 and RSP1, 2 and final in pairing as a mouse and subsequently sending key_down and key_up

Trying to .reconnect() with 49:16:90:09:AD
# Connecting step 4
Reconnect failed, going into pairing
Unable to reconnect to dongle... Pairing with any dongle...
# REQ1
- Radio check...
- Radio is available
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- Sending Packet: 15:5F:01:33:44:55:66:77:08:10:17:04:00:02:06:00:00:00:00:00:01:A6
- No response
- Sending BIS:    15:40:01:33:26
- Response:       15:1F:01:49:16:90:09:AE:08:88:02:04:01:02:06:00:00:00:00:00:00:86
- timeout is 0
- loop_counter is 246
- SUCCESS

# REQ2
- Radio check...
- Radio is available
- Sending Packet: 00:5F:02:00:00:00:00:AA:BB:CC:DD:04:00:00:00:01:DD:00:00:00:00:AF
- No response
- Sending BIS:    00:40:02:01:BD
- Response:       00:1F:02:0D:10:2C:91:AA:BB:CC:DD:04:00:00:00:01:00:00:00:00:00:F2
- timeout is 0
- loop_counter is 255
- SUCCESS

# REQ3
- Radio check...
- Radio is available
- Sending Packet: 00:5F:03:01:06:4D:4B:52:47:42:00:00:00:00:00:00:D4:00:00:00:00:50
- No response
- Sending BIS:    00:5F:03:01:0F
- Response:       00:0F:06:02:03:2C:91:AA:BB:C4:C4:C4:C4:C4:C4:C4:C4:C4:C4:C4:C4:C4
- timeout is 0
- loop_counter is 255
- SUCCESS

# Connecting step 4
- Saving our new MAC: 49:16:90:09:AE
Ready :)
RoganDawes commented 4 years ago

Make sure the format of the keystroke packet is correct?

I’ve not actually worked with LOGITacker or MouseJack at that low a level yet, but I imagine that the report should look pretty similar to a usb keyboard report.

1 byte modifier, 1 byte reserved (0x00), 6 bytes for down keys, or 0x00.

The whole prefixed with a report identifier or endpoint identifier.

Eg 0x04 for key A down.

On Sun, 12 Apr 2020 at 14:37 bilogic notifications@github.com wrote:

I paired as a mouse, it was able to move, but nothing happens when sending the key_down and key_up packets. Any idea where I should start looking?

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/RoganDawes/LOGITacker/issues/55#issuecomment-612607885, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABHBC526GOASMZAAA7BJEDRMGYXLANCNFSM4MF6SY2Q .

mame82 commented 4 years ago

On receiver's patched against MouseJack, a device paired as mouse would not be allowed to send unencrypted key strokes, even if it reports keyboard capabilities.

LOGITacker was updated to pair a keyboard with mouse capabilities, a while back, to account for this:

https://github.com/RoganDawes/LOGITacker/commit/f414073b8d8ecfa76d5001aeb7c6715576a0c378#diff-b840e312cca14ec76abcffbd87630d1fR199

bilogic commented 4 years ago

@mame82 I have 3 dongles

  1. C-U0007, 012.001.00019 - able to move as mouse, receives key packets, but keystrokes not received by OS
  2. C-U0007, 012.010.00032 - able to move as mouse, receives key packets, but keystrokes not received by OS
  3. C-U0008, 024.000.00018 - unable to pair

Any idea which is patched?

  1. and 3. should have no patches applied, both accept plain injection.
mame82 commented 4 years ago

Also LOGITacker always uses encrypted keyboard payloads, unless the receiver is a G700. The latter uses unencrypted payloads, although an encryption key is generated while pairing takes place.

For LIGHTSPEED (G900) receivers, not only keyboard payloads have to be encrypted, but HID++, too. This is to account for keyboard macro injection on the devices. Also LIGHTSPEED encryption is slightly different: it uses two AES CTR keys per transmitted frames.

bilogic commented 4 years ago

I did try encrypted keyboard payloads, but keystrokes not received by OS as well, I thought it was easier to make sure I got everything correct in plain text first. Let me try the encrypted payloads. I suppose it is pointless to try the C-U0008 dongle?

bilogic commented 4 years ago

f414073#diff-b840e312cca14ec76abcffbd87630d1fR199

Sorry, what is the key portion that I should be looking at here? Thanks!

mame82 commented 4 years ago

For mouse report format:

They differ between devices/receivers, f.e. X-/Y-Axes resolution could either be 8bit or 12bit.

Rogan is right: Keyboard and mouse payloads on RF are similar to resulting YSB HID reports. In addition the RF version includes headers, like:

mame82 commented 4 years ago

f414073#diff-b840e312cca14ec76abcffbd87630d1fR199

Sorry, what is the key portion that I should be looking at here? Thanks!

That the device type of the device to pair was changed from mouse to keyboard with this patch. The data structure is used to build/encode the pairing request

mame82 commented 4 years ago

It is currently not possible for me to provide all the info needed by you to do the correct payload encoding.

Suggestion:

Use two LOGITacker devices. Use one to pair a device, the other to sniff the pairing and you should get a good picture on how data has to be encoded. The rest is in the code

mame82 commented 4 years ago

Suggest read 1 (parsing of sniffed pairing requests/responses):

https://github.com/RoganDawes/LOGITacker/blob/master/logitacker/logitacker_pairing_parser.c

mame82 commented 4 years ago

Suggest read 2 (code used to generate requests for device pairing):

https://github.com/RoganDawes/LOGITacker/blob/master/logitacker/logitacker_processor_pair_device.c#L367

Also pay attention, that in between pairing request special frames are send one or multiple times, to pull a response from the receiver (response payload is part of ack frame). Pairing continues to the next step, once the respective response was received, otherwise the "pull" frame is sent again

bilogic commented 4 years ago

@mame82, I have managed to pair as a keyboard, this is the latest logs based on your remarks, I'm trying to generate the encrypted payloads now.

Trying to .reconnect() with 49:16:90:09:B0
# Connecting step 4
Reconnect failed, going into pairing
Unable to reconnect to dongle... Pairing with any dongle...
# REQ1
- Radio check...
- Radio is available
- Sending Packet: 15:5F:01:33:44:55:66:77:14:20:11:04:00:01:0D:00:00:00:00:00:01:8A
- Sending Packet: 15:5F:01:33:44:55:66:77:14:20:11:04:00:01:0D:00:00:00:00:00:01:8A
- Sending Packet: 15:5F:01:33:44:55:66:77:14:20:11:04:00:01:0D:00:00:00:00:00:01:8A
- Sending Packet: 15:5F:01:33:44:55:66:77:14:20:11:04:00:01:0D:00:00:00:00:00:01:8A

- No response
- Sending BIS:    15:40:01:33:26

- Response:       15:1F:01:49:16:90:09:B1:14:88:02:04:01:01:0D:00:00:00:00:00:00:71
- timeout is 0
- loop_counter is 252
- SUCCESS
# REQ2
- Radio check...
- Radio is available
- Sending Packet: 00:5F:02:00:00:00:00:AA:BB:CC:DD:04:00:00:00:01:DD:00:00:00:00:AF

- No response
- Sending BIS:    00:40:02:01:BD

- Response:       00:1F:02:16:F1:CB:FE:AA:BB:CC:DD:04:00:00:00:01:00:00:00:00:00:FC
- timeout is 0
- loop_counter is 255
- SUCCESS
# REQ3
- Radio check...
- Radio is available
- Sending Packet: 00:5F:03:01:06:4D:4B:52:47:42:00:00:00:00:00:00:D4:00:00:00:00:50

- No response
- Sending BIS:    00:5F:03:01:0F

- Response:       00:0F:06:02:03:CB:FE:AA:BB:B8:B8:B8:B8:B8:B8:B8:B8:B8:B8:B8:B8:B8
- timeout is 0
- loop_counter is 255
- SUCCESS
# Connecting step 4
- Saving our new MAC: 49:16:90:09:B1
Ready :)
bilogic commented 4 years ago

I think my question is, I managed to pair as a keyboard, my challenge is in generating the encrypted payload. Can I ask why you are suggesting I read the pairing code? Are you suspecting I missed something?

I have gotten through REQ1, 2, 3 and RSP1, 2, 3 (Final).

mame82 commented 4 years ago

In addition, here's an outdated and incomplete analysis of a SDR captured pairing (most recent and complete info is in LOGITacker code):

https://github.com/mame82/UnifyingVulnsDisclosureRepo/blob/master/documents/pairing_sdr_capture_full_analysis_incomplete.txt

bilogic commented 4 years ago

In addition, here's an outdated and incomplete analysis of a SDR captured pairing (most recent and complete info is in LOGITacker code):

https://github.com/mame82/UnifyingVulnsDisclosureRepo/blob/master/documents/pairing_sdr_capture_full_analysis_incomplete.txt

Yes, I have been running through all these docs today which is why I managed to pair and move the OS mouse cursor. Am I missing something in the pairing? I'm thinking to just dive straight to the encrypted payloads.

mame82 commented 4 years ago

I think my question is, I managed to pair as a keyboard, my challenge is in generating the encrypted payload. Can I ask why you are suggesting I read the pairing code? Are you suspecting I missed something?

I have gotten through REQ1, 2, 3 and RSP1, 2, 3 (Final).

Only to assure you fully understand the meaning of device type vs capabilities

A device could be a mouse with keyboard features or the other way around.

mame82 commented 4 years ago

For payload encryption/decryption look here:

https://github.com/RoganDawes/LOGITacker/blob/master/logitacker/logitacker_unifying_crypto.c

bilogic commented 4 years ago

Only to assure you fully understand the meaning of device type vs capabilities A device could be a mouse with keyboard features or the other way around.

I have device type as 0x1 (keyboard) and caps as 0x5 (unifying + encryption). All good yes?

bilogic commented 4 years ago

I'm just after unifying, not lightspeed. Does it make more sense for me to just look at logitacker_devices.c for the keyboard frames encryption? https://github.com/RoganDawes/LOGITacker/blob/cbc3c5adb35817fd7da657af743123a7d99e7cf9/logitacker/logitacker_devices.c#L823

Or do I have to go to logitacker_unifying_crypto.c? https://github.com/RoganDawes/LOGITacker/blob/master/logitacker/logitacker_unifying_crypto.c

Thanks.

bilogic commented 4 years ago

Ok, I think I know why my earlier encrypted payloads did not work, I merely copied the SDR captured payloads. I need to derive my device_key and encrypt my own payloads.

bilogic commented 4 years ago

I need some help:

  1. What is the initial value of the AES counter? 0?
  2. What should be the size of len_out be? I'm getting 44 https://github.com/RoganDawes/LOGITacker/blob/299d985eeb3cdeacce45ee8c8e6b1f3da821c2cc/logitacker/logitacker_unifying_crypto.c#L24

Thank you.

bilogic commented 4 years ago

Hi,

I have confirmed my AES ECB encryption from .2 to .3 is correct using http://aes.online-domain-tools.com/

Can help me check if the plain rf_frame in .4 is correct? I'm using counter value of 0x00000010 for keydown and and 0x00000011 for keyup

Sending a keydown 0x4 which I understand is an "a" https://github.com/insecurityofthings/jackit/blob/ee0bee854d544e0ee97d559604b4a673866db01e/jackit/keymap.py#L1060 .5 is basically XOR .4 with .3 I'm also sending keyup after that.

Currently, my OS does not receive any keys. Thank you.

1. device_key:          02:A1:84:A2:22:C5:66:92:44:88:27:10:F3:51:25:11
2. plain l_k_s+counter: 04:14:1D:1F:27:28:0D: 00:00:00:10 :0A:0D:13:26:0E
3. frame_key:           E2:51:33:9F:ED:F8:24:98:84:83:56:92:26:E9:F4:13
4. plain rf_frame:      00:D3: 00:04:00:00:00:00:00:C9 :00:00:00:10 :00:00:00:00:00:00:00:00
5. encrypted rf_frame:  00:D3:E2:55:33:9F:ED:F8:24:51 :00:00:00:10 :00:00:00:00:00:00:00:BA

1. device_key:          02:A1:84:A2:22:C5:66:92:44:88:27:10:F3:51:25:11
2. plain l_k_s+counter: 04:14:1D:1F:27:28:0D: 00:00:00:11 :0A:0D:13:26:0E
3. frame_key:           4E:B3:F3:E0:65:D8:1F:A1:19:5F:CF:0B:47:09:07:45
4. plain rf_frame:      00:D3: 00:00:00:00:00:00:00:C9 :00:00:00:11 :00:00:00:00:00:00:00:BA
5. encrypted rf_frame:  00:D3:4E:B3:F3:E0:65:D8:1F:68 :00:00:00:11 :00:00:00:00:00:00:00:84
bilogic commented 4 years ago

I'm trying to respond to the 10 bytes ACK + payloads documented here slide 39 of 86 https://initrd.net/stuff/mousejack/doc/pdf/DEFCON-24-Marc-Newlin-MouseJack-Injecting-Keystrokes-Into-Wireless-Mice.slides.pdf

Where can I find the code that decodes them?

1. 00:10:ce:00:12:3f:13:00:00:be
2. 00:10:ce:00:12:00:00:00:11:ff

Thank you.

bilogic commented 4 years ago

Sorry about the earlier post, my alt key was virtually stuck from all the hacking. The dongle still ignores my encrypted keyframes. Any help is greatly appreciated. In particular, where do I actually start AES counter?

I managed to hack together a sniffer and captured the following, of interest is 2nd line, CH: 62. That was transmitted from my actual K800 keyboard, this is unseen in any documentation I have covered so far. Any idea?

[CH: 35]  49:16:90:09:E4  00 40 00 14 AC (5 bytes) - Logitech 
[CH: 62]  49:16:90:09:00  E4 D3 C8 2C 86 A8 40 B2 ED DD F9 EB DE D1 00 00 00 00 00 00 00 D8 (22 bytes)
[CH: 71]  49:16:90:09:E4  00 D3 DC 97 5B 66 55 B6 D1 87 FA EB DE D1 00 00 00 00 00 00 00 02 (22 bytes) - Logitech        
[CH: 78]  49:16:90:09:E4  00 D3 DC 97 5B 66 49 AA D1 87 FA EB DE D1 00 00 00 00 00 00 00 1A (22 bytes) - Logitech        
[CH: 32]  49:16:90:09:E4  00 D3 DC 97 5B 66 7A 85 D1 87 FA EB DE D1 00 00 00 00 00 00 00 0E (22 bytes) - Logitech        
[CH: 35]  49:16:90:09:E4  00 D3 DC 97 5B 66 7A 85 D1 87 FA EB DE D1 00 00 00 00 00 00 00 0E (22 bytes) - Logitech        
[CH: 65]  49:16:90:09:E4  00 D3 DC 97 5B 66 55 B6 D1 87 FA EB DE D1 00 00 00 00 00 00 00 02 (22 bytes) - Logitech        
[CH: 74]  49:16:90:09:E4  00 D3 DC 97 5B 66 7A 85 D1 87 FA EB DE D1 00 00 00 00 00 00 00 0E (22 bytes) - Logitech        
mame82 commented 4 years ago

Sorry about the earlier post, my alt key was virtually stuck from all the hacking. The dongle still ignores my encrypted keyframes. Any help is greatly appreciated. In particular, where do I actually start AES counter?

I managed to hack together a sniffer and captured the following, of interest is 2nd line, CH: 62. That was transmitted from my actual K800 keyboard, this is unseen in any documentation I have covered so far. Any idea?

[CH: 35]  49:16:90:09:E4  00 40 00 14 AC (5 bytes) - Logitech 
[CH: 62]  49:16:90:09:00  E4 D3 C8 2C 86 A8 40 B2 ED DD F9 EB DE D1 00 00 00 00 00 00 00 D8 (22 bytes)
[CH: 71]  49:16:90:09:E4  00 D3 DC 97 5B 66 55 B6 D1 87 FA EB DE D1 00 00 00 00 00 00 00 02 (22 bytes) - Logitech        
[CH: 78]  49:16:90:09:E4  00 D3 DC 97 5B 66 49 AA D1 87 FA EB DE D1 00 00 00 00 00 00 00 1A (22 bytes) - Logitech        
[CH: 32]  49:16:90:09:E4  00 D3 DC 97 5B 66 7A 85 D1 87 FA EB DE D1 00 00 00 00 00 00 00 0E (22 bytes) - Logitech        
[CH: 35]  49:16:90:09:E4  00 D3 DC 97 5B 66 7A 85 D1 87 FA EB DE D1 00 00 00 00 00 00 00 0E (22 bytes) - Logitech        
[CH: 65]  49:16:90:09:E4  00 D3 DC 97 5B 66 55 B6 D1 87 FA EB DE D1 00 00 00 00 00 00 00 02 (22 bytes) - Logitech        
[CH: 74]  49:16:90:09:E4  00 D3 DC 97 5B 66 7A 85 D1 87 FA EB DE D1 00 00 00 00 00 00 00 0E (22 bytes) - Logitech        

2nd frame seems malformed, so ignore it.

All frames are directed device to dongle, thus the device index is 0x00 (offset 0)

Offset 1 is the report type (this byte actually is a mix of a bit mask and a type field, but I won't go into great detail here, just keep in mind that the bit6 == 0x40 means keep-alive if set)

The rest is payload, length depends 9n report type, the very last byte is an 8bit Logitech CRC.

The first report of type 0x40 is a pure keep-alive with the 2 byte payload 0x0014 (=20ms till next keep alive).

The next reports of type 0xD3 are encrypted keyboard payloads, but they look wrong to me. The first 8 payload bytes (DC 97 ... should be the encrypted keyboard report. The successive 4 bytes (FA EB DE D1) are the 32 bit counter.

Now here the counter is constant, instead of counting up ... this works only for receivers still vulnerable to Keyjack (counter reuse).

The 8 encrypted bytes reflect this (data looks the same except one or two bytes == same key used for each frame).

The bytes which change are at offset 4 and 5 of the encrypted payload. Although this could work (for keyjack), it looks weird to me, as those would map to HID key 4 and 5 of the plain (out of 6 HID keys which could be pressed at the same time)

I assume the report which has 0x85 as encrypted key is a key release (because it occurs repeatedly), but having two adjacent releases is still weird. This simply looks wrong to me.

For sure this data is not generated by LOGITacker

bilogic commented 4 years ago
  1. I forgot to mention that uc-mousejack was used to capture the packets from keys being pressed on an unpaired K800, a real logitech device
  2. I suspect the counter of the frames 3 and onwards do not increase because the packets were not transmitted succesfully, i.e. no ACK received
  3. Now for the interesting part, if frame 2 was malformed, it seems too coincidental that
    • the CRC is valid
    • the counter incremented by 1 on frame 3
    • I also managed to capture a similar packet from an unpaired M510, another real logitech device [CH: 35] 6F:B8:96:D6:00 6F C2 00 00 00 00 00 00 00 CF (10 bytes)
    • the RF address prefix and first byte of the payload is swapped
    • I have not seen any other malformed packets (assuming there is a bug in uc-mousejack)
  4. I also managed to force pair with a 012.001.00019 C-U0007 dongle, i.e. paired without having to put the dongle into pairing mode
  5. In the force paired case, the OS receives my encrypted keystrokes, this validates that my encryption routines are correct
  6. Taken togther, I opine that my issue of OS not receiving encrypted keystrokes is due to an improper pairing/reconnection process
  7. Right now, my code tries to pair on channel 5 upon power up, if that fails, it tries to connect by sending a set timeout packet, let's call this pairing method A
  8. Method A only works if the dongle has no paired devices or if I'm the only paired device. If there is already another paired device, sending a set timeout packet fails, i.e. no ACK received.
  9. Has anyone documented how real logitech devices pair and subsequently reconnect? I suspect that frame 2 might give us some clues
  10. How is the device firmware and battery information transmitted? The closest I have seen is the ACK + payload from Marc Newlin, but no explanation on how to decode.
  11. I do not rule out that frame 2 could indeed be malformed, but there are too many coincidences
mame82 commented 4 years ago

You got all the information required to answer your questions (either in code or on comments).

  1. Wrong place
  2. Wrong
  3. Wrong
  4. Cannot see relevance of forced pairing here
  5. Not really, it confirms that the receiver is old enough to accept counter re-use, too and gives a shit on correct crypto.
  6. Based on wrong assumptions
  7. Not efficient, channel where the dongle sends ACKs should be used
  8. You have errors in your implementation, the implementation in this repo has no such issues
  9. It is fully reversed and implemented here
  10. You have to analyze the content of the payloads. Both, Marc and me, gave hints on where to start searching in recorded talks.
  11. No such frames are common, as we are talking about RF
mame82 commented 4 years ago

None of the described issues applies to LOGITacker. Pairing and device emulation is implemented correctly and confirmed to be working

bilogic commented 4 years ago

Yes, I do apologize that my questions are not specific to LOGITacker, but this seems to be the only place that has the expertise.

Thanks to your guidance, I managed to work out all the issues except 1, if you could please bear with me for just 1 last question, I would most appreciate it.

  1. How is the initial value of the AES counter established for real Logitech devices at every power up?

When using the latest patched dongles C-U0007, 012.010.00032, I know that:

Just to be clear, I'm not trying to impersonate the paired Logitech K800, instead my device is pairing as itself and has gotten to the point where battery levels, charge status and firmware are showing up correctly in the Unifying software. I also know that my AES_ECB routines are correct because keystrokes show up on the OS when paired with a vulnerable dongle, 012.001.00019. What remains seems to be the logic behind this elusive AES counter value.

Thank you.

mame82 commented 4 years ago

Start counter after power cycle is totally random.

I'm pretty sure your encryption is broken or - to be more precise - the cipher in use for the specific frame does not match the counter

mame82 commented 4 years ago

Also I forgot to reference my talk on the topic. It includes details on Unifying crypto.

https://vimeo.com/378870549

The slides are linked in the video comments (pay attention to the ones illustrating the key generation and the counter re-use issues

bilogic commented 4 years ago

I'm pretty sure your encryption is broken or - to be more precise - the cipher in use for the specific frame does not match the counter

Thanks for the talk, it did not appear in any of my earlier searches. I'm trying to understand your statement. Please see my highly abbreviated pseudo code below.

  1. Did you mean that my C1 does not match C2?
cipher = AES_ECB(device_key, merge(little_known_secret, C1))
payload = XOR(plain, cipher)
rf_frame = concatenate(payload, C2)

I checked, and C1 == C2. I mean, if they were different, it would be impossible for the vulnerable dongle to decode the rf_frame, correct?

Thank you.

bilogic commented 3 years ago

You can send unencrypted keystrokes to the same endpoint as the mouse. If you want to send encrypted keystrokes, send to the keyboard endpoint.

@RoganDawes I'm re-visiting this issue in hopes of completing my project. What did you mean by endpoint? Thank you.

RoganDawes commented 3 years ago

I suggest you read Marc Newlin's Mousejack paper. (I really should have read it too! :-) )

DEFCON-24-Marc-Newlin-MouseJack-Injecting-Keystrokes-Into-Wireless-Mice.whitepaper.pdf

When saying endpoint, I should have said dongle address, using an Unencrypted Keystroke Payload packet format (table 8)

bilogic commented 3 years ago

@RoganDawes I see. Thanks.

Yes I have gone through all the materials but still unable to find out what I'm missing. My project behavior is as follows:

  1. Sending encrypted keystrokes to C-U0007, 012.001.00019 - working
  2. Sending encrypted keystrokes to C-U0007, 012.001.00032 - not working

Would you be able to confirm that C-U0007, 012.001.00032 accepts encrypted payloads from LOGITacker? Thank you.

P.S. Pt 1 means that I'm able to encrypt properly, so I wouldn't question the encryption routines unless the encryption has changed in .00032, which I'm certainly not aware of.

RoganDawes commented 3 years ago

I'm afraid not. My understanding of the LOGItacker codebase is severely lacking.

On Wed, 21 Oct 2020 at 14:08, bilogic notifications@github.com wrote:

@RoganDawes https://github.com/RoganDawes I see. Thanks.

Yes I have gone through all the materials but still unable to find out what I'm missing. My project behavior is as follows:

  1. Sending encrypted keystrokes payload C-U0007, 012.001.00019 - working
  2. Sending encrypted keystrokes payload C-U0007, 012.001.00032 - not working

Would you be able to confirm that LOGITacker is able to transmit encrypted payloads to C-U0007, 012.001.00032? Thank you.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/RoganDawes/LOGITacker/issues/55#issuecomment-713522457, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABHBCYJDXF5KNKSGBAN7A3SL3FNRANCNFSM4MF6SY2Q .