Introduction
After exploiting the D-Link DIR-868L and gathering hardware information via root shell, I wanted to analyze the firmware offline. This would let me search for vulnerabilities, understand the system architecture, and prepare for OpenWrt installation without relying on the live device.
D-Link uses a proprietary firmware format called SEAMA (SEAttle iMAge) to package their firmware. Understanding this format is crucial for firmware analysis, modification, and reverse engineering.
The Firmware Binary
First, I downloaded the official firmware from D-Link’s website:
File: DIR868LB1_FW203b01.bin Size: 13,074,584 bytes (12.5 MB) Release Date: April 19, 2015 Version: 2.03.B01 Download: DIR868LB1_FW203b01.bin (for analysis purposes)
This single binary file contains everything needed to run the router: bootloader configuration, Linux kernel, root filesystem, and device metadata.
Note: This firmware is provided for educational, security research, and analysis purposes. Only flash firmware to devices you own.
What is SEAMA?
SEAMA is a container format used by D-Link (and some other manufacturers) to wrap firmware images with metadata and security information. Think of it as a “firmware envelope” that includes:
- Magic number for identification
- Metadata (device type, signature, target partition)
- Checksum for integrity verification
- The actual firmware (kernel + filesystem)
SEAMA Header Structure
Offset 0x00: Magic number (4 bytes) - 0x5ea3a417
Offset 0x04: Meta size (4 bytes) - Size of metadata section
Offset 0x08: Image size (4 bytes) - Size of firmware image
Offset 0x0C: Metadata (variable) - Key-value pairs
After meta: Checksum (16 bytes) - MD5 hash
After chksum: Firmware data - LZMA kernel + SquashFS
Analyzing the Firmware with binwalk
binwalk is the swiss army knife for firmware analysis. It scans binary files for known signatures and identifies embedded content.
$ binwalk DIR868LB1_FW203b01.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 DLOB firmware header, boot partition: "dev=/dev/mtdblock/7"
120 0x78 LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 4844800 bytes
1835160 0x1C0098 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 10911482 bytes, 2536 inodes, blocksize: 131072 bytes, created: 2015-04-19 07:56:59
Analysis:
- Offset 0x0: DLOB/SEAMA header targeting
/dev/mtdblock/7 - Offset 0x78 (120 bytes): LZMA-compressed Linux kernel (~1.8 MB compressed, 4.8 MB uncompressed)
- Offset 0x1C0098: SquashFS root filesystem (10.7 MB)
The firmware has a simple structure: header → kernel → filesystem.
SEAMA Header Deep Dive
Let’s examine the SEAMA header from the boot log. When the router boots, the CFE bootloader verifies the SEAMA container:
verify_seama: data=0x02000000, size=13074528
SEAMA ==========================================
magic : 5ea3a417
meta size : 36 bytes
meta data : dev=/dev/mtdblock/7
meta data : type=firmware
meta data :
meta data :
image size : 13074464 bytes
verify_seama: signature=[(null)], type=[firmware]
checksum : 790F2D1FC9E8231690A50280E10072AD
digest : 790F2D1FC9E8231690A50280E10072AD
Selected !!!
================================================
seama check OK!!
Key Fields:
- Magic:
0x5ea3a417- SEAMA signature - Meta size: 36 bytes of metadata
- Device:
/dev/mtdblock/7(NAND partition where firmware lives) - Type:
firmware(vssealpacfor language packs) - Checksum: MD5 hash
790F2D1FC9E8231690A50280E10072AD - Verification: Checksum matches digest ✓
The bootloader verifies the MD5 checksum before decompressing and booting. This prevents corrupted or modified firmware from running (though it’s not cryptographic signature verification).
Extracting the Firmware
Step 1: Extract with binwalk
The easiest method is to let binwalk do the heavy lifting:
$ binwalk -e DIR868LB1_FW203b01.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 DLOB firmware header
120 0x78 LZMA compressed data
1835160 0x1C0098 Squashfs filesystem
$ ls _DIR868LB1_FW203b01.bin.extracted/
78.7z 1C0098.squashfs
This extracts:
78.7z- LZMA-compressed kernel1C0098.squashfs- Root filesystem
Step 2: Extract SquashFS Filesystem
$ unsquashfs 1C0098.squashfs
Parallel unsquashfs: Using 4 processors
2536 inodes (2462 blocks) to write
created 2087 files
created 232 symlinks
created 143 directories
created 0 devices
created 0 fifos
Result: Complete Linux root filesystem extracted!
$ ls squashfs-root/
bin/ dev/ etc/ htdocs/ lib/ mnt/ mydlink/ proc/
root/ sbin/ sys/ tmp/ usr/ var/ www/
Step 3: Decompress the Kernel
$ 7z x 78.7z
$ file 78
78: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
statically linked, stripped
$ ls -lh 78
-rwxr-xr-x 1 user user 4.7M Nov 7 08:15 78
The kernel is a 4.7 MB ARM ELF executable, statically linked and stripped of symbols.
What’s Inside the Firmware?
After extraction, we have access to the entire filesystem:
$ tree -L 1 squashfs-root/
squashfs-root/
├── bin/ # BusyBox and basic utilities
├── dev/ # Device nodes
├── etc/ # Configuration files
├── htdocs/ # Web interface (PHP + JavaScript)
├── lib/ # Shared libraries (uClibc)
├── mydlink/ # D-Link cloud service
├── sbin/ # System binaries (httpd, hnap, etc.)
└── usr/ # Additional programs
$ du -sh squashfs-root/
35M squashfs-root/
Key Components Found
Web Interface:
$ ls htdocs/web/
captcha.jpg config/ css/ img/ info js/ login.html
webaccess/ websetting/ wps_code_pop.html
HNAP Implementation (Vulnerable!):
$ ls htdocs/HNAP1/
control/ GetClientInfo.php SetClientInfoDemo.php ...
Services and Daemons:
$ ls sbin/
crond dnsmasq gpiod hnap httpd logd mt-daapd
rc servd smbd upnpd xmldbc
Firmware Statistics
From the extraction, here’s what we got:
Total files: 2,087
Directories: 143
Symbolic links: 232
Total size: ~35 MB uncompressed
Filesystem: SquashFS 4.0 with XZ compression
Kernel size: 4.7 MB (ARM EABI5)
Architecture: ARMv7l (Cortex-A9)
Software Stack:
- OS: Linux 2.6.36.4brcmarm+
- C Library: uClibc 0.9.32.1
- Init System: BusyBox v1.14.1
- Web Server: Custom httpd
- Languages: 23 language packs supported
SEAMA Beyond Firmware
Interestingly, SEAMA is also used for language pack management. From extracted scripts:
Loading language pack:
seama -x sealpac.tgz -i /dev/mtdblock/4 -m type=sealpac
Saving language pack:
seama -i sealpac.tgz -m type=sealpac -m langcode=en
cat sealpac.tgz.seama > /dev/mtdblock/4
The seama utility can create and extract SEAMA containers with different metadata:
type=firmware- Main firmware imagetype=sealpac- Language/localization packs
Practical Applications
1. Security Research
With extracted firmware, you can:
# Search for hardcoded credentials
$ grep -r "password\|admin\|root" squashfs-root/etc/
# Find command injection vulnerabilities
$ grep -r "system\|exec\|popen" squashfs-root/htdocs/ | grep -v ".js:"
# Analyze HNAP implementation
$ cat squashfs-root/htdocs/HNAP1/SetClientInfoDemo.php
2. Binary Analysis
# List all SUID binaries
$ find squashfs-root/ -perm -4000 -ls
# Check for insecure permissions
$ find squashfs-root/etc/ -type f -perm -002
# Analyze web server binary
$ file squashfs-root/sbin/httpd
$ strings squashfs-root/sbin/httpd | grep -i "version\|auth"
3. OpenWrt Preparation
Understanding the firmware structure helps with OpenWrt porting:
- Flash layout: Know where each partition lives
- GPIO mappings: Extract from device tree or scripts
- WiFi drivers: Identify chipsets and driver versions
- Network config: Understand default settings
Verifying Extraction Integrity
Always verify your extracted files:
# Check filesystem integrity
$ unsquashfs -s 1C0098.squashfs
Found a valid SQUASHFS 4:0 superblock on 1C0098.squashfs.
Creation or last append time Sun Apr 19 07:56:59 2015
Filesystem size 10911482 bytes (10655.74 Kbytes / 10.41 Mbytes)
# Verify kernel decompression
$ lzma -d < 78.lzma > kernel.img
$ file kernel.img
kernel.img: ELF 32-bit LSB executable, ARM, EABI5 version 1
Tools Reference
Essential Tools:
- binwalk - Firmware analysis and extraction
- unsquashfs - SquashFS filesystem extraction (part of squashfs-tools)
- 7zip/lzma - LZMA decompression
- hexdump/xxd - Binary file inspection
- file - File type identification
- strings - Extract printable strings from binaries
Install on Ubuntu/Debian:
sudo apt install binwalk squashfs-tools p7zip-full
Limitations and Considerations
Checksum, Not Signature: SEAMA uses MD5 checksums for integrity, not cryptographic signatures. This means:
- Detects accidental corruption ✓
- Does not prevent intentional modification ✗
- Not secure against determined attackers
Firmware Modification: While you can extract and modify firmware, re-packing it requires:
- Creating a new SquashFS image
- Recompressing the kernel (if modified)
- Recalculating the MD5 checksum
- Wrapping everything in a new SEAMA container
This is possible but requires additional tools and knowledge of the SEAMA format.
Conclusion
The SEAMA format is a simple but effective container for D-Link firmware. Key takeaways:
- Easy to analyze: binwalk automatically identifies SEAMA headers
- Simple structure: Header → Kernel → Filesystem
- MD5 verification: Protects against corruption but not malicious modification
- Well-supported: Standard tools (binwalk, unsquashfs) handle extraction
Understanding firmware formats like SEAMA is essential for:
- Security research and vulnerability discovery
- Custom firmware development (OpenWrt)
- Device recovery and repair
- Learning embedded Linux systems
With the firmware extracted, you have complete access to analyze the system offline, search for security issues, and understand exactly how the device works—all without touching the live hardware.
References
- binwalk Documentation - Firmware analysis toolkit
- SquashFS Format - Compressed read-only filesystem
- OpenWrt Firmware Format Guide - Flash layouts and formats
- Firmware Analysis for IoT Security - Security research techniques
Firmware analysis conducted on downloaded official firmware for educational and security research purposes.