
A dependency-light Rust CLI that rewrites existing media files to reproduce two pinned Chromium and FFmpeg parser bugs, built for authorized vulnerability research in isolated lab environments.
| Tool | aftermathlabs/discord-crasher — Rust media-gen generator producing two reproducible media-parser denial-of-service test cases found via binary instrumentation |
| Category | vulnerability research / test-case generation |
| Primary Use | Regenerating version-pinned crash and resource-exhaustion test cases against WebM/Vorbis and M4A parsers for parser hardening and regression testing |
| Safe Use | For authorized security researchers, parser maintainers, and defenders reproducing known denial-of-service behavior in isolated, bounded test environments; the README explicitly warns these are DoS test cases, not exploits, and to run them only in isolated labs |
| Telemetry Note | The generator itself contacts nothing and uploads nothing; its outputs cause observable renderer terminations (STATUS_BREAKPOINT / 0x80000003) and ~6.6 GB transient private-memory spikes, both highly visible in crash telemetry, memory monitors, and process sampling on the affected pinned builds |
Despite the attention-grabbing repository name, aftermathlabs/discord-crasher is fundamentally a research-reproducibility artifact, not an attack tool. The actual deliverable is media-gen, a small, dependency-light Rust command-line program that edits existing, valid media files in place to reconstruct two specific parser defects the authors discovered through binary instrumentation and fuzzing. The README is unusually disciplined about scope: the tool does not invoke FFmpeg, patch a browser, contact a server, or upload anything. What it does is take a valid WebM or M4A seed and rewrite specific container structures so that the defect is deterministically triggered in the exact pinned builds where it was observed.
Both test cases are version-pinned, and the README is explicit that other releases may reject the files, handle them safely, or fail differently. The WebM case was validated against Discord Desktop 1.0.9257 running Electron 42.11.1 / Chromium 148.0.7778.280, plus Chrome 153.0.8010.48. The M4A case remains specific to the pinned Discord/FFmpeg build. This pinning is the honest part of the research: the author is not claiming a universal vulnerability, but documenting a precise failing state in an exact runtime, which is exactly the standard a maintainer needs to reproduce and patch a bug.
The first case is a WebM/Vorbis discard-bridge crash that terminates the renderer with 0x80000003 (STATUS_BREAKPOINT) inside Chromium's AudioDiscardHelper release check, on both the older one-buffer-delayed Vorbis path and the current immediate-discard path. The mechanics are the interesting part. Matroska negative DiscardPadding becomes a Vorbis front skip, and the two Chromium code paths apply that skip differently. By repeating one large 577-frame skip across audio packets 0 and 1, the crafted file bridges both behaviors, guaranteeing that 129 frames carry into packet 2. Chromium's invariant check discarded_frames <= decoder_delay then fails, because the track's CodecDelay is only 128 frames. The generator computes all of this: it parses the Vorbis setup headers, determines decoded packet sizes, and fails closed unless the bridge arithmetic is viable.
The second case is a memory-exhaustion trigger classified by the authors as CWE-400 uncontrolled resource consumption. Rather than attacking the AAC payload, it abuses a legitimate MP4 sample-table shape: the generator replaces the explicit stsz sample-size array with sample_size = 1, then sets the declared sample count in stsz, the first stsc run, and the first stts run to the same large value, repairing ancestor box sizes and the absolute stco offset so the one-byte AAC payload still resolves inside mdat. The pinned FFmpeg demuxer trusts that declared count when building index and timing tables — roughly 24 bytes per AVIndexEntry plus 12 bytes of timing data per sample — and the maximum accepted count of 178,956,969 projects to roughly 6.4 GB of combined allocations. The observed private-memory peak was 6,614,761,472 bytes, purely from metadata loading.
The most instructive section of the README is the discussion of blare2, the binary-instrumentation framework that made the discovery practical. The author is candid that media-gen is only the reproducibility layer — the hard work was finding and proving the behavior inside a large native Discord executable with bundled media libraries. For the WebM case, a blare2 semantic probe stopped at the exact AudioDiscardHelper::ProcessBuffers check and recorded discarded_frames = 129 and decoder_delay = 128, converting a generic release assertion into a precise, attributable invariant failure. For the M4A case, high-frequency process sampling plus disassembly proved that the tiny file genuinely reached the MOV sample-table builder, separating a real scaling bug from an ordinary AAC decode failure or a misleading file-size correlation.
The author also documents the limits of instrumentation honestly, which is rare in this genre. blare2 did not prove that Discord's production upload/CDN path preserves these crafted bytes, did not replace container analysis and source review, and broad function-entry coverage alone was insufficient — low-count and high-count files traversed the same functions while allocating radically different amounts of memory. That last observation is a genuinely useful lesson for anyone doing parser research: coverage equality does not imply behavioral equality, and allocation-site attribution often matters more than code-path coverage.
From an engineering standpoint, media-gen shows good hygiene. It fails closed when structural preconditions are missing — the WebM input must contain an A_VORBIS track, a positive CodecDelay, at least three decodable audio packets, and specific packet-size relationships. It preserves the original encoded audio and video payloads, and repairs stale SeekHead, Cues, and cluster CRC elements so the rewritten Matroska container remains parseable rather than simply corrupt. Every run emits a JSON manifest reporting the immediate and delayed discard paths separately, including the expected carry frames and check outcome, so results are auditable rather than anecdotal.
Operationally the tool is straightforward to build: cargo build --release -p media-gen produces target/release/media-gen, and the subcommands webm and m4a each expose --help. The WebM path takes the checked-in 43 ms control sample with --input, --output, and --manifest, plus tuning flags like --trigger-skip, --codec-delay, and --sample-rate. The M4A path takes a fast-start AAC seed and a --sample-count defaulting to the maximum accepted value, with smaller counts explicitly offered as low-memory smoke tests and the adjacent count 178956,970 suggested as a rejection control. That control-samples mindset — trigger value, adjacent non-trigger, and low-dose variant — is textbook experimental design applied to parser research.
For defenders, this repository is more useful as intel than as threat. The observable signatures are loud: a renderer process terminating with STATUS_BREAKPOINT on media playback, or a transient multi-gigabyte private-memory spike during metadata load. Both patterns surface readily in crash telemetry and memory monitoring, and the M4A case's dependence on a metadata transition from preload="none" narrows the triggering interaction further. Parsing teams can harden against declared-count trust in stsz/stsc/stts and re-examine AudioDiscardHelper invariants across the discard-mode transition — the two concrete engineering takeaways embedded in the findings.
The repo sits at a modest 21 stars with no license declared, written in Rust on the master branch, so anyone redistributing or building on it should note the absent licensing terms. Nothing in the repository distributes malicious payloads beyond tiny crafted sample files pinned to specific builds, and the README's own framing — denial-of-service test cases, isolated bounded environments, no demonstrated code execution — matches how responsible parser research should be published. For professionals studying media-parsing attack surface, fuzzing methodology, or binary instrumentation workflows, this is a compact, well-documented reference worth reading in full, particularly the blare2 attribution narrative that explains how suspicious parser behavior becomes a defensible, version-pinned finding.
aftermathlabs/discord-crasher.Educational analysis for authorized security professionals. Use only in controlled, authorized environments.
0 comentários:
Post a Comment
Note: Only a member of this blog may post a comment.