Reputation: 63
I have a C code like this:
#include <stdio.h>
void x(int argc, char** argv) {
printf(argv[0]);
}
int main(int argc, char** argv) {
char* secret = "SECRET";
if (argc < 2)
x(argc, argv);
}
I now want to do a format string attack to print the secret to the shell. However, I don't know how get the string that I want to argv[0] and how I would access data from another scope (because from x it's not possible to directly address the pointer secret.
How would I do that?
Upvotes: 1
Views: 6296
Reputation: 85787
In unix, programs are started with execve
(or one of its wrappers, such as execlp
). All exec*
functions let you pass arbitrary strings for argv
, including argv[0]
.
If you're doing this interactively from a shell, have a look at the exec
builtin:
( exec -a '%x...' ./prog )
The parens create a subshell, exec
loads and runs ./prog
into the subshell process, and the argument to -a
is used as argv[0]
.
As for how you can access variables, look at the generated assembler code. If secret
is stored on the stack and printf
pulls arguments from the stack, it may be possible to get the results you want just by specifying enough %x
directives (followed by %s
).
Upvotes: 15
Reputation: 15229
argv[0]
contains the program name, which is usually the string you invoke the program with. For a program executed with ./a.out
, argv[0]
would point to ./a.out
.
Your format string attack would need to modify argv[0]
. That means you need to rename the executable to a format string that fits your needs.
I changed your program to read from argv[1]
and removed the argc < 2
restriction. I used %s
and prepended %d
until "SECRET"
was printed. Why %d
? I figured the stack is aligned to a multiple of int
(which %d
prints) because sizeof(int)
is usually the natural word size.
In the end, I came up with %d%d%d%d%d%d%d%d%d%d%d%d%s
. This prints some values from the stack (if there was some kind of "skipping" formatter to avoid actually printing those values, I'd use it), pops those, and prints "SECRET"
in the end.
Note that this is undefined behavior and completely dependent on your machine, though.
Upvotes: 2