Repository navigation
feat: identify + descramble D-Link OTA container (Realtek Ameba XOR payload) - #62
Merged
Merged
Conversation
…ayload)
The D-Link OTA firmware container is a plain [u32 build][u32 count][count x
24-byte entries] wrapper; each entry is {"OTAn", 0x18, cksum, size, payload_off,
flags} and the payloads tile forward from just after the entry table to EOF.
Each payload is a Realtek Ameba (RTL8710/8711) firmware image obfuscated with a
single-byte XOR.
Add a dlink_ota descramble scheme + signature. The deobf validator parses the
entry table, derives the one-byte key from the Ameba image magic "81958711" in
the first payload, and verifies it before decrypting. Keyless and
self-validating: a sibling device with a different key still decrypts, and a
payload that is not an Ameba image is reported encrypted-but-unkeyable rather
than emitted as garbage. Under -e the first slot is de-XORed and handed to the
extraction recursion, which then finds the embedded certs/keys/lzma.
Observed on D-Link DSP-W118 (two firmware builds). Tests: a synthetic container
is identified (verified) and descrambled byte-exact; a non-0xab derived key still
decrypts; a bogus entry table and a non-Ameba payload are rejected. Adds a
sample-coverage fixture; full suite green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Identify and descramble the D-Link OTA firmware container, recovering the
Realtek Ameba firmware image inside it (which then unpacks to the embedded
certificates, private keys, and lzma).
Format
A plain container:
[u32 build][u32 count][count x 24-byte entries]. Each entryis
{"OTAn", u32 0x18, u32 cksum, u32 size, u32 payload_off, u32 flags}; payloadsbegin right after the entry table and tile forward, the last ending at EOF. Each
payload is a Realtek Ameba (RTL8710/8711) firmware image (magic
81958711)obfuscated with a single-byte XOR.
Change
signatures/dlink_ota.toml— anchors on theOTA1tag at offset 8, with thedeobfvalidator.dlink_otadescramble scheme indeobfuscate/scheme.cpp— parses and validatesthe entry table (count, 24-byte stride, offsets tiling to EOF), then derives
the one-byte XOR key from the Ameba magic
81958711and verifies it beforedecrypting. Keyless and self-validating:
present-but-unkeyable (structural tier), never emitted as garbage.
-e, the first slot is de-XORed and handed to the extraction recursion,which then identifies the embedded certificates / private keys / lzma.
Scope
Validated on the D-Link DSP-W118 (two firmware builds). The container, XOR, and
Ameba magic are shared across Realtek-Ameba-based D-Link devices, but this is
anchored and verified against what was observed; the derive-and-verify design
means other devices either decrypt cleanly or are reported unkeyable, with no
false output.
Tests
tests/test_dlink_ota.py: a synthetic container is identified (verified) anddescrambled byte-exact; a non-
0xabderived key still decrypts; a bogus entrytable and a non-Ameba payload are rejected.
tests/gen_samples.py: adlink_otafixture (sample-coverage gate).tests/run.shgreen (unit tests + sample regression + fuzz smoke).