Introduction #
“Finally” I said, my router Dlink DIR-1253 was support officially by dlink here it is! support.dlink.com but I notice something weird, file size are really big its about 23MB.
┌─[root@sv32]─[~/re]
└──╼ # ls -lah DIR-1253_V1.0.1.250923.142435_official.bin
-rw-r--r-- 1 root root 23M Nov 27 10:04 DIR-1253_V1.0.1.250923.142435_official.binMy router SPI it just 8MB maybe, so rather than put this update to my router I decide doing analysis (SAST) again. Here what I found!
Methodology #
Analysis using Binwalk #
┌─[root@sv32]─[~/re]
└──╼ # binwalk DIR-1253_V1.0.1.250923.142435_official.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
480 0x1E0 uImage header, header size: 64 bytes, header CRC: 0xF5B29EE6, created: 2025-09-23 06:41:59, image size: 2304923 bytes, Data Address: 0x40008000, Entry Point: 0x40008000, data CRC: 0x4E508451, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux Kernel Image"
544 0x220 Linux kernel ARM boot executable zImage (little-endian)
16079 0x3ECF LZMA compressed data, properties: 0x5D, dictionary size: 67108864 bytes, uncompressed size: -1 bytes
2297560 0x230ED8 Flattened device tree, size: 7907 bytes, version: 17
2305472 0x232DC0 JFFS2 filesystem, little endianMost interesting part of these partition is are just JFFS filesystem at the bottom. Then lets use binwalk to extra those in automatically.
┌──[root@sv32]─[~/re]
└──╼ # binwalk --run-as=root -Me DIR-1253_V1.0.1.250923.142435_official.bin
Scan Time: 2025-11-27 10:20:01
Target File: /root/re/DIR-1253_V1.0.1.250923.142435_official.bin
MD5 Checksum: cd50babdb261bbd2b535424062c2c40b
Signatures: 411
---SNIP---This is extracted firmware binwalk output
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # file *;ls -lah
232DC0.jffs2: Linux jffs2 filesystem data little endian
3ECF: OpenPGP Public Key
3ECF.7z: LZMA compressed data, streamed
_3ECF.extracted: directory
total 50M
drwxr-xr-x 3 root root 4.0K Nov 27 10:20 .
drwxr-xr-x 3 root root 4.0K Nov 27 10:20 ..
-rw-r--r-- 1 root root 21M Nov 27 10:20 232DC0.jffs2
-rw-r--r-- 1 root root 5.9M Nov 27 10:20 3ECF
-rw-r--r-- 1 root root 23M Nov 27 10:20 3ECF.7z
drwxr-xr-x 2 root root 4.0K Nov 27 10:20 _3ECF.extractedJefferson to extract jffs2 #
We need to download Jefferson first by using this command.
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # pip install --user jefferson --break-system-packagesThen extract 232DC0.jffs2 using this command.
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # jefferson 232DC0.jffs2 -d rootfs
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # ls -lh rootfs/
total 92K
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 bin
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 ctcap
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 db_excp
drwxr-xr-x 4 root root 4.0K Nov 27 10:40 dev
drwxr-xr-x 12 root root 4.0K Nov 27 10:56 etc
drwxr-xr-x 4 root root 4.0K Nov 27 10:40 home
-rwxr-xr-x 1 root root 66 Nov 27 10:40 init
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 ipks
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 kmodule
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 lib
lrwxrwxrwx 1 root root 11 Nov 27 10:40 linuxrc -> bin/busybox
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 mnt
drwxr-xr-x 3 root root 4.0K Nov 27 10:40 opt
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 proc
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 root
drwxr-xr-x 4 root root 4.0K Nov 27 10:40 run
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 sbin
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 sys
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 tagparam
lrwxrwxrwx 1 root root 7 Nov 27 10:40 temp -> var/tmp
lrwxrwxrwx 1 root root 7 Nov 27 10:40 tmp -> var/tmp
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 userconfig
drwxr-xr-x 8 root root 4.0K Nov 27 10:40 usr
drwxr-xr-x 5 root root 4.0K Nov 27 10:40 var
drwxr-xr-x 2 root root 4.0K Nov 27 10:40 wlan
drwxr-xr-x 7 root root 4.0K Nov 27 10:40 wwwHardcoded Credential #
they have two users, and its.
root:roottmadmin:password
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # cat rootfs/etc/shadow | grep -v "\!\!"
root:$1$qGmxLn8v$yTzaaXdb6.6QLLgS0Euz.1:12571:0:99999:7:::
tmadmin:$1$W9mpTzNH$GCFTW1Zoa6LPPOv3T1jDO/:0:0:99999:7:::
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # john rootfs/etc/shadow
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 ASIMD 4x2])
Will run 4 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
root (root)
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
password (tmadmin)
2g 0:00:00:00 DONE 2/3 (2025-11-27 10:57) 5.263g/s 7847p/s 7850c/s 7850C/s 123456..john
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted/rootfs/etc]
└──╼ # john rootfs/etc/shadow --show
root:root:12571:0:99999:7:::
tmadmin:password:0:0:99999:7:::
2 password hashes cracked, 0 leftfstab #
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # cat rootfs/etc/fstab
# <file system> <mount point> <type> <options> <dump> <pass>
# The syntax of busybox's fstab entry's a little different than traditional
# mount, and doesn't work with the usual 'rootfs / rootfs rw 0 0' entry.
# Actually, it's not needed unless you're mounting from a non-nfs device,
# like a hard disk. In that case, you probably need something like the
# following:
# /dev/hda1 / ext3 rw 1 1
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
#devpts /dev/pts devpts defaults 0 0
#tmpfs /var tmpfs rw 0 0Openwrt pkgs (opkg) and its ARM devices #
┌─[root@sv32]─[~/re/_DIR-1253_V1.0.1.250923.142435_official.bin.extracted]
└──╼ # file rootfs/bin/opkg
opkg: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 4.1.0, strippedThis is the most interesting part I notice, they own openwrt pkg opkg, but as you can see the architecture is differ they using ARM cpu within 32-bit executable.
That why file size are big, this firmware are absolutly uncompatible with the previous one (Black version).
Command injection prevention #
They own regex security prevention at /www/cgi-bin/{upgrade,backup}.
---SNIP---
## urldecode and handle command injection
urldecode()
{
str=$1
len1=0
len2=${#str}
while [ "$len1" -ne "$len2" ]; do
str=${str//[\"\'\`|\\<>@?*~!();,.]/}
str=${str//%/\\x}
str=${str//+/ }
str=$(printf "$str")
len1=$len2
len2=${#str}
done
echo "$str"
}
---SNIP---Conclusion #
So the conclusion is, this firmware are not compatible with DLINK DIR-1253 Black Version, because it use different architecture, and if you think both are equal? I said no, this is not! even they said “DIR-1253”.