RedBulletTooling / KEYVILBOARD

Repository for the KEYVILBOARD modules
https://www.keyvilboard.nl
MIT License
38 stars 10 forks source link

Clean code, add payloads and add leaking features #2

Closed illera88 closed 5 years ago

illera88 commented 5 years ago

In this PR we try to structure the code in a more clean way making it easier to contribute.

It adds:

RedBulletTooling commented 5 years ago

Thanks a lot! I'll check and verify the code tomorrow. Looks really cool what you guys made :).

RedBulletTooling commented 5 years ago

Hey, I just started testing the code and there were a few things I noted.

First thing is the the backspace function is now not working anymore. Before if a user pressed backspace, it was removed from the buffer that was send to the sms. Now if I type "abc" + backspace once, it sends "abc" instead of "ab". Is that intended?

Also when the SMS buffer is full, it spams the last pressed key like 15 times. The user will definitly notice this. To test this yourself => try to type a text of 500 chars, without stopping. You will see what I mean.

I did not test the remote execution features yet, as I had no more time today. For now I won't merge it, and I also don't recommend to use it yourself. As the main keylogging functionality is currently noticable unstable.

RedBulletTooling commented 5 years ago

Btw, for OS detection there is this very neat trick we found yesterday. Here is the PoC code. It detects the OS based on a communication request that is send to the USB bus. So very simple and the user will not be impacted by it in any way. Here is the link:

https://github.com/joelsernamoreno/PoC-BadUSB_DetectOS

0ca commented 5 years ago

That sounds very interesting, taking a look at the code it's not clear how with only one condition is able to differentiate between three OS. https://github.com/joelsernamoreno/PoC-BadUSB_DetectOS/blob/a9f390de0ab61f6f1326ac22d4ce84758cdf510e/libraries/FingerprintUSBHost/src/FingerprintUSBHost.cpp#L44 But I will test it to see if it detects my laptops correctly.

We are taking a look at the other issues.

0ca commented 5 years ago

The backspace should work now.

About the 500 chars I believe the problem is that the code was using too much memory. Arduino leonardo has a limited amount of memory ram (called dynamic memory) 2500 bytes. And the code was using ~70% of that RAM for local variables (a lot of strings). When the buffer has 500 characters (because the SIM card cannot send SMSs) the memory is too low and weird thing starts to happen.

I added F( to all the strings to force these strings to be defined in the CODE section instead of in the dynamic memory area. Now the code uses only the 26% of the dynamic memory so there is more space for the buffer to hold more characters. Still there is a problem if that buffer continue growing. So I have defined a variable with the max amount of characters that buffer can hold 1024. After that the program discards characters. (This would only happen if the keylogger can not send SMS). https://github.com/RedBulletTooling/KEYVILBOARD/pull/2/commits/8a09f5dded009b06ee26dfde128637b94608048d#diff-fb23d74c7141564e599c445fa2dcaea3R33

I would appreciate if you can test it a little bit. I don't have a keylogger with me at the moment.

Thank you for creating this device!

0ca commented 5 years ago

Btw, for OS detection there is this very neat trick we found yesterday. Here is the PoC code. It detects the OS based on a communication request that is send to the USB bus. So very simple and the user will not be impacted by it in any way. Here is the link:

https://github.com/joelsernamoreno/PoC-BadUSB_DetectOS

It doesn't work in my MacOs: https://github.com/keyboardio/FingerprintUSBHost/issues/5

RedBulletTooling commented 5 years ago

Nice, I'll test your code in the upcoming days! Regarding the fingerprint library; we tested it on a MacBook Air and multiple Windows machines. We did not encounter cases that the fingerprinting did not work. But it does seem that it is not fully stable on some Mac systems, like you experienced.

The library seems base the OS determination based on the descriptor length that is given during the session initialisation of the USB (which is different per OS). I think it is similair to how you can fingerprint systems based on the TTL in network data https://subinsb.com/default-device-ttl-values/.

It could be that in newer versions of MacOS that descriptor length has been changed. I'll try to debug it if I have time next week and look it there may be another trick that is more stable (although I think this is already quite solid).

0ca commented 5 years ago

Hi @RedBulletTooling, What version of MacOS do you have?

I added a commit to fix the detection for MacOs Mojave. It should also fixed this issue a user with MacOs Sierra had: https://github.com/keyboardio/FingerprintUSBHost/issues/5

I tested it on physical laptops on Windows 8./10, ubuntu 18 and MacOs Mojave (MacBook Pro and Air) and now it works for all of them. I'd appreciate if you could test it in your environment for double check.

Thanks!

RedBulletTooling commented 5 years ago

@0ca The Mac we used had Mojave installed. I'll double check it on our PC's upcoming saturday. I'll also test the changes made by @illera88 that saturday. Study related activities came up monday, so was not able to test it earlier than I intended to like I said in the previous comment.

RedBulletTooling commented 5 years ago

Hey,

Quick update on my testing.

First of all, really loving the code you guys wrote. It really adds cool features we didn't even thought of before.

The keylogging seems to be good now. Also the backspace function. The OS detection (Tested on two Windows machines, as that's the only devices I have) worked normally. So the essential functionality is working, at least during my testing. I also tested the Manual, UnlockDownload and UnlockRunAndExfil for Windows. I still need to test it for MacOS and Linux.

I had one issue tho with the WindowsUnlockAndRun. The powershell commando did not work on my laptop as you can see here:

image

When investigating this further I found that the commando syntax was not correct. The issue is in the $s variable. It was like this:

$s=(Get-WmiObject -Class Win32_PnPEntity -Namespace \"root\CIMV2\"-Filter \"PNPDeviceID like ÚSB\VID_2341^&PID_8036%'\").Caption;

And changing it to this worked:

$s=(Get-WmiObject -Class Win32_PnPEntity -Namespace \"root\CIMV2\"-Filter \"PNPDeviceID like 'USB\VID_2341&PID_8036%'\").Caption;

There was a ' missing before USB and the ^ before & was also not correct. If you have really good eyes, you can see the U is somewhat different. I was having a very weird issue as you can see here:

image

The U that is printed by the KEYVILBOARD has the hex value DA instead of 55. Or Ú instead of U. Which broke the command too. In the Arduino sketch there is a 55 U and I've not managed to find out why it corrupts to DA yet.

Did you also have issues with this commando?

illera88 commented 5 years ago

The ^ is the way to escape the &. I don't know how the É ended up there. It should be a regular E.

@0ca can you verify that?

On Sat, Jun 8, 2019, 8:21 AM RedBulletTooling notifications@github.com wrote:

Hey,

Quick update on my testing. The keylogging seems to be good now. Also the backspace function. The OS detection (Tested on two Windows machines, as that's the only devices I have) worked normally. So the essential functionality is working, at least during my testing. I also tested the Manual, UnlockDownload and UnlockRunAndExfil for Windows. I still need to test it for MacOS and Linux.

I had one issue tho with the WindowsUnlockAndRun. The powershell commando did not work on my laptop as you can see here:

[image: image] https://user-images.githubusercontent.com/45310844/59148672-2bc3be80-8a0c-11e9-9a2f-1b3dd8fb48c3.png

When investigating this further I found that the commando syntax was not correct. The issue is in the $s variable. It was like this:

$s=(Get-WmiObject -Class Win32_PnPEntity -Namespace "root\CIMV2"-Filter "PNPDeviceID like ÚSB\VID_2341^&PID_8036%'").Caption;

And changing it to this worked:

$s=(Get-WmiObject -Class Win32_PnPEntity -Namespace "root\CIMV2"-Filter "PNPDeviceID like 'USB\VID_2341&PID_8036%'").Caption;

There was a ' missing before USB and the ^ before & was also not correct. If you have really good eyes, you can see the U is somewhat different. I was having a very weird issue as you can see here:

[image: image] https://user-images.githubusercontent.com/45310844/59148980-ef925d00-8a0f-11e9-9f28-b353dde0a15f.png

The U that is printed by the KEYVILBOARD has the hex value DA instead of

  1. Or Ú instead of U. Which broke the command too. In the Arduino sketch there is a 55 U and I've not managed to find out why it corrupts to DA yet.

Did you also have issues with this commando?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/RedBulletTooling/KEYVILBOARD/pull/2?email_source=notifications&email_token=ABHT3KBCD4DXUQY7QHU3JULPZPE5ZA5CNFSM4HOYONUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXHWTHI#issuecomment-500132253, or mute the thread https://github.com/notifications/unsubscribe-auth/ABHT3KDQBYKJTJ3KZ2Y3QFTPZPE5ZANCNFSM4HOYONUA .

RedBulletTooling commented 5 years ago

@illera88 My bad, the ^ is indeed needed.

0ca commented 5 years ago

Hi,

I don't know why it types that Ú. In my testing it doesn't happen. I'm using Arduino Micro, maybe @illera88 can do a better testing.

I though that maybe it was because of your OS language and the behavior with accents, but the single quote shouldn't trigger that and it works well in other parts of the command.

0ca commented 5 years ago

Could you try to execute this code in the main loop and see if you get the Ú or 'U:

keyboard.println("'U");

May be it only happens when there is a vocal after the single quote when using a keyboard that is not english.

RedBulletTooling commented 5 years ago

@0ca Lol, it outputs Ú on my PC. You are indeed correct, I tried some of my keyboard settings and got these results: dd

RedBulletTooling commented 5 years ago

A possible fix could be to just add a wildcard like %, I tested it just now and that works on my end. The PNPDeviceID stays unique enough too, as the PID and VID are still in there, so the likelihood that the addtitional wildcard will cause trouble is negligible.

0ca commented 5 years ago

That sounds like a good solution.

Thank you for the testing!