Blog

Security research, reverse engineering, CTF writeups, and open-source tools.

gdk-pixbuf ICNS: Heap OOB Read in uncompress() (CVE-2026-18090)

gdk-pixbuf is the image-loading library used by GTK — the toolkit behind GNOME, gedit, and most Linux desktop applications. It parses Apple icon (.icns) files, and a crafted icon can make it read past the end of a heap buffer, potentially crashing the application or leaking adjacent memory just by opening a rogue file. uncompress() takes a pixel count and a source pointer but no source length, reading compressed pixel data until size×size pixels are decoded regardless of how many bytes the block actually contains. load_icon() computes the valid payload length from the block header but never forwards it to the decompressor. All four legacy RLE icon sizes (16×16 through 128×128) are affected, reachable from any GTK application that opens a file dialog. CVE-2026-18090 assigned 2026-08-03; unfixed as of publication.

WINCAPTURE (OmniCTF 2026 Quals) — Windows Kernel Double-Fetch Race

A Windows kernel driver controls hardware at the deepest level of the OS. This CTF challenge presents a stripped driver for a packet-capture tool where two requests racing against each other trick it into overflowing a kernel buffer — the same vulnerability class behind real privilege-escalation exploits. IOCTL_COMMIT_CAPTURE reads g_shared_pkt_size[rid] twice — once to validate against MAX_CAPTURE_SIZE, then again after releasing the region lock. A concurrent IOCTL_WRITE_SHARED on a second pipe handle raises the size between the two reads, overflowing g_capture_buf into the adjacent bump-allocated key_object_t and flipping the granted flag. Correct canary placement at the overflow offset is required; blind fill fails the canary check even when the race is won.

CREDVAULT (OmniCTF 2026 Quals) — Android Parcel Format Mismatch

Android apps pass data between system services using a format called Parcel — a compact serialized byte stream. This CTF challenge exploits a real vulnerability class (same root cause as CVE-2021-0928, CVE-2023-20963, CVE-2024-49746) where two components each expect a different layout of the same byte blob, and the one-field difference lets a crafted value pass as harmless to one parser while landing as an elevated-privilege flag in the other. Two Parcel parsers operate on the same 24-byte blob: v1 has a format_tag prefix that v2 removed, but the elevation handler passes cred_buf to the v2 parser instead of cred_buf + 4. Setting user_uid = AUTH_ELEVATED (0xCA110042) satisfies v1 (field unchecked) while landing exactly on v2's auth_level check.

onnxruntime-extensions: Heap OOB Write in LogMelSpectrum

microsoft/onnxruntime-extensions is the library that handles audio pre-processing in speech-to-text applications — anything built on Whisper or Azure AI Speech goes through it. When it converts a recording into the format neural networks understand (mel-spectrogram), a missing length check causes the code to write past the end of a heap allocation: the buffer is sized for expected_time frames but the loop runs for mag_time frames, overwriting 32 KB of heap per second of audio beyond the expected chunk. Any application processing untrusted audio with AudioDecoder.max_samples = 0 or a mismatched chunk_size is affected. Reported to MSRC (case 115486); fix in commit 8e7b615 (2026-07-01).

MalwareTech Labs — Windows Malware RE Challenge Series

Real malware rarely announces itself — it hides strings, obfuscates control flow, and chains multiple layers before the payload appears. This challenge series (eleven real-style Windows binaries) teaches you to dismantle those techniques using only a disassembler, with no dynamic execution. Each sample is solved purely through static analysis in Binary Ninja: string concealment in .rdata, on the stack, and in Win32 resources; C2 protocol reversing (URLDownloadToFile, two-phase HTTP, XOR-encrypted DLL over MDropper UA); ROL5/XOR/PEB-walk + SHA1-by-ordinal + RC4 shellcode layers; a 3-opcode bytecode VM; and a multi-stage LOLBIN dropper that harvests Chrome's cache for a JPEG polyglot DLL decrypted with AES-256-CBC via the Windows legacy Crypto API.

VEILGATE (ROCSC Bootcamp 2026) — Android Native RE with Control Flow Flattening

Commercial Android apps often use obfuscation to prevent reverse engineering of their logic. This CTF challenge stacks three real-world protection layers on a license verifier: hiding the native code entry point so disassemblers can't find it, scrambling the control flow into a 124-state machine, then splitting the encryption key across two separate data arrays. RegisterNatives hides the JNI binding (no exported symbol), OLLVM-style control flow flattening transforms the verification function, and the AES-128-CBC key is split across two XOR'd arrays in .rodata. Deobfuscate with angr/deflat.py, extract the key material from Ghidra, and decrypt the embedded license.

iSCSI CHAP: Heap Buffer Overflow in the Linux Kernel

iSCSI lets servers expose raw block storage over a network as if it were a locally attached drive. The CHAP handshake is supposed to authenticate who can connect — but this vulnerability allows an attacker on the network to overflow a kernel heap buffer before authentication completes, using only a crafted username. The BASE64 branch of chap_server_compute_hash() passes up to 127 attacker-controlled characters to chap_base64_decode() without a length check, writing 95 bytes into a 16- or 32-byte heap object. Confirmed with KASAN on linux-next, patch submitted to Martin K. Petersen with Fixes: 1e5733883421.

mac80211 EPCS: OOB Array Access in the Linux Kernel WiFi Stack

Every Linux system with WiFi uses mac80211, the kernel's shared wireless networking stack. WiFi 7 added a new protocol feature (EPCS — Emergency Preparedness Communications Service), and its implementation has a classic one-off mistake: a 4-bit field from a rogue access point's beacon frame can index into a 15-slot array with values up to 15. A 4-bit link_id from a PRIO_ACCESS ML element can be 0–15, but sdata->link[] has only 15 entries. Index 15 reads into activate_links_work, bypasses the NULL check, and crashes the kernel via ieee80211_sta_wmm_params(). Any rogue WiFi 7 AP within radio range can trigger it with no authentication required. Accepted by Johannes Berg, backported to stable.

WRAITHSTEP (ROCSC Finals 2026) — Linux Implant Forensics

When an attacker wants to persist on a Linux system without leaving obvious files, they use the OS against itself — running code entirely in memory, hooking the authentication system, and hiding communications inside normal-looking DNS traffic. This forensics challenge traces the full chain: find a program running with no file on disk (via memfd_create), trace its persistence back to a udev /dev/random rule, reverse the RC4-obfuscated PAM module that replaced pam_pkcs11.so, and decode base32-encoded credentials tunneled over DNS queries.

WINSENSOR (ROCSC Finals 2026) — Hidden IOCTL in a Windows Kernel Driver

Kernel drivers are among the most privileged code on a Windows system — they run with full hardware access and can bypass every user-space security boundary. This challenge presents a sensor-monitoring driver with a documented interface and a hidden backdoor, the same pattern behind real BYOVD (Bring Your Own Vulnerable Driver) attacks used by ransomware and APT groups. Two IOCTL handlers are public; a third, unlisted handler at code 0x8800001C writes directly to the driver's auth variable with no privilege check. Reverse the token ADMIN_TOKEN = 0xC0FFEE1337DEAD01, send the undocumented command, and demonstrate how a single missing check in kernel space voids all user-mode protections.

rtl8723bs — WiFi Heap Overflow in the Linux Kernel

The rtl8723bs is a cheap WiFi+Bluetooth chip found in millions of budget laptops and single-board computers. Its Linux kernel driver accepted 802.11 management frames without checking their length, meaning a rogue access point within radio range could corrupt kernel heap memory just by transmitting a crafted packet — no user interaction, no authentication required. OnAuthClient() was the primary entry point, but missing bounds checks span thirteen functions across the driver. Three patch series plus a separate nl80211 fix, eight commits total, backported to every active LTS tree. CVEs assigned: CVE-2026-64440, CVE-2026-64441, CVE-2026-64442, CVE-2026-64443, CVE-2026-64444, CVE-2026-64445, CVE-2026-64446, CVE-2026-64536.

VLC — Three Bugs in One Audit

VLC is the world's most popular open-source media player, installed on hundreds of millions of machines. A single focused audit of the 4.0-dev branch found three separate bugs, each reachable by opening a crafted media file or stream: a tautological guard in the Smooth Streaming parser that unconditionally dereferences chunks.end() on an empty list, a uint32_t overflow in the ID3 tag parser that freezes VLC permanently on a crafted audio file, and a uint16_t underflow in the AMT IPv6 handler that moves a buffer pointer ~64 KB before its allocation.

libmspack — Salvage Mode Use-After-Free in Cabinet Parser

libmspack is the open-source library that reads Microsoft Cabinet (.cab) archives — the format used by Windows installers and update packages. When the parser encounters a corrupt archive and enters "salvage mode" (a recovery path for partial files), a crafted second cabinet header can leave a circular singly-linked list unresolved, causing the cleanup code to walk a freed pointer. ASAN-confirmed heap-use-after-free in cabd_close() on any crafted .cab that fails midway through the second cabd_read_files() call. Fixed in commit c8336f2.

file/libmagic — OOB Read in ELF Core Note Parser

The file command is installed on virtually every Unix system — it identifies what a file actually is by inspecting its contents, and its core library libmagic is embedded in countless editors, IDEs, and security tools. A missing bounds check in the ELF core dump parser (NT_PRPSINFO path for FreeBSD) lets a crafted core file cause do_core_note() to read a process name at an attacker-controlled offset past the buffer's end. Fixed in commit 6bb1b445 by Christos Zoulas.

DWMShield — Kernel-Mode Window Capture Exclusion on Windows

On Windows, the Desktop Window Manager (DWM) is the component that composites every window you see on screen. There is a public API to exclude a window from screen recording, but DWMShield goes deeper — it calls an undocumented kernel function (win32kfull!GreProtectSpriteContent) to mark any window as capture-excluded at the compositor level, making it completely invisible to every user-mode recording API without using the documented flag. The result confirms that WDA_EXCLUDEFROMCAPTURE enforcement lives entirely inside the kernel's compositor path, beyond the reach of user-space monitoring or anti-cheat tools.

CourierDrop (OSC Regional 2026) — 4-Stage Android RE

CTF Android challenges teach the same techniques used by malware analysts and app security testers. This one wraps a fake courier logistics app around four chained protections: an obfuscated dispatch code, a JNI native callback (native code bridge) hiding the attestation logic, an anti-debug trap locking away encrypted notes, and a local HMAC verifier for the final secret. Each layer must be broken in sequence using Frida (a dynamic code-injection tool) and static analysis in a disassembler.

KernelBackdoor (UNBR Finals 2026) — Android + Hidden Kernel Module

Android apps normally cannot access kernel-level features directly. This challenge ships a Linux kernel module hidden inside an APK's assets folder — when manually loaded, it exposes a device file that only responds to a specific secret token derived from the companion native library. Reverse the XOR token from libnative.so, load the .ko manually, and send ioctl(0x1337) on /dev/ctf to retrieve the flag.

RAM Vault Beacon (UNBR Quals 2026) — Linux Malware Forensics

Malware sometimes stores sensitive data in anonymous memory regions that vanish the moment the process ends — no file on disk, nothing obvious in a snapshot. This forensics challenge presents a Linux implant that encrypts the flag with XChaCha20-Poly1305 and stores it only in an anonymous mmap region, while beaconing its C2 over HTTP with a windowed timestamp. Recovering the flag requires five key ingredients scattered across three separate artifacts: a windowed timestamp from the network capture, three environment variables (TASK_ID, KDF_SALT, STAGE_ARGS_B64) from the memory dump, and /etc/machine-id from the disk image. Feed all five into the SHA256 derivation chain — miss any one and the decryption fails silently with garbage output.

In Search of the Lost Note (ROCSC Quals 2026) — SQLite WAL Forensics

SQLite is the most widely deployed database engine in the world — it runs inside every Android app, every browser, and most desktop software. To stay fast, SQLite writes changes to a separate "write-ahead log" (WAL) file before committing them to the main database; standard queries see only committed frames. This challenge hides the flag in an uncommitted WAL frame that SQLite's normal interface skips entirely. Parse the WAL file raw to reach the hidden frame, reverse the native library to extract the PBKDF2 pepper, then decrypt the AES-GCM blob and unpack the MessagePack payload.

git-secret-scanner — Three-Layer Secret Detection in Git History

Developers occasionally commit API keys, passwords, or private certificates into a repository by mistake — and those secrets remain in the history even after the file is deleted or the key is rotated. This open-source tool scans the full commit history in three passes to find them with low false-positive rates: a regex stage that catches known credential formats (AWS keys, GitHub PATs, database URLs, private keys), a Shannon entropy filter that scores randomness, and a final LLM pass that reads the full commit context — message, file path, surrounding diff — to discard test data and placeholders before reporting real secrets.

Angry Birds (VianuCTF 2025) — Android HMAC Score Forgery

Game servers that trust client-reported scores are vulnerable: if you can reverse the signing mechanism, you can submit any score you want. This CTF challenge patches a real Angry Birds APK with xdelta, adds a hidden score-submission endpoint, and buries the signing key inside the source. Decompile with JADX, find the hardcoded HMAC-SHA256 secret in GoogleConnectService, forge a 109 score, and collect the flag from the server.

llm-decompile-cleaner — Decompiler Output Cleanup with llm4decompile-22b-v2

Decompilers (Ghidra, IDA, Binary Ninja) convert compiled machine code back into C-like source — but the output is full of generated variable names, duplicate prototype declarations, and inconsistent formatting that slow down analysis. This tool post-processes those C dumps automatically: it splits the output by function, pipes each one through llm4decompile-22b-v2 (a model trained specifically on decompiler output rather than general source code), then deduplicates declarations and normalizes whitespace to produce clean, readable pseudo-C ready for further analysis.

Arno (HackTheBox) — Android Unity IL2CPP

Unity games use IL2CPP to compile their C# logic to native machine code, which is significantly harder to reverse than reading .NET bytecode. This HackTheBox challenge provides a Unity APK where the flag is encrypted inside the native library. Run Il2CppDumper against libil2cpp.so and global-metadata.dat to reconstruct the type metadata, locate the decryption routine, extract the AES-CBC key and IV, and decrypt in Python to recover the flag.