This repository documents my hands-on analysis of a low-cost Anyka/Tuya-based camera hidden inside a USB charger. The device is sold as a stealth camera and requires a Chinese mobile app (Tuya) to configure it and connect it to your LAN. Given the device’s function (camera), its dependency on a foreign cloud service and a closed app, I was concerned about its security and decided to investigate.
The product felt sketchy from the start. It’s marketed as a stealth camera, requires a vendor app to operate, and pushes cloud subscriptions — a combination that raises privacy and attack surface concerns:
- Hidden camera hardware in a consumer product.
- Reliance on a proprietary mobile app and remote cloud servers.
- Limited or unknown modified firmware/software transparency.
Because of those factors, I wanted to answer: how secure is this device in practice? Can an owner or a third party gain unintended access? What data flows to remote servers?
This repository collects everything I found during the investigation, including:
- Firmware extraction steps and tools used.
- Static and dynamic analysis results.
- The modifications I made to the firmware and the rationale behind them.
- Bootlogs, screenshots, and other artifacts (where appropriate).
- Notes on observed network traffic and suspicious behavior.
This project is a technical security analysis and documentation of the steps I took to analyze, modify and reflash a camera device. The goal is research and disclosure — to understand the risks and to document reproducible steps for defenders and researchers. It is not intended to enable wrongdoing. If you plan to reproduce any of the steps here, ensure you own the device or have explicit permission to work on it.
This document describes the initial reconnaissance steps I performed on the camera after unboxing and adding it to my LAN via the vendor app. It explains the scanning and network-observation steps, the tools used, and the high-level findings.
- I configured the device using the official mobile application and connected it to my home Wi-Fi.
- After the device joined the network, I identified its local IP address from the router client list (
192.168.1.28) and proceeded with active and passive network reconnaissance.
- Kali Linux
- nmap
Command I used:
┌──(lawliet㉿kali)-[~]
└─$ sudo nmap 192.168.1.28 -sV -O
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-10 21:36 CEST
Nmap scan report for 192.168.1.28 (192.168.1.28)
Host is up (0.0092s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE VERSION
21/tcp open ftp BusyBox ftpd (D-Link DCS-932L IP-Cam camera)
23/tcp open telnet BusyBox telnetd
6668/tcp open irc?
MAC Address: 30:BE:29:E9:9D:4B (Unknown)
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10
Network Distance: 1 hop
Service Info: Host: anyka; Device: webcam; CPE: cpe:/h:dlink:dcs-932l
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 169.72 seconds
-
A
telnetservice was reachable on the device on port23. -
An
ftpservice was reachable on port21and custom vendor daemons was exposed. -
A service was reachable on port
6668. Was it custom protocol? Can't tell more than this from nmap.
I quickly set up a MITM and packet captures on the LAN using Ettercap + Wireshark while the mobile app talked to the camera.
I attempted to intercept requests from the mobile app to the device and to remote servers. I was hoping to find something (maybe clear traffic) while the device was talking to my phone to configure the camera.
-
Application traffic was protected by TLS (HTTP over TLS), so payloads were encrypted and not trivially readable via a basic MITM.
-
Local live video streaming occurred over
UDPon the LAN (likely RTP/RTSP or a vendor-specificUDPstream). -
When the phone was not on the same LAN, the app still displayed the live stream — indicating the device can stream via vendor cloud/relay servers (i.e. traffic leaves the LAN and is proxied/relayed).
-
TLS (and/or certificate pinning and proprietary protocols) prevented recovering plaintext control traffic with passive MITM.
Well.. What would you do if you find telnet opened on port 23? Of course you try a quick brute force using wordlist and hope to find out the password so you just get in.. I was not expecting much from this,but I spent some time trying to bruteforce both ports.
A strange thing I found out was FTP allowed me to get in with anonymous access,but could not run any command (system was asking for credentials).
-
The device exposes multiple services on the local network (telnet and others). Those services can be entry points for local attacks.
-
Live video streaming occurs locally over
UDPand can be relayed via vendor cloud servers for remote access. -
TLS protects the app<>device control channel, preventing straightforward passive inspection (could be proper TLS or certificate pinning or a custom crypto layer).
-
Device behavior extends beyond the LAN due to outbound connections to cloud/relay servers — so security concerns include both local attack surface and remote exfiltration/command channels.
At this point I had to tear apart the device to see what was under that cheap plastic shell. I were afraid some glue was there to prevent the internal structure from coming out,but on my surprise,I was able to took the shell away using a thin needle and pushing towards the top of the board. This is how the device looked after removing the plastic shell:
That reavealed an Anyka SoC,the model is AK3918v200EN080-v200. You can clearly see the Wi-Fi Antenna on the side.
There were some screws that was holding that tiny board in place. After removing them,this is the back of the board:
The first thing I noticed was that XMC flash chip,the first candidate for hosting firmware. The chip was so small I had to had a look with the microscope to see the label on it:
It is a XM25QH. A big classic for storing fw.
- Digital Multimeter
- TTL to USB Adapter
- Clips
- Copper Cable
- Sewing Needle
- Soldering Iron
- screen on Kali Linux
Well,this one has been undoubtly the most creative and funny part.
After finding the flash chip where fw was stored,the next thing I wanted to try was UART interface to get some boot logs and see what we can find from them. My intention was trying to get a shell from U-Boot (interrupting auto boot or smth like that).
I saw two unlabeled pins next to the power flat cable and thought they could be for UART Serial communication:
I took my multimeter and measured the voltage.
- One was outputting
3,34V(stable). Probably theRX Pin(the one you can send command to the board). - The other one was outputting a fluctuating voltage that moved around
3,28V. Probably theTX Pin(the one that outputsUARTlogs.)
I don't know if it's clear from the pics,but that board is so freaking small.. Normally,in situations like this you would solder a cable on the pads and see if it output logs.
I can solder but I'm not definitely a master,I'm at completely beginner level,and in this scenario,I could've easily burn/screw the board or shortcircuit UART serial pads with iron,or even worse...
So I started thinking how could I plug to them in a phisical way that was not permanent or so risky.
I started to think out and had an idea,so I soldered a Sewing Needle to a copper cable and I came out with two of this tinkered "clip",let's call it Unholy Cable Clip.
Well,thanks to my engineering (😂) I was able (!) to get UART logs (I admit that when that happened I got so excited and proud ahahah).
The final result was this one:

That looked soooo satisfying to me.
┌──(lawliet㉿kali)-[~/Scrivania/dump_firmware/_dumpfw.bin.extracted]
└─$ screen -L /dev/ttyUSB0 115200The UART Logs said:
U-Boot 2013.10.0-AK_V2.0.04 (Oct 30 2023 - 14:13:57)
DRAM: 64 MiB
8 MiB
Create flash partition table init OK!
ANYKA SDHC/MMC4.0: 0
Load Env CRC OK!
In: serial
Out: serial
Err: serial
write 1 to pin 13 on address 0x2017000c down
write 1 to pin 47 on address 0x20170010 down
Hit any key to stop autoboot: 0
SF: 2199432 bytes @ 0x33000 Read: OK
## Booting kernel from Legacy Image at 81808000 ...
Image Name: Linux-3.4.35
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2199368 Bytes = 2.1 MiB
Load Address: 81808000
Entry Point: 81808040
Verifying Checksum ... OK
XIP Kernel Image ... OK
Starting kernel ...As expected, U-Boot starts and loads the system kernel.
If you want to read the complete log,you can find it inside the logs directory.
When U-Boot starts,it says
Hit any key to stop autoboot: 0
I was assuming that 0 means that there is no delay to let the user press a key and the system just won't wait to perform kernel loading.
More than this,the system won't catch/get any keyboard input before kernel is compleately loaded and linux is started (I even made up a quick python script that was just basically spamming buttons as soon as the UART communication starts).
Due to the fact that the system has this behaviour,I realised I could't get a shell from here.
- I noticed in the log that at some point (exactly here) my Wi-Fi SSID and Password was exposed completely in clear text.
Not surprised by that,but surely more worried than I was before. It was obviously an isolated router,but it has to be connected on internet to configure the cam on your LAN. If the bootlog is sent for some reason to the vendor,they basically have your Wireless Network credentials.
After a while,you can see in the log:
start telnet......
starting mdev...
**************************
Love Linux ! ! !
**************************
200+0 records in
200+0 records out
102400 bytes (100.0KB) copied, 0.017081 seconds, 5.7MB/s
aksensor_module_init
anyka login: default log level=4
***************************************
******** cmd server has running! ******
***************************************
[main:309] Success to create TCP socket.
[main:343] Waiting for connect......
[atbm_log]:atbm_usb_module_init 0
[atbm_log]:platform_init(251)
[atbm_log]:SVN_VER=34074,DPLL_CLOCK=2,BUILD_TIME=2024-07-17_11:36:31
[atbm_log]:atbm_usb_probe : idVendor[7a] idProduct[8890]
[atbm_log]:reset wifi_chip_probe!
[atbm_log]:Probe called -1 v1
[atbm_log]:not CONFIG_USE_DMA_ADDR_BUFFER
[atbm_log]:CONFIG_TX_NO_CONFIRM
[atbm_log]:ble_spin_lock init
[atbm_log]:Allocated hw_priv @ c2082ea0
[atbm_log]:atbmwifi USB_USE_TASTLET_TXRX enable (c2082ea0)
[atbm_log]:atbmwifi USB_USE_TASTLET_TXRX enable (c2082ea0)
[atbm_log]:atbm_get_chiptype, chipver=0xa3, g_wifi_chip_type[14]
[atbm_log]:atbm_before_load_firmware++
[atbm_log]:+++++++++++++++++1.1v++++++++++++++++++
[atbm_log]:===================~_~====================
[atbm_log]: wait_event_interruptible from send_prbresp_wq
[atbm_log]:atbm_start_load_firmware++
[atbm_log]:
======>>> load WIFI BLE COMB firmware <<<======From that point (after telnet service is started and Love Linux banner is shown),the system performs an auto login (outputs anyka login:,the same prompt we're getting when connecting via telenet) and starts accepting keyboard input from my Linux system.
If I pressed enter,the system prompted me with the same anyka login: message.
The UART interface keep spamming logs,but if I blinded input root (for username) another prompt even showed up asking for Password:.
Looked like I got at the same point of before when tried to connect to telnet (but I had a lot more informations),so I had to go furhter.
At this point,I had to bring out the big guns.
- CH341A Programmer
- Kali Linux
- flashrom
- binwalk
I took my CH341A programmer,my intention was to dump out the fw from the chip,hoping it was not encrypted,but on these cheap IoT devices they usually are not.
I plugged the SOIC8 clip to the board XMC XM25QH chip and started dumping the firmware.
From the firmware I could of course recovered crucial information for my security analysis.
Command used
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ sudo flashrom -p ch341a_spi -w dumpfw.bin
[sudo] password di lawliet:
flashrom v1.6.0 on Linux 6.12.38+kali-amd64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org
Found XMC flash chip "XM25QH64C/XM25QH64D" (8192 kB, SPI) on ch341a_spi.
===
This flash part has status UNTESTED for operations: WP
The test status of this chip may have been updated in the latest development
version of flashrom. If you are running the latest development version,
please email a report to flashrom@flashrom.org if any of the above operations
work correctly for you with this flash chip. Please include the flashrom log
file for all operations you tested (see the man page for details), and mention
which mainboard or programmer you tested in the subject line.
You can also try to follow the instructions here:
https://www.flashrom.org/contrib_howtos/how_to_mark_chip_tested.html
Thanks for your help!
Reading flash chip contents... done.After dumping the firware, I run binwalk:
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ binwalk -e dumpfw.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
215688 0x34A88 LZO compressed data
216048 0x34BF0 LZO compressed data
2185321 0x215869 xz compressed data
2506752 0x264000 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 850190 bytes, 226 inodes, blocksize: 131072 bytes, created: 2025-05-20 02:22:25
3424256 0x344000 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 4522164 bytes, 300 inodes, blocksize: 131072 bytes, created: 2025-05-20 02:22:27
7966732 0x79900C JFFS2 filesystem, little endian
WARNING: One or more files failed to extract: either no utility was found or it's unimplementedThat revealed squashfq and jffs2 file system partitions. This is common for chinese IP cams.
I had a quick look inside the binwalk extracted directory:
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ cd _dumpfw.bin.extracted
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware/_dumpfw.bin.extracted]
└─$ ls
215869.xz dmesg ifenslave libdl-0.9.33.2.so lsmod ps sys
264000.squashfs dnsdomainname ifup libdl.so.0 makedevs pwd sysconfig
344000.squashfs dumpkmap init libgcc_s.so mdev rc.local sysctl
34A88.lzo echo init.d libgcc_s.so.1 mdev.conf rcS syslogd
34BF0 egrep inittab libiw.so.29 mkdir reboot tar
34BF0.lzo etc inotifyd libm-0.9.33.2.so mkdosfs resolv.conf telnetd
79900C.jffs2 false insmod libm.so.0 mkfs.vfat rm tmp
acpid fbsplash ionice libnsl-0.9.33.2.so mknod rmdir touch
adjtimex fdflush iostat libnsl.so.0 mkswap rmmod true
arp fdisk ip libpthread-0.9.33.2.so mmc_test route tunctl
ash fgrep ipaddr libpthread.so.0 mnt run tuya.key
base64 free ipcalc libresolv-0.9.33.2.so modinfo runlevel udhcpc
bin freeramdisk iplink libresolv.so.0 modprobe sbin udhcpd
blkid fsck iproute librt-0.9.33.2.so modules scriptreplay udhcpd.conf
blockdev fstab iprule librt.so.0 more sed uevent
bootchartd fstrim iptunnel libstdc++.so mount services umount
busybox fsync jffs2 libstdc++.so.6 mountpoint setarch uname
cat ftpd jffs2-root libstdc++.so.6.0.19 mpstat setconsole uncompress
catv getopt kill libstdc++.so.6.0.19-gdb.py mt setserial updater
chattr getty killall libubacktrace-0.9.33.2.so mv sh usleep
chgrp grep killall5 libubacktrace.so.0 nameif shadow usr
chmod group klogd libuClibc-0.9.33.2.so netstat slattach var
chown gunzip ldconfig libutil-0.9.33.2.so nice sleep vconfig
cp gzip ld.so.conf libutil.so.0 nsswitch.conf squashfs-root vi
cpio halt ld-uClibc-0.9.33.2.so linux32 passwd squashfs-root-0 watch
cttyhack hdparm ld-uClibc.so.0 linux64 pidof stat watchdog
custom host.conf lib ln ping stty xxx
date hostname libatomic.so loadkmap pivot_root su zcat
dd HOSTNAME libatomic.so.1 login poweroff sulogin
depmod hosts libatomic.so.1.0.0 logread powertop swapoff
dev hwclock libcrypt-0.9.33.2.so losetup printenv swapon
devmem ifconfig libcrypt.so.0 ls proc switch_root
df ifdown libc.so.0 lsattr profile sync
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware/_dumpfw.bin.extracted]
└─$ cd squashfs-root
┌──(lawliet㉿kali)-[~/Scrivania/dump_firmware/_dumpfw.bin.extracted/squashfs-root]
└─$ ls
bin custom dev etc init lib mnt proc sbin sys tmp usr var
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware/_dumpfw.bin.extracted/squashfs-root]
└─$ cd etc
┌──(.venv)─(lawliet㉿kali)-[~/…/dump_firmware/_dumpfw.bin.extracted/squashfs-root/etc]
└─$ ls
fstab host.conf init.d jffs2 mdev.conf passwd resolv.conf shadow tuya.key xxx
group hosts inittab ld.so.conf nsswitch.conf profile services sysconfig udhcpd.confI went straight to the squashfs-root/etc directory and I saw a bunch of important files,more than others,the passwd file ,the shadow file,the inittab file and the init.d directory.
┌──(.venv)─(lawliet㉿kali)-[~/…/dump_firmware/_dumpfw.bin.extracted/squashfs-root/etc]
└─$ cat shadow
root:$1$SALT$HASH:0:0:99999:7::: <--- Redacted
bin:*:10933:0:99999:7:::
daemon:*:10933:0:99999:7:::
nobody:*:10933:0:99999:7:::At this point,I already got some important information. The camera username was root (as expected) and we even got the root hash. The format is md5crypt:
$1$SomeSalt$hash
From this point,I had just to decide how to attack the device and get access to invesrigate furthermore.
I found a gist on GitHub with a bunch of users trying to decrypt similiar hash from kinda similiar devices (made by other vendors,looks like there's a lot of modified firmware combined with different hardare, and every firmware has its hash). Some users got lucky and got their hash decrypted due to community being active. I obviously got no luck,so that mf is still laying there unbroken. I had to find another way.
Guessed it,right? That way was patching the firmware and got access to the system.
I obviosly can't post exactly what I did,otherwise all this work would be taken down by GitHub, but if you point your attention on the right stuff,you can outsmart the boot logic and gain access kinda easily. Just think about what I told you til now (from UART logs and system behaviour),and look what I'm showing from this point.
First of all,I wanted to understand how the boot happens.
The files responsible for that are basically:
- inittab file
- init.d directory that contains:
- rcS file
- rc.local file
Had a quick look into them:
┌──(lawliet㉿kali)-[~/Scrivania/dump_firmware/_dumpfw.bin.extracted/squashfs-root/etc]
└─$ cat inittab
# /etc/inittab
# Copyright (C) 2010 Anyka
# Note: BusyBox init doesn't support runlevels. The runlevels field is
# completely ignored by BusyBox init. If you want runlevels, use
# sysvinit.
#
# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# id == tty to run on, or empty for /dev/console
# runlevels == ignored
# action == one of sysinit, respawn, askfirst, wait, and once
# process == program to run
# Startup the system
::sysinit:/etc/init.d/rcS # <--------- The system Loads rcS file
ttySAK0::respawn:/sbin/getty -L ttySAK0 115200 vt100 # GENERIC_SERIAL <-- This is where the system start accepting keyboard input: when getty is launched. Before of that,rcS file is launched.
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -aAs I showed in the file,the system Loads rcS file,that loads rc.local file.
┌──(.venv)─(lawliet㉿kali)-[~/…/dump_firmware/_dumpfw.bin.extracted/squashfs-root/etc]
└─$ cd init.d
┌──(.venv)─(lawliet㉿kali)-[~/…/_dumpfw.bin.extracted/squashfs-root/etc/init.d]
└─$ ls
rc.local rcS
┌──(.venv)─(lawliet㉿kali)-[~/…/_dumpfw.bin.extracted/squashfs-root/etc/init.d]
└─$ cat rcS
#! /bin/sh
echo "mount all file system..."
mkdir /dev/pts
/bin/mount -av
echo "start telnet......"
telnetd &
runlevel=S
prevlevel=N
umask 022
export runlevel prevlevel
echo "starting mdev..."
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir /var/cache
mkdir /var/run
mkdir /var/log
mkdir /var/spool
echo "**************************"
echo " Love Linux ! ! ! "
echo "**************************"
/bin/hostname -F /etc/sysconfig/HOSTNAME
#local service
/etc/init.d/rc.localWe can clearly see this is the boot part when the Love Linux banners shows up.
After that,the rc.local file is loaded
┌──(lawliet㉿kali)-[~/…/_dump_2_fw.bin.extracted/squashfs-root/etc/init.d]
└─$ cat rc.local
#!/bin/sh
#print kernel error default
echo 4 > /proc/sys/kernel/printk
# mount usr file-system.
/bin/mount -t squashfs /dev/mtdblock5 /usr
# mount jffs2 file-system.
/bin/mount -t jffs2 /dev/mtdblock6 /etc/jffs2
# note: can't recommend running other app before `mount` command.
#start ftp server, dir=root r/w, -t 600s(timeout)
/usr/bin/tcpsvd 0 21 ftpd -w / -t 600 &
#start syslogd & klogd, log rotated 3 files(200KB) to /var/log/messages
syslogd -D -n -O /var/log/messages -s 200 -b 3 & # -l prio
klogd -n & # -c prio
#create ramdisk
dd if=/dev/zero of=/tmp/zero bs=512 count=200
losetup /dev/loop0 /tmp/zero
mkfs.vfat /dev/loop0
mkdir /tmp/ramdisk
mount /dev/loop0 /tmp/ramdisk
ifconfig lo 127.0.0.1
#load camera module
/usr/sbin/camera.sh setup
dmesg > /tmp/start_message
#start system service
/usr/sbin/service.sh start &
## set min free reserve bytes
echo 2048 > /proc/sys/vm/min_free_kbytesHere service.sh is launched, under /usr/sbin/service.sh and it is responsible for launching anyka_ipc,
the main ELF binary that runs the Anyka Services and make the camera bind with Tuya App.
I tried some basic reversing stuff,like launching strings on the file and opening it in Ghidra.
The binary is not obfuscated,but as you know reversing takes a lot of time due to the fact that symbols get removed and you have to guess what the pseudo code is doing.
I saw some basic hashing functions,and saw the system calculates the md5 sum of the FW,but despite that,he never checks it (LOL) .
If you're interested in anyka_ipc ELF file,you can find it in the bin directory of this repo.
At time of publishing,I'm not sure if publishing FW dump is a good idea,I'll think about it.
In this file,I made the major changes to get access to the system.
- CH341A Programmer
- Kali Linux
- flashrom
- binwalk
- dd
- mksquashfs
After modifying squashfs-root, I had to flash the modified firmware onto the XMC flash chip.
The first thing was to recompress the squashfs-root folder to create a patch to write inside the firmware using dd. To make it:
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ mksquashfs _dumpfw.bin.extracted/squashfs-root \
/tmp/A_new.squashfs \
-comp xz -Xbcj arm -b 131072 -noappend -all-root -no-xattrs
Parallel mksquashfs: Using 6 processors
Creating 4.0 filesystem on /tmp/A_new.squashfs, block size 131072.
[===========================================================================================================================|] 52/52 100%
Exportable Squashfs 4.0 filesystem, xz compressed, data block size 131072
compressed data, compressed metadata, compressed fragments,
no xattrs, compressed ids
duplicates are removed
Filesystem size 785.90 Kbytes (0.77 Mbytes)
32.59% of uncompressed filesystem size (2411.46 Kbytes)
Inode table size 1178 bytes (1.15 Kbytes)
15.10% of uncompressed inode table size (7803 bytes)
Directory table size 2014 bytes (1.97 Kbytes)
57.12% of uncompressed directory table size (3526 bytes)
Number of duplicate files found 0
Number of inodes 226
Number of files 37
Number of fragments 5
Number of symbolic links 171
Number of device nodes 0
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 18
Number of hard-links 0
Number of ids (unique uids + gids) 1
Number of uids 1
root (0)
Number of gids 1
root (0)Then you want to make all the needed checks to avoid binary segments overlapping (be extremely careful here,if you make mistakes and creates a squashfs-root folder bigger than the original,you should then re-align binary sections,otherwise you'll create a corrupted binary and the system will likely went down as soon as he gets fucked up due to bad section alignment. Trust me,it's not good).
For e.g.:
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ stat -c '%n %s' /tmp/A_new.squashfsIn my case the output should be <= 917504 byte, that's the size squashfs-root partition (you can see it from binwalk extraction logs).
After you performed all the checks,you basically write the new partition inside the firmware:
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ cp dumpfw.bin dumpfw_patched_squashA.bin To make a backup the old firmware,and then use dd to write inside the new copy of the fw:
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ sudo dd if=/tmp/A_new.squashfs of=dumpfw_patched_squashA.bin \
bs=1 seek=$((0x264000)) conv=notrunc status=progress
[sudo] password di lawliet:
466935 bytes (467 kB, 456 KiB) copied, 1 s, 467 kB/s
806912+0 records in
806912+0 records out
806912 bytes (807 kB, 788 KiB) copied, 1,73171 s, 466 kB/sIf everything is good,you're now ready to flash the patched firmware.
The command here is straightforward:
┌──(.venv)─(lawliet㉿kali)-[~/Scrivania/dump_firmware]
└─$ sudo flashrom -p ch341a_spi -w dumpfw_patched_squashA.bin
flashrom v1.6.0 on Linux 6.12.38+kali-amd64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org
Found XMC flash chip "XM25QH64C/XM25QH64D" (8192 kB, SPI) on ch341a_spi.
===
This flash part has status UNTESTED for operations: WP
The test status of this chip may have been updated in the latest development
version of flashrom. If you are running the latest development version,
please email a report to flashrom@flashrom.org if any of the above operations
work correctly for you with this flash chip. Please include the flashrom log
file for all operations you tested (see the man page for details), and mention
which mainboard or programmer you tested in the subject line.
You can also try to follow the instructions here:
https://www.flashrom.org/contrib_howtos/how_to_mark_chip_tested.html
Thanks for your help!
Reading old flash chip contents... done.
Updating flash chip contents... Erase/write done from 0 to 7fffff
Verifying flash... VERIFIED.- telnet
- ftp
At this point we're basically done. If everything I did was correct, and in this case was (but not at first try), the system should go up and now you can login as root. There's no need to plug in my complex engineered-needle system again,as we know we've got telenet opened waiting for someone to basically break in :D
As expected,after patching:
I was able to login with FTP as well :
This basically makes the offensive part over. Now it's time to investigate inside of the OS,but now we're root and we can see everything.
Work in progress, To Be Continued
logs/— boot logs.images/— screenshots and photos taken while interacting with the device.scripts/— tbdbin/— a place for original firmware dumps/binary.
Only perform these actions on devices you lawfully own. Do not use these instructions to access devices you do not own or to perform unauthorized operations. This repository is meant for documentation and defensive research.














