Notes on a book
A Bug Hunter's Diary
Tobias Klein · No Starch Press, 2011
Seven real vulnerabilities, each told as a diary: how the target was chosen, how the bug was found, how it was exploited, and what the vendor did next.
Klein wrote this as seven diary entries, one per bug, across a browser, a media library, a kernel, an operating system and a mobile phone. Each entry follows the same arc: how he picked the target, the audit that found the flaw, the exploitation, the disclosure, and a note on lessons learned.
It is the shortest book on this shelf and the only one that is a narrative. That is exactly why it is here. Every other book presents finished knowledge; this one shows the search, including the parts where he is guessing.
Why it is on this shelf
Because it makes the process visible. A reader who has only seen finished writeups believes bug hunting is a matter of insight arriving. What this book shows is a decision about where to look, followed by a great deal of ordinary reading, followed by one line that does not check what it should.
Chapter 4, NULL Pointer FTW
The entry the exploitation module cites, and the best worked example of a type confusion in any of these books. The target is FFmpeg, which matters because FFmpeg is inside Chrome, VLC, MPlayer and a great deal of server-side video processing - one library, an enormous attack surface.
His search is three steps and worth copying. List the demuxers, because a demuxer is by definition code that parses attacker-supplied file data. Identify the input data, which turns out to be a context pointer that every demuxer reads through the same family of accessors. Then trace that input through each demuxer in turn, one file at a time.
The bug he finds in the 4X movie demuxer is small enough to state in full. A track index is read out of the file as an unsigned 32-bit value and stored in a signed integer. A value above 0x7fffffff therefore becomes negative. The bounds check asks whether the index plus one is greater than the current track count, which is zero, and a negative number never is - so the check passes, the allocation it guards never happens, and the pointer stays null. Four subsequent writes then use that never-allocated pointer with the attacker's index as the offset. The result is not a crash at address zero but four fully controlled writes to four addresses chosen by the attacker.
Integer bugs and type confusion covers this class in general, and the exploitation half - turning controlled writes into control of execution - is the ground stack overflow to shell and the ROP payload builder work on.
The exploitation section is a good model for a CTF workflow too: find a real sample file rather than constructing one, learn the chunk layout from the sample, mutate the field until it crashes, and only then work on turning the crash into control. That is faster than building an input from the specification, and it is the same instinct behind mutation fuzzing in From Day Zero to Zero Day.
Where it stops
It is from 2011, and exploitation has changed more than any other subject on this shelf. The bugs are found in source, the exploits assume 32-bit Linux, and the mitigations that make modern exploitation hard - full address space randomisation, non-executable everything, control-flow integrity, hardened allocators - are largely absent. Read the discovery, not the shellcode.
It is also seven anecdotes rather than a curriculum. There is no coverage of anything by design, and the six entries the curriculum does not cite are a browser bug, a Windows kernel bug, an OS X bug, a BSD bug and a phone bug, each interesting and none of them systematic.
What to take into a challenge
Pick a surface and read all of it. Klein's method is not clever - list the parsers, then read them - and it is the method that works, because a bug in the one file you did not open is invisible to any amount of intuition. In a challenge the surface is small enough that this is a genuine strategy rather than an aspiration.