Format string exploitation and read primitive development
Format string exploitation and read primitive development
When user input is passed directly as the format string to printf, sprintf, _snprintf, or vsprintf, the attacker owns both a read primitive and a write primitive. This domain tests building a reliable read first - leaking stack contents and module pointers - and only then converting that into control.
Core rules
- On x86 cdecl, variadic arguments sit on the stack above the format pointer;
%xprints them in order and positional specifiers such as%6$xindex a slot directly. - To read arbitrary memory: place the target address at the front of the buffer, find which argument slot points back into that buffer, and reference it with
%s.%sdereferences;%xdoes not - a crash on%susually means the pointer you supplied is wrong, which is itself information about alignment. - The write primitive uses
%n/%hn; split the target dword into two halves and write each with a separate address (target, target+2) to keep the character count manageable. - On Windows, the MSVC CRT disables
%nby default from VS2005 onward, so confirm the runtime before planning a write. Also distinguish ANSI from wide (wsprintfW) paths.
Worked example
Send AAAA%x.%x.%x.%x.%x.%x. The output eventually contains 41414141, meaning the buffer's first dword appears at that argument index. If it is the seventh, then %7$s treats the bytes at the start of the buffer as a pointer and prints the string there. Replace AAAA with the little-endian address of a saved return address or a module pointer, and you have an ASLR-breaking read that feeds directly into a DEP bypass chain.
Traps that cost marks
- Miscounting slots, because the format string's own buffer address occupies one of them.
- Target addresses containing null bytes, truncating the string before the specifier.
- Misaligning the address block relative to the argument grid, so a slot reads half of one address and half of another.
- Planning a
%nwrite against a CRT that has the conversion disabled.