Data modification

Luckily C contains a rarely-used format specifier %n. This specifier takes in a pointer (memory address) and writes there the number of characters written so far.

How %n works ?

As explain in introduction, %n take a pointer as argument and write there the number of characters written so far.

This mean that to write 0x41 which is 81 in decimal, It means that 81 characters must be written before the %n placeholder in order to make it write 0x41 at the targeted location.

Padding

As explained before, a large amount of chars had to be sent in order to write a byte. But in much case, the user input lenght is size limited, so how to write as many characters as needed ?

To do that, the usage of padding will help : %81d will write 81 characters (the decimal value of the pointed argument padded with spaces in order to have a data size of 81)."

Arbitrary write

In order to write at an arbitrary location, the user input offset must be known because the targeted address will be injected here, such as Arbitrary data read.

Then, A format string will be sent that will write the sufficient amount of characters in order to write the chosen value.

Finally there is the %n or any of variants.

Pwntools

Pwntools has a feature for automating %n format string exploits:

from pwn import *
payload = fmtstr_payload(offset, {location : value})

Example if the user input offset is 7 and the targeted address is 0x41414141 and the arbitrary chose value is 0x44434241 :

from pwn import *
payload = fmtstr_payload(7, {0x41414141 : 0x44434241})
b'%65c%18$hhn%1c%19$hhn%1c%20$hhn%1c%21$hhnaaaAAAABAAACAAADAAA'

In this example, the format string is injected before the targeted address ( it's better to do that in case of null bytes in the targeted address that will stop the printf function )

Last updated