It's a lot of questions, here are a few answers:
How can we write something in memory with a format string vulnerability ?
For this, you need to know two specific features used in the
printf format string specifications. First,
%n is a format specifier that has the following effect (according to the manual page):
%n The number of characters written so far is stored into the integer indicated by the
int * (or variant) pointer argument. No argument is converted.
Now, the second format string feature will allow us to select a specific argument from the format string. The main selection operator is
$, and the following code means that we select the second argument (here the outcome will be to display
printf("%2$x", 1, 2, 3)
But, in the general case, we can do
printf("%<some number>$x") to select an arbitrary argument of the current
printf function (format string argument does not count).
If we could pass the string
AAAA%10$n to the program and make it appear as a format string, then we could write the value
4 to the address
So, format string bugs may offer a full access to the memory and you can decide what to write and where in the memory.
I really advise you to read "Exploiting Format String Vulnerabilities" from Scut (2001) to get a whole grasp on these kind of manipulations.
Are they other languages than C/C++ that are vulnerable to these bugs ?
Well, format string bugs are tied up to the
printf function family and the way format strings may be passed to the function. It's a whole class of security issue itself. So, you might find ways to exploit similar problems in some other languages. Though, you may not find the exact same features as the format string capabilities in other languages may differ a lot.
I do think about languages such as Perl, Python, and so on, that all offer similar access to format string features.
How can I spot format string vulnerabilities if I have only the binary ?
First, you have to locate the calls to procedure of the
printf family. Then, I would say that fuzz-testing (fuzzing) should be a good way to find the vulnerabilities. Especially if you can forge a few entries with seeds such as
If you want a more accurate and exhaustive way to find it, you will probably need to do some binary analysis and taint analysis on every call to a procedure of the