
CVE-2026-36355: Realtek rtl819x Jungle SDK - 디버그 ioctl을 통한 인증되지 않은 커널 메모리 읽기/쓰기
Realtek rtl819x out-of-tree "Jungle SDK"의 rtl8192cd Wi-Fi 커널 드라이버는 액세스 제어 검사 없이 write_mem(0x89F5) 및 read_mem(0x89F6)이라는 두 개의 IOCTL을 노출한다. 드라이버가 지원하는 무선 네트워크 인터페이스를 열 수 있는 모든 로컬 사용자는 임의의 커널 가상 메모리를 읽거나 쓸 수 있으며, 이는 직접적으로 root 권한으로 이어진다.
해당 핸들러는 8192cd_cfg.h의 _IOCTL_DEBUG_CMD_에 의해 제어되는데, 이 매크로는 조건 없이 정의되므로(#ifdef DEBUG 없음) 디버그 명령 집합이 모든 프로덕션 빌드에 컴파일된다.
참조 익스플로잇(kpwn)은 비특권 셸에서 uid=0을 달성하며 하드코딩된 주소가 전혀 없다. task_struct 레이아웃과 init_task 위치는 모두 런타임에 자동 감지되므로 다양한 커널 버전과 OEM 빌드에서 이식 가능하다.
이 취약점은 Realtek rtl819x Jungle SDK 커널 Wi-Fi 드라이버에 존재하며, v3.4.14B까지의 모든 알려진 버전이 영향을 받는다. 공개 시점 기준 수정 사항은 없다. 메인라인 Linux rtlwifi / rtw88 / rtw89는 다른 코드베이스이며 영향을 받지 않는다.
공유 드라이버 코어는 여러 변형(rtl8192cd, rtl8192es, rtl8192ee, rtl8192fe, rtl8188ee 등)으로 컴파일된다. Wi-Fi 드라이버를 포함하는 모든 Jungle SDK 빌드가 영향을 받는다.
Realtek Jungle SDK는 OEM 계약에 따라 널리 재배포된다. CVE-2021-35395 공급업체 목록(동일 SDK의 다른 사용자 공간 구성 요소를 대상으로 했음)에 문서화된 공급업체로는 D-Link, TOTOLINK, Tenda, NEC, I-O DATA, Elecom, Buffalo, Humax, H3C 및 IP-COM이 있다. 각 특정 제품 라인이 취약한 커널 드라이버를 탑재하는지 여부는 제품별 GPL 소스 릴리스를 검토해야 알 수 있다. 본 권고는 독립적인 검증 없이 이를 단정하지 않는다.
| 장치 | Ortel 4G LTE CPE (OEM: MeiG Smart FORGE_SLT711) |
| SoC | Qualcomm MDM9607, ARMv7 Cortex-A7 |
| 커널 | Linux 3.18.48 |
| 모듈 | rtl8192es.ko |
확인됨: 모듈 .bss에 0xDEADBEEF를 쓰고 읽어 검증한 후 복원함. 비특권 셸에서 init_task 탐색 및 자격 증명 덮어쓰기를 통해 uid=1000에서 uid=0으로의 전체 LPE가 성립함.
8192cd_cfg.h:
#define _IOCTL_DEBUG_CMD_
#ifdef DEBUG로 차단되지 않는다. 디버그 명령 집합은 모든 프로덕션 빌드에 포함된다.
드라이버의 rtl_ioctl() 디스패처는 write_mem 및 read_mem으로 0x89F5와 0x89F6(무선 드라이버가 공급업체 확장에 사용하는 표준 SIOCDEVPRIVATE+5/+6 개인 IOCTL 범위)을 라우팅한다. 핸들러는 사용자가 제공한 문자열을 구문 분석한다:
dw,<addr>,<count> — 커널 가상 주소 addr에서 count개의 32비트 워드를 읽는다dw,<addr>,<count>,<value> — addr에 value의 32비트 워드 count개를 쓴다주소는 _atoi(16진수)로 구문 분석되고, 커널 가상 주소 공간을 대상으로 memcpy()에 전달되며, 결과는 copy_to_user()로 다시 사용자 공간에 복사된다. 다음이 없다:
capable() 검사 없음access_ok() 검사 없음.bss에 있는 단일 2000바이트 전역 버퍼(tmpbuf1)를 공유한다읽기 프리미티브는 호출당 128바이트로 제한된다. 쓰기 프리미티브는 임의의 길이를 허용한다.
동일한 액세스 제어 결함이 디버그 집합의 다른 핸들러(하드웨어 레지스터 읽기/쓰기 - 0x89F3/0x89F4/0x89F8–0x89FD, MIB 쓰기 - 0x89F1, eFuse 읽기/쓰기, 제조 테스트 모드)에도 적용된다. 이들은 동일한 코드 경로를 통해 도달할 수 있으므로 이 버그를 패치하는 모든 사람은 전체 감사를 수행해야 한다.

참조 익스플로잇 kpwn.c(본 권고와 함께 공개됨):
init_task를 탐색하여 task_struct 오프셋(comm, cred, tasks, pid)을 자동 감지한다. init_task 자체는 커널 .data를 무차별 대입 스캔하여 찾는다./sys/class/net/*에 대해 읽기 프리미티브를 프로빙하여 취약한 인터페이스를 자동 감지한다./proc/kallsyms을 읽을 수 있으면 IOCTL 44회, kptr_restrict=2이면 IOCTL 약 7600회(전체 .data 스캔 경로)가 필요하다. 모든 테스트 실행에서 무조건 root 셸을 얻는다.# Build:
arm-linux-gnueabi-gcc -static -O2 -o kpwn kpwn.c
# Run as unprivileged user:
$ id
uid=1000(pwn) gid=3003(inet) ...
$ /tmp/kpwn
kpwn — RTL8192CD kernel LPE
[*] Scanning interfaces...
[+] wlan0 — read primitive confirmed
[*] Resolving init_task...
[+] init_task @ 0xc08ecb38
[+] comm=0x3a8 cred=0x3a4 tasks=0x250 pid=0x2c0
[+] cred=0xed3a4500 uid=1000 gid=3003
[*] Overwriting credentials...
[+] uid=0 euid=0 gid=0 egid=0
*** GOT ROOT *** uid=1000 -> 0 (44 ioctls)
# id
uid=0(root) gid=0(root) groups=0(root)
| 날짜 | 2026-02-23 |