
삼성 Tizen 9 TV를 Chromium WasmGC RCE와 V4L2 physmap 임의 물리 메모리 접근을 통해 루팅하는 연구 툴킷으로, 부팅 시 지속되는 페이로드와 루트 셸 채널을 제공합니다.
Tizen 9를 실행하는 2024년형 Samsung Neo QLED에 대한 비공식 보안 연구입니다. sdb도, 개발자 모드도, 펌웨어 플래싱도 없습니다. TV는 자체 브라우저에서 루팅되며, 루트는 부팅 시 실행되는 기본 탑재 서비스 앱을 통해 영구적으로 유지됩니다.
| 테스트 기기 | 2024년형 Neo QLED, QNX1D 시리즈 (QTV T09 플랫폼) |
| 펌웨어 | T-PTMxxxx (01400) |
| 커널 | Linux 5.4.249, ARM32 (VMSPLIT_3G + HIGHMEM, LPAE 없음), PAGE_OFFSET 0xC0000000, PHYS_OFFSET 0x20000000 |
| 브라우저 | Chromium 120.0.6099.5 (SamsungBrowser/7.0) |
| 루트 | uid=0, CapEff=0x3fffffffff |
| 영구 페이로드 | 저장소 v41 (현재 md5/크기는 AGENTS.md 상태 행에 있음 — 아티팩트에서 재생성됨); 테스트 기기는 동일한 빌드를 실행 중 (2026-10-27 배포, 비콘에 tok= 포함); payload_backup.dll은 이전 빌드를 유지 |
| 루트 채널 | TV의 TCP 31337, 라인 프로토콜, 응답은 __END__로 종료 |
pwsh -File .\root.ps1 -TvIp <tv-ip> # root the TV
pwsh -File .\uninstall.ps1 -TvIp <tv-ip> # restore stock
root.ps1은 PC에서 실행되며 모든 것을 제어합니다. 포트 80 서버를 시작하고, 브라우저 스텁을 루팅하고, 부팅 페이로드를 설치한 뒤, 재부팅 후 루트 채널을 기다립니다. 두 단계는 TV 리모컨에서 수행해야 하며, 스크립트가 두 단계 모두를 안내합니다:
http://<pc-ip>/index.html을 열고 RUNNING이 될 때까지 기다립니다;그런 다음:
python tools\root_shell.py "id" <tv-ip> # talk to the TV's root channel
모든 옵션, 정확한 프롬프트, 예상 출력, 호스트 IP 관련 주의사항 및
수동 대체 방법: docs/USAGE.md.
/dev/video40/30/60)는 mmap()에서 공격자가 선택한
vm_pgoff를 받아 검증 없이 remap_pfn_range()로 전달합니다: 비특권 프로세스(uid 5001,
그룹 video)에서 임의의 물리 메모리 읽기/쓰기가 가능합니다.init_task를 찾고, 포크된 자식의 real_parent를
통해 우리 자신의 task를 찾아 자격 증명을 0으로 만듭니다.app_onboot 서비스의 IL 어셈블리를 .NET 페이로드로 교체하여 매 부팅 시
physmap/cred 패치를 반복하고, 노드를 닫은 뒤 TCP 31337에서 root 명령 채널을 제공합니다.GPU CVE도, 커널 익스플로잇도, 서명된 모듈도 없습니다. physmap이 흥미로운 부분이며, 측정된
상수와 함께 단계별로 설명한 문서는 docs/EXPLOIT.md입니다.
| 문서 | 내용 |
|---|---|
docs/USAGE.md | 실행 방법: 옵션, 프롬프트, 예상 출력, 제거 세부 사항, 복구 |
docs/EXPLOIT.md | 펌웨어별 상수와 함께 단계별로 설명한 체인 |
docs/ROOT-METHODS.md | 평가된 모든 root/지속성 방법과 최종 선택된 방법 |
docs/FAILED.md | 작동하지 않은 것과 그 이유 — 막다른 길 목록처럼 읽히며, 몇 주를 절약해 줌 |
docs/BOOT-REGRESSION-SMACK.md | 프로젝트에서 가장 미묘한 버그: 잘못된 SMACK 레이블로 인해 앱이 Main 전에 종료됨 |
docs/PORTABILITY.md | 다른 Tizen 9 TV: 네 가지 관문, 재측정할 항목, 단계별 이식 |
docs/SERVER-HOSTING.md | PC 측 서버: 실행 방식, 조용한 종료 함정, 방화벽, 로그 |
docs/SCRIPT-REVIEW.md | 스크립트의 프로덕션 준비 상태 감사 |
docs/TESTING.md | 테스트 계층, 오프라인 및 TV 상 테스트, 각 계층이 잡아내는 것 |
docs/LOGGUIDE.md | 모든 비콘 및 도구 오류 해석과 다음 단계 |
docs/REFERENCE-MATERIALS.md | 자신의 모델용 펌웨어 / GPL 소스 / 시뮬레이션 도구 다운로드 위치 |
docs/REVIEW-HISTORY.md | 종료된 리뷰 발견 사항과 그 근거 (아카이브) |
docs/OPEN-ISSUES.md | 현재 상태, 대기 중인 작업, 종료된 리뷰/패스 이력 |
AGENTS.md | 인수인계: 도구, 절차, 검증, 함정, 복구 |
CHANGELOG.md | 변경 사항과 그 이유에 대한 날짜별 이력 |
SECURITY.md | 인증 없는 31337 백도어, 범위, 신고, 법적 사항 |
NOTICE.md | 제3자 저작자 표시; 재라이선스되지 않은 파일 |
LICENSE | 원본 작업에 대한 MIT (제3자 파일 제외) |
root.ps1, uninstall.ps1 PC entry points (PowerShell)
payload/ boot payload source (.NET 6, Program.cs)
server/ port-80 server, exploit page, TV-side deploy scripts
tools/ physmap client, kernel helpers, build scripts
docs/ the documents above
AGENTS.md hand-off notes
LICENSE, NOTICE.md license + third-party attribution
SECURITY.md backdoor/scope/reporting
툴킷 전체가 커밋되어 있으므로, 클론만으로 다른 작업 트리 없이 실행됩니다.
server/payload.dll은 의도적으로 포함되어 있으며(빌드 출력과 바이트 단위로 동일),
.NET SDK 없이도 툴킷이 작동하도록 합니다. 런타임 로그, 빌드 출력, 호스트별로
생성되는 배포 스크립트는 git에서 무시되며 HTTP로 제공되지 않습니다.
docs/PORTABILITY.md를 참조하십시오.server/deploy.sh는
템플릿이며, server.py가 TV가 사용한 주소와 실제로 제공된 페이로드로부터
요청마다 H=/WANT=/SIZE_WANT=/TOKEN= 마커를 렌더링하고, 페이지는
셸코드의 콜백(IP 및 포트)을 재작성하며, 페이로드는 share/rootchan.host를
읽습니다. 컴파일된 Host는 TEST-NET 자리표시자입니다.docs/SERVER-HOSTING.md 참조).payload/global.json은
10.0.x를 고정하며(rollForward: latestPatch), 프로젝트는 net6.0을 대상으로
하며, 고정된 SDK로도 여전히 빌드됩니다(EOL 경고가 예상됨).참조 자료(펌웨어, GPL 커널 소스, QEMU 도구)는 번들로 제공되지 않습니다. docs/REFERENCE-MATERIALS.md에 각 항목을 자신의 모델용으로 다운로드할 위치가 나열되어 있습니다.
방법은 이식 가능하지만, 이 빌드는 그렇지 않습니다. payload.dll은 이 커널의
PHYS_OFFSET, init_task 및 네 개의 task_struct 오프셋을 하드코딩하며,
브라우저 체인은 Chromium 120에 특화되어 있습니다. 요약하면:
server/probe.html을 제공하고(안전함; 아무것도 실행하지
않음) TV에서 엽니다. WasmGC를 지원하는 Chromium ~120이 필요하며, 그렇지 않으면
이 CVE는 적용되지 않습니다.owner로서 코드 실행을 확보한 후(브라우저 체인),
tools/physmap.py / tools/physrpc.S로 TV의 /dev/video* 노드 중 하나에서
임의 pfn mmap을 입증합니다. 오프셋이 검증되면 중단하십시오.PHYS_OFFSET, Image 베이스, init_task, 그리고
tasks/comm/cred/real_parent 오프셋을 측정합니다. payload/Program.cs의
상수를 편집하고, 아래의 읽기 신뢰성 한계를 다시 확인하십시오./opt에서 자체 SMACK 레이블로 파일을 재작성할 수 있는
dotnet-inhouse, app_onboot 앱을 찾습니다. server/deploy.sh,
server/uninstall.sh, server/recover.sh에 해당 앱 id/경로를 설정하십시오.dotnet build -c Release -o out을 실행하고, 산출물을
server/payload.dll 위에 복사한 후(배포 게이트가 이로부터 렌더링되므로 편집할
WANT=가 없음), root.ps1로 배포한 다음 콜드 부팅합니다. 2번째 시도가 예상되는
최저선입니다.테스트 유닛에서 발견된 읽기 신뢰성 한계: video40 physmap은 VA/PA 별칭이
올바르더라도 0xE0000000 이상에서의 읽기에 대해 쓰레기 값을 반환합니다.
선형 맵 자체는 더 큽니다(zoneinfo: high_memory = VA 0xF0400000). 따라서
0xE0000000은 그 내부에 있습니다 — 가장 유력한 용의자는 CPU 맵이 아니라 V4L2
노드의 DMA 윈도우입니다. 어느 쪽이든: Kptr을 신뢰하기 전에 새 모델에서 알려진
저주소 페이지와 알려진 고주소 페이지를 테스트하십시오. 여기서 성공한 모든 cred
패치는 0xE0000000 미만이었으며, 이는 "찾을 수 없음"을 해석하는 방식에 영향을
줍니다.