Notes, bugs, primitives, and the occasional rant.
-
Tencent's ACE guards something like 700 million players with a 4 MB VMProtect-wrapped kernel driver that can read and write physical memory through an IOCTL. CVE-2024-22830 was supposed to fix that. i pulled the current driver out of memory with a chain of signed vendor drivers, BlueStacks for the addresses and KKYUM for the reads, unwrapped 519 virtual machine handlers by hand, and the "patch" turns out to be a size check, a probe, and a PID list that authorizes whoever calls it. full dumps of all three binaries are at the bottom, VMP stripped, ready for IDA.
windowskernelvmprotectanti-cheattencentphysical-memorybyovdlpecwe-284reverse-engineering
-
WHQL-signed cheat driver from LOLDrivers PR #405. two ioctls wrap MmCopyVirtualMemory with a caller-supplied pid, no ACL on the device, so kernel read/write for anyone who can open it. elevated SYSTEM is 126 lines and not interesting. the interesting part took four bluescreens on two machines: on 26200 every unelevated kernel-address leak i tried is scrubbed, and sidt returns a decoy IDT base that bugchecks the box when you read it. also why the 3-offset PoCs online work at all (admin cmd) and the one AdjustTokenPrivileges call between zero ImageBase and the real base.
windowsbyovdkernel-driverlpekaslrsidtmwcopyvirtualmemoryeprocesstoken-stealhvciexploit-dev
-
FortiOS .out files have two encryption layers, and the public tooling only cleanly covers half of them depending on year and arch. this wires the full chain into tpbreak: Bishop Fox outer KPA, ext2 carve of flatkc+rootfs.gz, RSA-wrapped FORT-RC4 for the rootfs, including the aarch64 PRGA where the shift constants are swapped. seven lab images (FGT/FFW, KVM/ALI, x86 and ARM64, 7.6.7 and 8.0.0) come out as real initrd cpios with squashfs inside.
tpbreakfortinetfortiosfirmwarereverse-engineeringfort-rc4aarch64iot
-
After decrypting FortiOS firmware, the interesting leftover is licensing. Static RE of the stripped /bin/init from FGT_VM64_KVM 8.0.0: what prefixes it accepts, where it stages the file, how install success turns into a reboot, and where the client stops and Fortinet issuance begins.
fortinetfortioslicensingreverse-engineeringfirmwarevm.liccloudinitinit
-
AOMEI Backupper 8.4.0 amwrtdrv.sys: raw disk r/w to any local user, no ACL, no security descriptor. the same driver class was assigned CVE-2026-12780 on 8.3.0 by someone else -- their PoC writes to a test VHD. this one redirects the GPT, plants FAT12 in the pre-partition gap, and executes an EFI binary before the kernel exists. confirmed on 8.4.0, which shipped the same vulnerable driver.
windowslpekernel-driveruefibootkitfat12gptaomeiamwrtdrvexploit-dev
-
SignalRGB installs a LocalSystem, auto-start service whose executable lives in a per-user AppData folder, ACL'd so any standard user has Full Control over it. overwrite the file, the service runs your code as SYSTEM on next start. honest about the trigger: a standard user has SERVICE_START but can't stop the running service, so it's reboot/auto-start, or chain a separate user-startable SYSTEM service (the SteelSeries GG sideload) for a no-reboot restart. proven on Win11: standard user to Administrators and a SYSTEM shell on the console. CWE-732 / CWE-276.
lpewindowssignalrgbservice-aclcwe-732cwe-276systemprivilege-escalation
-
i had SYSTEM on a Windows 11 box and wanted the kernel. most of the old playbook didn't work, because of HVCI. this walks the g_CiOptions/DSE line from direct patches through VBS/KDP and the three bypasses people still use without HVCI (page swap, CiValidateImageHeader PTE patch, SeCiCallbacks swap), then what HVCI actually stops (unsigned kernel code, KRWX, executable-page patching), the two ways people still get past plain HVCI (ROP through signed code, data-only page-table remap), and the two things closing them: kernel CET and Intel VT-rp / HLAT as HVPT. whether any of it works depends on the CPU and build, not the checkbox.
windowshvcivbskerneldseg-cioptionshlatkdpkcetvt-rpbyovdexploit-dev
-
SteelSeries GG installs a SYSTEM auto-updater, and its service DACL lets Authenticated Users START it, with arguments. those arguments tell the SYSTEM-side Go updater which installer to run, out of a directory any user can write. it does check the binary first: Authenticode, a signer allowlist, a symlink check. so you don't forge a signature, you bring a real one, a genuinely GN-signed SteelSeries EXE, and you put your code in a DLL it loads. standard user to an interactive SYSTEM shell on the desktop, no admin, no race, no reboot. proven on Win11.
lpewindowsdll-sideloadingauthenticodeservice-aclprivilege-escalationcwe-269cwe-732cwe-426cwe-347steelseries
-
odhcpd is the default DHCPv6 server on OpenWrt and it runs as root. its IA reply builder reports more bytes than it was allowed to write, the caller subtracts that from an unsigned length, and the length wraps to near SIZE_MAX. after that the next matched IA_NA writes straight off the end of a 512-byte stack buffer. one DHCPv6 RENEW from anyone on the LAN does it, no auth. the stack canary turns it into a crash-loop instead of a shell. CVE-2026-53922.
openwrtodhcpddhcpv6integer-underflowstack-bofdoscve-2026-53922
-
Just Hacking Training shipped a free three-level prompt-injection playground. you talk a networking-tutor chatbot called NetworkJohn into breaking the three rules it swears it won't break. the levels aren't a difficulty slider, they're three different attack classes (direct, stored, and retrieved injection) behind three escalating defenses (a naked prompt, a regex tripwire, an LLM judge). no payloads spoiled here, just what the thing is, why the design works, and what each level is teaching. go play it.
prompt-injectionllmctfai-securityjhtwriteup
-
MX Linux ships mx-snapshot with a polkit action set to allow_any=yes, so any local user runs the snapshot-lib helper as root with no password. that helper has a chown_conf subcommand that chowns a file in your home directory without -h. two config mistakes, one chain: symlink the conf path at the helper itself, chown it to yourself, rewrite it, pkexec it back. local user to uid=0 in one script, no spray, no leak, no race, no memory corruption. verified live on a fresh MX 25.2 install, reported and patched same day.
lpepolkitpkexecmx-linuxsymlinkchowncwe-59cwe-269linux
-
cracked the firmware last time, so the next pull is the cloud that drives it. V-Net 2.0 is Wecon's remote-access app: bind an HMI/PLC by its "machine code", punch a VPN tunnel through the V-Box gateway, run your plant from a phone. it's a DCloud uni-app shell over Ant's mPaaS, so all the logic sits in one 1.9 MB app-service.js. the whole business API runs over cleartext http, every request is "signed" with one MD5 key that is identical for every install, and devices are addressed by guessable machine codes. this is the app, the key, the transport, and a 20-line script that reproduces the request signature locally.
weconicscloudmobilereverse-engineeringapiscada
-
most "PLC firmware" is plaintext in a U-Boot wrapper, and the one vendor everyone's already cracked (Moxa) had nothing left to say. Wecon's HMIs were the real thing: .osf3 files at a flat entropy of 8.0, no compression magic, a four-byte "WSFI" header and nothing else. the decryptor ships in plain sight, a 32-bit DLL inside the free EasyBuilder/PIStudio editor. the entropy sweep that killed Delta and Inovance, the static RE that proved the cipher core is SHA and not the RC4 the extension promises, and running the vendor's own DLL natively out of WSL, hooked with Frida, decrypting 21 MB of ARM Linux. then the update: the cipher reversed all the way down, stock AES-256-CFB (the "no AES tables" call was a false negative) keyed by a block-64 HMAC chain, and Wecon wired into tpbreak as an auto fetch-and-decrypt vendor like TP-Link.
tpbreakfirmwarereverse-engineeringweconicshmifridaaes-256
-
the overnight fuzzers were coughing up nothing but KASAN noise, so i went sideways: which other vendors encrypt their firmware, and is the key as recoverable as TP-Link's? D-Link and QNAP fell over in an afternoon, key sitting in a shipped binary same as always. Synology made me work for it: the master keys are published nowhere, patology's key verified the signature but refused to decrypt, and the fix was to pull synofwupgrade out of a DSM 6 image and read the 10-key table straight out of get_keys(). the whole night in order, including the part where i had to actually reverse something.
tpbreakfirmwarereverse-engineeringsynologyqnapd-linkxchacha20iot
-
Ubuntu's AppArmor 5.0 "fine grained ipv4/ipv6 mediation" SAUCE patch ships in Resolute (26.04 LTS). bind_map_addr() dereferences a pointer one branch before it gets assigned. any unprivileged user oopses the kernel with a single bind() syscall under the stock unprivileged_userns profile. no caps, no userns, no modules, no sudo. CWE-476, local DoS, full host DoS where panic_on_oops=1.
linuxapparmorkernelubuntucvenull-deref
-
TP-Link serves every firmware image, 52,609 of them, from one S3 bucket that lists itself, and the "encryption" on most of them uses a scheme where the verification public key is also the decryption key. the whole break: the bucket, six crypto formats reversed (camera RSA+AES, Cloud, switch DES, the EAP RSA-PSS derive i called hardware-locked twice and was wrong both times, config DES-ECB), an 11-key cryptanalysis, and a point-and-click service that auto-decrypts 96.6% of the fleet in your browser.
tp-linkfirmwareiotrsareverse-engineering
-
five days on a v3d INDIRECT_CSD OOB-write that pops root cleanly, except it needs one kernel address i cannot read unprivileged on any default kernel. source dive, dead ends, and the structural ceiling on the primitive.
linuxkernelv3draspberry-pioob-writeinfo-leakrant
-
V4bel's Dirty Frag covers rxkad (security_index 2). it doesn't cover rxgk (security_index 6), the GSSAPI/Kerberos class merged into the rxrpc tree in the 7.0 cycle. the shared-dispatcher gate fix patches both, so that part is downstream of his class. the exploit method had to change: brute-forcing pcbc(fcrypt) at 18 M/s doesn't survive the move to AES-128. this walks the algebraic CTS-CBC chain that replaces the brute force, the RFC 3961 KDF derivation needed to get there, and the kernel-oracle harness used to debug three off-by-one bugs in the chain.
linuxkernelrxrpcrxgkkerberoskrb5encmsg_splice_pagespage-cachecopyfaillpeexploit-dev
-
a map of every kernel-side exploit mitigation on stock Ubuntu 26.04 LTS Resolute (kernel 7.0.0-15-generic). three structural classes, informational, structural, gating, with the verified bypass for each: EntryBleed (KASLR slide unpriv in 3s), RANDOM_KMALLOC seed leak + bucket graph (3830 call sites), drain-and-groom (MOVABLE/UNMOVABLE pageblock fallback), aa-rootns (apparmor userns escape), FUSE-as-stall (uffd alternative), cross-cache crossover at 100%. plus the catalog of mitigations that don't touch write-class slab bugs.
linuxkernelmitigation-bypasskaslrrandom-kmallocapparmorusernsexploit-devresolute
-
empirical buddy-mediated cross-cache from kmalloc-cg-256 to kmalloc-rnd-XX-256 on stock Resolute Ubuntu 26.04 LTS, kernel 7.0.0-15-generic. 100% rate, zero memory pressure, no sudo, sub-100ms drain-spray window. Includes the introspection LKM (slab_observe.ko), the allocator harnesses, and the v6 / v7 / v8 experiment evolution that exposed three folklore claims as wrong.
linuxkernelslubsheavesrandom-kmalloccross-cacheexploit-devmitigation-bypass
-
the same xfrm/ESP MSG_SPLICE_PAGES no-COW path lives in esp6_input over IPv6, and netdev/net.git f4c50a4034 never touched it. the PoC fires unprivileged on stock Ubuntu 26.04 over ::1 loopback. same primitive as Copy Fail 2, routed over IPv6, still unfixed.
linuxkernelxfrmesp6ipv6msg_splice_pagespage-cachecopyfaillpeexploit-dev
-
Hyunwoo Kim and Kuan-Ting Chen's xfrm ESP-in-UDP MSG_SPLICE_PAGES no-COW fast path bug, fixed in netdev/net.git f4c50a4034 on 2026-05-05, is a sibling of Copy Fail (CVE-2026-31431). Same primitive class, kernel AEAD running in-place over splice'd page-cache pages, different subsystem. Walks how the xfrm receive path lets an unprivileged user land a keystream-derived write into the page cache of any readable file, and how that turns into a root shell on a stock distro by byte-flipping a nologin line in /etc/passwd into a passwordless uid-0 user and su'ing into it.
linuxkernelxfrmespipsecmsg_splice_pagespage-cachecopyfaillpeexploit-dev
-
found this while auditing cryptodev-linux for siblings of the get_userbuf UAF. zc.c:97 returns -EINVAL when get_user_pages_remote partially succeeds (0 < ret < pgcount) and never releases the partial pins. any user with O_RDWR on /dev/crypto can reach it. each call leaks ret page-pin counts; the pinned pages are non-migratable. requesting a CVE.
linuxkernelcryptodevgupoot-modulerefcount-leakdos
-
nasm published a UAF in cryptodev-linux's get_userbuf in January 2026, complete with a uid=0 victory screenshot. Tried to reproduce: it doesn't land on Ubuntu 26.04 LTS (Resolute) prod, doesn't land on Ubuntu 22.04 LTS jammy even with init_on_alloc=0 boot-arg disabled. The PoC works on the author's hand-rolled defconfig+kvm_guest.config kernel and nowhere else. The bug class is real; the exploitation claim is misleading. Sibling audit also found a separate refcount-leak DoS in get_user_pages_remote partial-success handling.
linuxkernelcryptodevuafoot-moduleexploit-devdisclosure
-
Canonical patched Qualys's March 2025 single-hop AppArmor profile bypass with a new sysctl (apparmor_restrict_unprivileged_unconfined) that force-stacks the target profile when the caller is the global-unconfined sentinel. a two-hop transition (unconfined -> crun -> chrome) defeats the patch: the second hop sees a non-sentinel label and the stacking branch is skipped. confirmed live on Ubuntu 26.04 LTS Resolute, both sysctls enabled, from a clean unprivileged user.
linuxapparmorkernelusernsubuntubypass
-
Ubuntu shipped apparmor_restrict_unprivileged_userns=1 in 24.04 to kill the unprivileged-userns LPE class. two AppArmor profiles that ship in the base apparmor package defeat it: chrome and crun. one binary, present on every default install, and the structural fix is harder than it looks.
linuxapparmorkernelusernsubuntu
-
companion to the F_SEAL_EXEC kernel bug. i tried to turn the seal-state TOCTOU into journald log forgery on Resolute 26.04 LTS systemd 259.5. the kernel primitive worked, 2710/2710 forge attempts mutated the buffer between journald's parse and dispatch passes. independent systemd hardening rejected the forged underscored-prefix fields. the kernel bug stands; the journald weaponization on current systemd does not.
linuxkernelmemfdsealssystemdjournaldtoctou
-
fcntl(F_ADD_SEALS, F_SEAL_EXEC) on a memfd with executable mode bits OR-injects F_SEAL_WRITE into the seal state without running mapping_deny_writable() or memfd_wait_for_pins(). pre-existing PROT_WRITE | MAP_SHARED mappings stay live, so F_GET_SEALS lies about the file's mutability for as long as the sender holds the original mapping. confirmed against Linux 6.12.74 (Ubuntu Resolute 26.04 LTS) and 6.6.87.2 WSL2.
linuxkernelmemfdsealsmmresolute
-
built this while weaponizing the JFS jfs_readdir OOB-write. root-only kernel module that exposes kva→pfn, pfn neighbor inspection, kmem_cache layout dump, current-task cred kva, victim-spray helpers, and a kernel-memory read primitive, all gated on CAP_SYS_ADMIN. resolves unexported symbols with a kprobe on kallsyms_lookup_name. for any slab-OOB primitive where you need to know what's in the adjacent page.
linuxkernelmoduleexploit-devslabkproberesearch
-
fs/jfs/jfs_dtree.c:2916 budgets the directory-entry buffer in bytes but treats d->namlen, a UTF-16 code-unit count, as a byte count. with iocharset=utf8 each unit expands up to 6 bytes, so a crafted JFS image overflows the __get_free_page buffer into the adjacent buddy page on getdents. Pali Rohár posted an RFC fix in 2021 that was never merged. verified live on Resolute 26.04 LTS, Arch 7.0.3, mainline 7.1-rc1.
linuxkerneljfsfilesystemoobresolute
-
fs/ntfs3/dir.c:308 reads fname->name_len as bytes when it's a UTF-16 code-unit count. that lets a crafted entry through the bound check, and ntfs_utf16_to_nls then reads up to ~510 bytes past the slab object into adjacent kmalloc-1024 memory. those bytes come back to userspace as the directory entry name via dir_emit. dfir.ru disclosed it 2023-08-13 as CVE-2023-45896, Greg KH disputed it, CISA reasserted at CVSS 7.1 HIGH. still alive on Resolute 26.04 LTS, Arch 7.0.3, mainline 7.1-rc1.
linuxkernelntfs3filesystemoobcve-2023-45896