Auto-SummaryThe author of this post is discussing format string attacks, a type of software vulnerability that allows malicious users to crash or execute code on a system. Format string attacks occur when a program uses unfiltered user input as a format string in a function like printf, allowing the attacker to manipulate the program's behavior. The author explains that format string bugs can be particularly problematic on Alpha Linux systems, where the format string can be used to overwrite a single return address on the stack, making it difficult to exploit. The author then proposes a method for constructing a format string using the fgets() function, which can accept binary characters and store them on the stack, allowing the attacker to execute arbitrary code. The post also touches on the limitations of this method, including issues with printf() functions and the need to use digit$ directives to pull data from the stack. The author invites readers to try the proposed exploit and report their results.
Maybe this is not suited for this forum, but hell, you guys would read anything.
Format string attacks are a class of software vulnerability discovered around 1999, previously thought harmless. Format string attacks can be used to crash a program or to execute harmful code. The problem stems from the use of unfiltered user input as the format string parameter in certain C functions that perform formatting, such as printf(). A malicious user may use the %s and %x format tokens, among others, to print data from the stack or possibly other locations in memory. One may also write arbitrary data to arbitrary locations using the %n format token, which commands printf() and similar functions to write the number of bytes formatted to an address stored on the stack.
A typical exploit uses a combination of these techniques to force a program to overwrite the address of a library function or the return address on the stack with a pointer to some malicious Shellcode. The padding parameters to format specifiers are used to control the number of bytes output and the %x token is used to pop bytes from the stack until the beginning of the format string itself is reached. The start of the format string is crafted to contain the address that the %n format token can then overwrite with the address of the malicious code to execute.
Format bugs arise because C's argument passing conventions are not type-safe. In particular, the varargs mechanism allows functions to accept any number of arguments (e.g. printf) by "popping" as many arguments off the call stack as they wish, trusting the early arguments to indicate how many additional arguments are to be popped, and of what types.
Format string bugs can occur in other programming languages besides C, although they appear with less frequency and usually cannot be exploited to execute code of the attacker's choice.
I got this completely from Wikipedia, http://en.wikipedia.org/wiki/Format_string_attacks
If there's still someone reading, you gotta be interested. Here will be described how to do this on alpha linux systems. Have a go, and let me know how you did.
<case of buffer overflow exploit>
"/* align */" "/* nops */" "/* shellcode */" "\xc0\xfe\xff\x1f\x01\x00\x00\x00" "\xc0\xfe\xff\x1f\x01\x00\x00\x00" "\xc0\xfe\xff\x1f\x01\x00\x00\x00" "/* ; return addresses */
If the above string is our arbirary string, then it is recognized as this.
"/* align */" "/* nops */" "/* shellcode */" "\xc0\xfe\xff\x1f\x01" ^ | \x00 :This would be recognized end of string.
This feature is showing why the exploit of alpha linux buffer overflow should get only one return address. And that is a fatal problem against the format string bug exploit. As a matter of fact, arbitrary format string is constructed with two or more addresses like this:
<case of format string exploit>
"\xc0\xfe\xff\x1f\x01\x00\x00\x00" "\xc2\xfe\xff\x1f\x01\x00\x00\x00" "\xc3\xfe\xff\x1f\x01\x00\x00\x00" "\xc4\xfe\xff\x1f\x01\x00\x00\x00" "blah%blah .u%hn" "blah%blah .u%hn" "blah%blah .u%hn" "blah%blah .u%hn"
It seems to be impossible to set that strings into our programs environmental values or arguments properly. I explained the reason already. Environmental variables are read as a string before the program is started and it's also read as a common string. (string is a sequential bytes that is ended by null 0x00). Arguments are also read as a string. It works like case of environmental variables too. So we couldn't construct our arbirary format string in the environmental variables or arguments with expected branch address and control directives.
But how about applicate that using 'fgets()' or 'read()' for getting the user input string? How about applications that use functions which gets the user input strings through a file descriptor? This is the point of this document.
For instance, fgets() reads the string from file descriptor still EOF(-1) encounted. It means null(0x00) is not a problem to us more over, so we could put something into its stack like 64bits addresses and arbitrary format control directives. Exactly, 0x00 could be passed to that application. We might use it as a 'our arbirary format string'. As a result, it gives us more chances.
"aaaaaaa\x00\x00\x00\x01\x1f\xff\xff\xff%p"
If the application uses 'fgets()' for user input string, something binary character could be passed and set in his stack. So our hell string would be stored in the application stack. You can confirm what it features if you do this right.
-- snip1 -- 0x11ffff7b0 1a 00 00 00 00 00 00 00 61 61 61 61 61 61 61 00 ........aaaaaaa. 0x11ffff7c0 00 00 01 1f ff ff ff 25 70 00 df 03 00 00 00 00 .......%p....... -- snip2 --
But there are other problems, a kind of 'printf()' functions recognize it as a string, which should be cut off in front of "null", it would parse only the above string as "aaaaaaa".
Character set. It prints only "aaaaaaa" and does nothing after that. Parsing is over. However, we need not to worry about that, it could be solved simply. We know that we could use '%digit$' directives to pull something out from a stack. and if we get the command string to locate itself in the forth of string, then we could keep our work successfully.
"%<digit>$p%<digit+1>$p\x00\x00\x00\x01\xff\xff\xff\xff\x00\x00\x00\x01\xfc \xff\xff\xff"
The remain of our work is doing exploits.
If anyone read this and tried it for his own. Let me know the results
-------------------- Ik hou van je
While you're still sleeping the saints are still weepin' cause things you call dead haven't yet had the chance to be born. -Scatman John
|