
Detalhes do CVE-2020-14292
No aplicativo COVIDSafe até a versão 1.0.21 para Android, o uso inseguro da opção de transporte Bluetooth na conexão GATT permite que atacantes enganem o aplicativo para estabelecer uma conexão através do transporte Bluetooth BR/EDR, o que revela o endereço Bluetooth público do telefone da vítima sem autorização, contornando a proteção de aleatorização de endereço Bluetooth no telefone do usuário. Este problema é rastreado através de CVE-2020-14292.
A causa do problema está na função startWork, onde uma conexão GATT é feita usando connectGatt, mas nenhuma opção de transporte foi especificada.
fun startWork(
context: Context,
gattCallback: StreetPassWorker.StreetPassGattCallback
) {
gatt = device.connectGatt(context, false, gattCallback)
if (gatt == null) {
CentralLog.e(TAG, "Unable to connect to ${device.address}")
}
}
Isso fará com que o Android use a opção TRANSPORT_AUTO para o transporte ao iniciar a conexão Bluetooth. Parece que, na implementação no Android, isso assumirá o padrão BR/EDR se o periférico ao qual está se conectando for um dispositivo de modo duplo (suportando tanto BR/EDR quanto LE); isso pode ser devido à seguinte implementação do cliente GATT no Android, veja por exemplo, este código (trecho de código relevante incluído abaixo):
// Determine transport
if (transport_p != BT_TRANSPORT_AUTO) {
transport = transport_p;
} else {
switch (device_type) {
case BT_DEVICE_TYPE_BREDR:
transport = BT_TRANSPORT_BR_EDR;
break;
case BT_DEVICE_TYPE_BLE:
transport = BT_TRANSPORT_LE;
break;
case BT_DEVICE_TYPE_DUMO:
if (transport_p == BT_TRANSPORT_LE)
transport = BT_TRANSPORT_LE;
else
transport = BT_TRANSPORT_BR_EDR;
break;
}
Como a aleatorização do endereço MAC não é suportada em BR/EDR, o central revelará seu endereço de identidade para o periférico.
Para lançar um ataque, o atacante anuncia um servidor GATT em um dispositivo de modo duplo (BR/EDR + LE), usando o endereço público (esta parte é importante, caso contrário o downgrade não acontecerá e o central Android usará o transporte LE). Isso fará com que o aplicativo COVIDSafe use o transporte BR/EDR, em vez do transporte LE, para conectar-se ao periférico, o que então faz com que o endereço público do telefone seja revelado. Isso funciona para todos os telefones e versões do Android testados.
Para Android 6 e posteriores, a correção é simples: basta especificar a opção de transporte explicitamente.
gatt = device.connectGatt(context, false, gattCallback, BluetoothDevice.TRANSPORT_LE)
No entanto, isso não funciona para Android 5.1 (API Level 22), porque esse método não está exposto na API. Na verdade, ele está lá, mas está oculto. Então, para Android 5.1, uma possível correção envolve usar reflexão para chamar esse método oculto. Essas correções foram implementadas no COVIDSafe (Android) v1.0.48.
No entanto, a correção para Android 5.1 pode não funcionar 100% das vezes; meus testes indicaram que ainda havia vazamento de endereços de identidade. Isso pode ser devido à falha da técnica de reflexão em tempo de execução; mais investigações serão necessárias.
A posse do endereço de identidade de um telefone permitiria que um atacante rastreasse o telefone quando seu bluetooth estiver ligado e estiver dentro do alcance bluetooth do atacante. Algumas vulnerabilidades relacionadas ao bluetooth (por exemplo, CVE-2020-0022) dependem do conhecimento do endereço de identidade para montar ataques adicionais, portanto, há potencial para encadear este ataque com outros. Veja este documento para algumas das consequências do atacante possuir o endereço de identidade.
Recomenda-se fortemente que os usuários da versão Android do aplicativo COVIDSafe atualizem seu aplicativo. Para aqueles que usam Android 5, é recomendável desligar o bluetooth quando estiver em uma situação onde a funcionalidade bluetooth não for necessária.
Este problema foi relatado pela primeira vez à Australian Government Digital Transformation Agency em 2 de junho de 2020. A primeira correção foi lançada em 22 de junho de 2020, para Android 6 e superior. Foi confirmado que funciona para Android 6 e superior. Mas o problema ainda afetava o Android 5.1. A segunda correção, lançada em 30 de julho de 2020, resolveu o problema restante com o Android 5.1.
Agradecimentos a Jim Mussared por confirmar este problema de forma independente e por várias discussões relacionadas a este problema.