Skip to content

feat: identify + descramble D-Link OTA container (Realtek Ameba XOR payload) - #62

Merged
nmatt0 merged 1 commit into
masterfrom
feat/dlink-ota
Oct 17, 2026
Merged

nmatt0 merged 1 commit into
masterfrom
feat/dlink-ota

Conversation

@nmatt0

@nmatt0 nmatt0 commented Oct 17, 2026

Copy link
Copy Markdown
Owner

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 entry
is {"OTAn", u32 0x18, u32 cksum, u32 size, u32 payload_off, u32 flags}; payloads
begin 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 the OTA1 tag at offset 8, with the
    deobf validator.
  • dlink_ota descramble scheme in deobfuscate/scheme.cpp — parses and validates
    the entry table (count, 24-byte stride, offsets tiling to EOF), then derives
    the one-byte XOR key from the Ameba magic 81958711 and verifies it before
    decrypting. Keyless and self-validating:
    • a device shipping a different key still decrypts;
    • a structurally valid container whose payload is not an Ameba image is reported
      present-but-unkeyable (structural tier), never emitted as garbage.
  • Under -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) and
    descrambled byte-exact; a non-0xab derived key still decrypts; a bogus entry
    table and a non-Ameba payload are rejected.
  • tests/gen_samples.py: a dlink_ota fixture (sample-coverage gate).
  • Full tests/run.sh green (unit tests + sample regression + fuzz smoke).

…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.
@nmatt0
nmatt0 merged commit 99dfb20 into master Oct 17, 2026
4 checks passed
@nmatt0
nmatt0 deleted the feat/dlink-ota branch October 17, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant