<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>algoatson.github.io</title>
    <link>https://algoatson.github.io/</link>
    <atom:link href="https://algoatson.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <description>A remote service with a stack overflow, that forks per connection, and that you have no binary for. Blind ROP turns the only feedback you have — does the connection crash or not — into an oracle, and reads the canary, finds gadgets, and dumps the binary over the socket. The most elegant trick in the ROP toolkit.</description>
    <language>en</language>
    <lastBuildDate>Tue, 16 Jun 2026 02:47:53 +0000</lastBuildDate>
    <item>
      <title>House of Apple 2 — FSOP after the hooks died</title>
      <link>https://algoatson.github.io/p/house-of-apple-2/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/house-of-apple-2/</guid>
      <pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category><category>fsop</category>
      <description>glibc 2.34 deleted __free_hook and __malloc_hook, and everyone&#x27;s muscle memory broke. The modern answer is to forge a FILE — but the vtable is validated now. House of Apple 2 slips past that check by abusing a legitimate vtable that dereferences a second, unchecked one.</description>
    </item>
    <item>
      <title>the House of Spirit</title>
      <link>https://algoatson.github.io/p/house-of-spirit/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/house-of-spirit/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 7 — instead of corrupting a real chunk, you forge a fake one in memory you already control and trick free() into filing it away. The next malloc hands it right back, so you get malloc to return the stack.</description>
    </item>
    <item>
      <title>the poison null byte</title>
      <link>https://algoatson.github.io/p/poison-null-byte/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/poison-null-byte/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 8 — the most innocent-looking heap bug there is: one null byte written one byte too far. It lands on a neighbouring chunk&#x27;s size field, desyncs the allocator&#x27;s bookkeeping, and ends with two chunks overlapping the same memory.</description>
    </item>
    <item>
      <title>tcache dup</title>
      <link>https://algoatson.github.io/p/tcache-dup/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/tcache-dup/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 10 — the fastbin dup&#x27;s lazier cousin. The tcache had no double-free check at all for two glibc releases, and the one it finally got is a single field you can overwrite. Free a chunk twice, get it twice, poison.</description>
    </item>
    <item>
      <title>the House of Corrosion</title>
      <link>https://algoatson.github.io/p/the-house-of-corrosion/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/the-house-of-corrosion/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 14, the finale — for the challenge that gives you no libc leak and barely any allocations. Blow open global_max_fast and the fastbin index arithmetic starts pointing into libc itself, turning &quot;free a chunk of size N&quot; into &quot;write a heap pointer to a libc address&quot;. Bootstrap a leak from nothing.</description>
    </item>
    <item>
      <title>the House of Einherjar</title>
      <link>https://algoatson.github.io/p/the-house-of-einherjar/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/the-house-of-einherjar/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 11 — one null byte clears a chunk&#x27;s PREV_INUSE, a forged prev_size says &quot;the previous chunk starts way over there&quot;, and free() consolidates backward into a fake chunk you placed anywhere. Arbitrary allocation from a single off-by-one.</description>
    </item>
    <item>
      <title>the House of Lore</title>
      <link>https://algoatson.github.io/p/the-house-of-lore/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/the-house-of-lore/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 12 — the smallbins are doubly-linked and handed out from the tail. Overwrite a smallbin chunk&#x27;s bk to point at a fake chunk and malloc will walk right into it, returning a chunk on the stack. The unlink check just needs a back-pointer.</description>
    </item>
    <item>
      <title>the House of Orange</title>
      <link>https://algoatson.github.io/p/the-house-of-orange/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/the-house-of-orange/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 9, the capstone — no free() in the binary at all. Force malloc to free the top chunk for you, leak libc from it, then turn the unsorted bin attack into a forged FILE struct whose vtable call drops a shell. Heap meets FSOP.</description>
    </item>
    <item>
      <title>the House of Rabbit</title>
      <link>https://algoatson.github.io/p/the-house-of-rabbit/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/the-house-of-rabbit/</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 13 — fastbins don&#x27;t consolidate… until malloc_consolidate sweeps them. Forge a fastbin chunk&#x27;s size to something enormous, trigger the sweep, and that little chunk becomes a giant free chunk overlapping everything after it. Overlap from almost no primitive.</description>
    </item>
    <item>
      <title>the unsorted bin attack</title>
      <link>https://algoatson.github.io/p/the-unsorted-bin-attack/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/the-unsorted-bin-attack/</guid>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 5 — corrupt one freed chunk&#x27;s bk and the next malloc writes a libc pointer to an address you choose. You control WHERE, not WHAT — which sounds useless until you aim it at global_max_fast and unlock the whole fastbin.</description>
    </item>
    <item>
      <title>unsafe unlink (and the safe-unlink bypass)</title>
      <link>https://algoatson.github.io/p/unsafe-unlink/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/unsafe-unlink/</guid>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 4 — when a free chunk is pulled out of a doubly-linked list, four pointer writes happen. Forge the pointers and one of them lands wherever you want. Then the modern twist: how to pass the &quot;corrupted double-linked list&quot; check that was supposed to kill this.</description>
    </item>
    <item>
      <title>fastbin dup</title>
      <link>https://algoatson.github.io/p/fastbin-dup/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/fastbin-dup/</guid>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 3 — free a fastchunk twice past glibc&#x27;s one-line double-free check, get the same chunk handed out twice, then poison its fd to allocate straight onto __malloc_hook. The classic that teaches &quot;allocate where you want&quot;.</description>
    </item>
    <item>
      <title>the rendering reference</title>
      <link>https://algoatson.github.io/p/the-rendering-reference/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/the-rendering-reference/</guid>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <category>meta</category><category>reference</category>
      <description>every block this site knows how to render, in one scroll — listings, the checksec panel, admonitions, spoilers, tables, footnotes. The other seed post is the gentle tour; this one is the exhaustive list, and my regression test.</description>
    </item>
    <item>
      <title>the House of Force</title>
      <link>https://algoatson.github.io/p/house-of-force/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/house-of-force/</guid>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 2 — overwrite the top chunk&#x27;s size with -1 and malloc will hand you a chunk anywhere in the address space. The cleanest &quot;arbitrary allocation&quot; there ever was, and a clean look at why glibc 2.29 killed it.</description>
    </item>
    <item>
      <title>the glibc heap, from the chunk up</title>
      <link>https://algoatson.github.io/p/glibc-heap-internals/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/glibc-heap-internals/</guid>
      <pubDate>Mon, 08 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>Part 1 of the heap series — the only internals that matter for exploitation: chunk anatomy, the size field&#x27;s flag bits, and the six places a free chunk can live (tcache, fastbins, unsorted, small, large, top). Everything later is corrupting one of these on purpose.</description>
    </item>
    <item>
      <title>PTR_MANGLE and hijacking the exit handlers</title>
      <link>https://algoatson.github.io/p/ptr-mangle-exit-handlers/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/ptr-mangle-exit-handlers/</guid>
      <pubDate>Sun, 07 Jun 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>glibc</category><category>internals</category>
      <description>glibc stores some function pointers — atexit handlers, TLS destructors, jmp_buf — mangled with a secret guard so you can&#x27;t just overwrite them with a target. Read how the mangle works, where its guard lives (fs:0x30, the canary&#x27;s neighbour), and the two moves that defeat it: leak the guard, or zero it.</description>
    </item>
    <item>
      <title>reading _int_free: a source-code review of the checks</title>
      <link>https://algoatson.github.io/p/reading-int-free-source-review/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/reading-int-free-source-review/</guid>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>glibc</category><category>internals</category>
      <description>Every heap exploit is a negotiation with the checks in _int_free. This is a guided read of glibc&#x27;s free path — each malloc_printerr in order, what corrupted state it inspects, and exactly which attack it was added to kill. Know the gates and you know which technique survives on which libc.</description>
    </item>
    <item>
      <title>CET — shadow stacks, IBT, and what still works</title>
      <link>https://algoatson.github.io/p/cet-shadow-stack-ibt/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/cet-shadow-stack-ibt/</guid>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>internals</category>
      <description>Intel CET puts return addresses on a second, hardware-protected stack and demands every indirect branch land on an endbr64. That ends classic ROP and JOP. It does not end exploitation — whole-function calls, data-only attacks, and the occasional shadow-stack write all walk right past it.</description>
    </item>
    <item>
      <title>the tcache stashing unlink attack</title>
      <link>https://algoatson.github.io/p/tcache-stashing-unlink/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/tcache-stashing-unlink/</guid>
      <pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate>
      <category>heap</category><category>pwn</category><category>glibc</category>
      <description>When a smallbin serves a request, glibc stashes the leftover chunks into the tcache — and that stashing does a doubly-linked-list unlink with a far weaker check than the real thing. Corrupt one bk pointer and you get a libc write and an allocation at an address you choose.</description>
    </item>
    <item>
      <title>Dirty Pipe (CVE-2022-0847): one uninitialised flag</title>
      <link>https://algoatson.github.io/p/dirty-pipe-cve-2022-0847/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/dirty-pipe-cve-2022-0847/</guid>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <category>kernel</category><category>pwn</category>
      <description>A pipe buffer&#x27;s flags field was left uninitialised, so a stale PIPE_BUF_FLAG_CAN_MERGE let a write() spill into the page cache of a file you only opened read-only. No memory corruption, no ROP — just a missing assignment that turns &quot;read a file&quot; into &quot;overwrite it&quot;. A source review of one of the cleanest LPEs in years.</description>
    </item>
    <item>
      <title>PAC and MTE — how ARM64&#x27;s new walls fall</title>
      <link>https://algoatson.github.io/p/arm64-pac-and-mte/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/arm64-pac-and-mte/</guid>
      <pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>internals</category><category>arm</category>
      <description>ARMv8.3 signs pointers with a cryptographic MAC in their spare bits; ARMv8.5 tags every allocation with a 4-bit lock the pointer must match. Both are real upgrades over the stack canary — and both are beaten by the same old moves: a leak, a signing gadget, or a brute force the field is too small to resist.</description>
    </item>
    <item>
      <title>rizin and radare2 in anger</title>
      <link>https://algoatson.github.io/p/rizin-radare2-in-anger/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/rizin-radare2-in-anger/</guid>
      <pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate>
      <category>re</category><category>tooling</category>
      <description>The terminal reverse-engineering workflow — open, analyse, navigate, search, patch, and debug a binary without ever leaving the prompt. The commands I actually use, plus where rizin and radare2 diverge.</description>
    </item>
    <item>
      <title>the setcontext gadget — one call to every register</title>
      <link>https://algoatson.github.io/p/setcontext-register-control/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/setcontext-register-control/</guid>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>rop</category><category>internals</category>
      <description>A single controlled call — from a hook, an FSOP vtable, a function pointer — sets one register and jumps once. setcontext turns that into everything: it restores rsp and the whole register file from a struct you point it at, converting one redirect into a full pivot. The modern bridge from &quot;I control one call&quot; to &quot;I control the machine&quot;.</description>
    </item>
    <item>
      <title>stack pivoting — when the overflow is too small</title>
      <link>https://algoatson.github.io/p/stack-pivoting/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/stack-pivoting/</guid>
      <pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>rop</category>
      <description>You control the return address but only have room for two or three gadgets after it. Pivot the stack: point rsp at a buffer you fully control and run the real chain from there. leave;ret, pop rsp, xchg — the move that turns a cramped overflow into unlimited ROP.</description>
    </item>
    <item>
      <title>a pwntools cookbook</title>
      <link>https://algoatson.github.io/p/pwntools-cookbook/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/pwntools-cookbook/</guid>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>tooling</category><category>ctf</category>
      <description>The pwntools I reach for from memory — the template, tubes, packing, the ELF/libc helpers, format-string and shellcode one-liners, and the CLI subcommands that replace a pile of little scripts. Real snippets, copy-paste shaped.</description>
    </item>
    <item>
      <title>writeup: static — no libc, no leak, just SROP</title>
      <link>https://algoatson.github.io/p/writeup-static-srop/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/writeup-static-srop/</guid>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>rop</category><category>ctf</category>
      <description>A stripped, statically-linked binary with a stack overflow and almost nothing else — no PLT, no libc to leak, barely any gadgets. The way out is to write &quot;/bin/sh&quot; with a read, then chain two forged sigreturn frames into an execve. A clean SROP from recon to shell.</description>
    </item>
    <item>
      <title>SROP — one syscall, every register</title>
      <link>https://algoatson.github.io/p/srop-one-syscall-every-register/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/srop-one-syscall-every-register/</guid>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>rop</category>
      <description>A signal return restores the entire CPU state from a frame on the stack. Forge that frame and a single rt_sigreturn sets rax, rdi, rsi, rdx, rip and rsp at once — the densest gadget in the binary, perfect when you have almost nothing to work with.</description>
    </item>
    <item>
      <title>one keybind to checksec everything</title>
      <link>https://algoatson.github.io/p/checksec-everything/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/checksec-everything/</guid>
      <pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate>
      <category>tooling</category><category>pwn</category><category>ctf</category>
      <description>A small workflow I paste into every CTF box — pull every binary&#x27;s mitigations into one scannable list, run it from a single keybind, and stop re-typing checksec for the hundredth time. Glue, not genius.</description>
    </item>
    <item>
      <title>writeup: notekeeper — a UAF from menu to shell</title>
      <link>https://algoatson.github.io/p/writeup-notekeeper-uaf/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/writeup-notekeeper-uaf/</guid>
      <pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>heap</category><category>ctf</category>
      <description>A textbook menu-driven heap challenge, start to finish. A dangling pointer after delete gives a read and a write on freed memory; the unsorted bin leaks libc, tcache poisoning aims a freed chunk at __free_hook, and the program frees its way into a shell.</description>
    </item>
    <item>
      <title>BROP — return-oriented programming without the binary</title>
      <link>https://algoatson.github.io/p/brop-blind-rop/</link>
      <guid isPermaLink="true">https://algoatson.github.io/p/brop-blind-rop/</guid>
      <pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate>
      <category>pwn</category><category>rop</category>
      <description>A remote service with a stack overflow, that forks per connection, and that you have no binary for. Blind ROP turns the only feedback you have — does the connection crash or not — into an oracle, and reads the canary, finds gadgets, and dumps the binary over the socket. The most elegant trick in the ROP toolkit.</description>
    </item>
  </channel>
</rss>
